1 #ifdef SSHTEST
2 #define SSHBUILTIN
3 #endif /* SSHTEST */
4
5 #include "ckcsym.h"
6 char *userv = "User Interface 9.0.315, 14 Sep 2021";
7
8 /* C K U U S R -- "User Interface" for C-Kermit (Part 1) */
9
10 /*
11 Authors:
12 Frank da Cruz <fdc@columbia.edu>,
13 The Kermit Project, New York City
14 Jeffrey E Altman <jaltman@secure-endpoints.com>
15 Secure Endpoints Inc., New York City
16
17 Copyright (C) 1985, 2021,
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.
21 */
22
23 /*
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
29 command parser.
30 */
31
32 /*
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 platform-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
42 parser are these:
43
44 . Set parameters via global variables like duplex, speed, ttname, etc. See
45 ckcmai.c for the declarations and descriptions of these variables.
46
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.
50
51 . If a command requires the Kermit protocol, set the following variables:
52
53 sstate string data
54 'x' (enter server mode) (none)
55 'r' (send a 'get' command) cmarg, cmarg2
56 'v' (enter receive mode) cmarg2
57 'g' (send a generic command) cmarg
58 's' (send files) nfils, cmarg & cmarg2 OR cmlist
59 'c' (send a remote host command) cmarg
60
61 cmlist is an array of pointers to strings.
62 cmarg, cmarg2 are pointers to strings.
63 nfils is an integer.
64
65 cmarg can be a filename string (possibly wild), or
66 a pointer to a prefabricated generic command string, or
67 a pointer to a host command string.
68 cmarg2 is 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.
76
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
81 file transfers.
82 */
83
84 /* Includes */
85
86 #ifdef MULTINET
87 #define MULTINET_OLD_STYLE /* Leave select prototype undefined */
88 #endif /* MULTINET */
89
90 #include "ckcdeb.h"
91 #include "ckcasc.h"
92 #include "ckcker.h"
93 #include "ckcnet.h" /* Network symbols */
94 #include "ckuusr.h"
95 #include "ckcxla.h"
96
97 int g_fncact = -1; /* Needed for NOICP builds */
98 int noinit = 0; /* Flag for skipping init file */
99 int nscanfile = SCANFILEBUF;
100
101 int rcdactive = 0; /* RCD active */
102 int keepallchars = 0; /* See cmfld() */
103
104 int locus = 1; /* Current LOCUS is LOCAL */
105 #ifdef OS2
106 int autolocus = 2; /* Automatic LOCUS switching: ASK */
107 #else /* OS2 */
108 int autolocus = 1; /* Automatic LOCUS switching enabled */
109 #endif /* OS2 */
110
111 #ifndef NOICP
112 #ifdef CKLEARN
113 #ifdef VMS
114 #include <time.h> /* For CKLEARN */
115 #endif /* VMS */
116 #endif /* CKLEARN */
117 #ifdef OS2
118 #ifndef NT
119 #define INCL_NOPM
120 #define INCL_VIO /* Needed for ckocon.h */
121 #include <os2.h>
122 #undef COMMENT
123 #else
124 #define APIRET ULONG
125 #include <windows.h>
126 #include <tapi.h>
127 #include "cknwin.h"
128 #include "ckntap.h" /* CK_TAPI definition */
129 #endif /* NT */
130 #include "ckowin.h"
131 #include "ckocon.h"
132 extern int tcp_avail;
133 extern bool viewonly;
134 extern int k95stdout;
135 extern int tt_scroll;
136 #ifndef NOTERM
137 extern tt_status[VNUM];
138 #endif /* NOTERM */
139 #include "ckossh.h"
140 #ifdef KUI
141 #include "ikui.h"
142 #endif /* KUI */
143 #endif /* OS2 */
144
145 int optlines = 0;
146 int didsetlin = 0;
147
148 #ifdef NEWFTP
149 extern int ftpget, ftpisopen(), doftpres();
150 _PROTOTYP(int doftptyp,(int));
151 _PROTOTYP(VOID doftpglobaltype,(int));
152 #endif /* NEWFTP */
153
154 #ifdef VMS
155 extern int batch;
156 #endif /* VMS */
157
158 #ifdef datageneral
159 #include <packets:common.h>
160 #define fgets(stringbuf,max,fd) dg_fgets(stringbuf,max,fd)
161 #endif /* datageneral */
162
163 extern int xcmdsrc, hints, cmflgs, whyclosed;
164
165 int isinternal = 0; /* Flag for internally-defined macro */
166
167 char * hlptok = NULL;
168
169 #ifdef CK_TTGWSIZ /* Whether to use more-prompting */
170 int xaskmore = 1; /* Momentary setting */
171 int saveask = 1; /* Permanent setting */
172 #else
173 int xaskmore = 0;
174 int saveask = 0;
175 #endif /* CK_TTGWSIZ */
176
177 #ifndef NOCSETS
178 extern int nfilc;
179 extern struct keytab fcstab[];
180 extern int fcharset;
181 #endif /* NOCSETS */
182
183 char * g_pswd = NULL;
184 int g_pcpt = -1;
185 int g_pflg = -1;
186
187 extern int cmd_rows, cmd_cols;
188
189 #ifdef CKROOT
190 extern int ckrooterr;
191 #endif /* CKROOT */
192
193 extern int inserver, filepeek;
194
195 #ifdef CKLEARN
196 FILE * learnfp = NULL;
197 char * learnfile = NULL;
198 int learning = 0;
199 #endif /* CKLEARN */
200
201 #ifndef NOXFER
202 extern int atcapr, atdiso, nfils, moving, protocol, sendmode, epktflg, size,
203 sndsrc, server, displa, fncnv, fnspath, fnrpath, xfermode, urpsiz,
204 spsizf, spsiz, spsizr, spmax, wslotr, prefixing, fncact, reliable,
205 setreliable;
206
207 #ifdef IKSDCONF
208 extern int iksdcf;
209 #endif /* IKSDCONF */
210
211 #ifdef CK_LOGIN
212 extern int isguest;
213 #endif /* CK_LOGIN */
214
215 extern CK_OFF_T sendstart;
216
217 extern char *cmarg, *cmarg2, **cmlist, *dftty;
218
219 extern struct keytab fntab[]; extern int nfntab;
220 extern struct ck_p ptab[NPROTOS];
221
222 int sndcmd = 0; /* Last command was a SEND-class command. */
223
224 int g_xfermode = -1;
225 int g_proto = -1;
226 int g_urpsiz = -1;
227 int g_spsizf = -1;
228 int g_spsiz = -1;
229 int g_spsizr = -1;
230 int g_spmax = -1;
231 int g_wslotr = -1;
232 int g_prefixing = -1;
233 int g_fncnv = -1;
234 int g_fnspath = -1;
235 int g_fnrpath = -1;
236 int g_fnact = -1;
237 int g_displa = -1;
238 int g_spath = -1;
239 int g_rpath = -1;
240 char * g_sfilter = NULL;
241 char * g_rfilter = NULL;
242
243 extern int patterns;
244 #ifdef PATTERNS
245 extern char *txtpatterns[], *binpatterns[];
246 int g_patterns = -1;
247 #endif /* PATTERNS */
248 int g_skipbup = -1;
249
250 #ifdef PIPESEND
251 extern int usepipes, pipesend;
252 extern char * sndfilter;
253 #endif /* PIPESEND */
254
255 #ifndef NOSPL
256 extern int sndxlo, sndxhi, sndxin;
257 #endif /* NOSPL */
258
259 extern char fspec[]; /* Most recent filespec */
260 extern int fspeclen; /* Length of fspec[] buffer */
261
262 #ifndef NOFRILLS
263 extern int rmailf; /* MAIL command items */
264 extern char optbuf[];
265 #endif /* NOFRILLS */
266
267 extern int
268 en_cpy, en_cwd, en_del, en_dir, en_fin, en_get, en_bye, en_mai, en_pri,
269 en_hos, en_ren, en_sen, en_spa, en_set, en_typ, en_who, en_ret, en_xit,
270 en_mkd, en_rmd, en_asg;
271
272 #ifndef NOMSEND /* Multiple SEND */
273 extern char *msfiles[];
274 int filesinlist = 0; /* And ADD ... */
275 extern struct filelist * filehead;
276 extern struct filelist * filetail;
277 extern struct filelist * filenext;
278 extern int addlist;
279 #endif /* NOMSEND */
280
281 static struct keytab addtab[] = {
282 #ifdef PATTERNS
283 { "binary-patterns", ADD_BIN, 0 },
284 #endif /* PATTERNS */
285 #ifndef NOMSEND
286 { "send-list", ADD_SND, 0 },
287 #endif /* NOMSEND */
288 #ifdef PATTERNS
289 { "text-patterns", ADD_TXT, 0 },
290 #endif /* PATTERNS */
291 { "", 0, 0 }
292 };
293 static int naddtab = sizeof(addtab)/sizeof(struct keytab) - 1;
294
295 #ifndef NOCSETS
296 struct keytab assoctab[] = {
297 { "file-character-set", ASSOC_FC, 0 },
298 { "transfer-character-set", ASSOC_TC, 0 },
299 { "xfer-character-set", ASSOC_TC, CM_INV }
300 };
301 static int nassoc = sizeof(assoctab)/sizeof(struct keytab);
302 extern int afcset[MAXFCSETS+1]; /* Character-set associations */
303 extern int axcset[MAXTCSETS+1];
304 #endif /* NOCSETS */
305
306 #ifndef ADDCMD
307 #ifndef NOMSEND
308 #define ADDCMD
309 #endif /* NOMSEND */
310 #ifndef ADDCMD
311 #ifdef PATTERNS
312 #define ADDCMD
313 #endif /* PATTERNS */
314 #endif /* ADDCMD */
315 #endif /* ADDCMD */
316 #endif /* NOXFER */
317
318 /* External Kermit Variables, see ckmain.c for description. */
319
320 extern xx_strp xxstring;
321 extern long xvernum;
322
323 extern int local, xitsta, binary, msgflg, escape, duplex, quiet, tlevel,
324 pflag, zincnt, ckxech, carrier, what, nopush, haveline, bye_active;
325 #ifdef TNCODE
326 extern int debses;
327 extern char tn_msg[];
328 #endif /* TNCODE */
329
330 int sleepcan = 1;
331 int g_binary = -1;
332 int g_recursive = -1;
333 int g_matchdot = -1;
334 extern int nolinks;
335
336 extern long vernum;
337 extern char *versio, *copyright[];
338 extern char *ckxsys;
339 #ifndef NOHELP
340 extern char *introtxt[];
341 extern char *newstxt[];
342 #endif /* NOHELP */
343
344 #ifndef OS2
345 #ifndef UNIX
346 extern char *PWDCMD;
347 #endif /* UNIX */
348 extern char *WHOCMD;
349 #endif /* OS2 */
350
351 extern char ttname[];
352
353 extern CHAR sstate;
354
355 extern int network; /* Have active network connection */
356 extern int nettype; /* Type of network */
357 extern int ttnproto; /* NET_TCPB protocol */
358
359 #ifndef NODIAL
360 extern int dialsta, dialatmo, dialcon, dialcq; /* DIAL status, etc. */
361 #endif /* NODIAL */
362
363 #ifdef CK_APC
364 extern int apcactive, apcstatus;
365 #endif /* CK_APC */
366
367 #ifndef NOPUSH
368 #ifndef NOFRILLS
369 extern char editor[];
370 extern char editopts[];
371 extern char editfile[];
372 #endif /* NOFRILLS */
373 #endif /* NOPUSH */
374
375 #ifdef BROWSER
376 extern char browser[]; /* Web browser application */
377 extern char browsopts[]; /* Web browser options */
378 extern char browsurl[]; /* Most recent URL */
379 #endif /* BROWSER */
380 #ifndef NOFTP
381 char ftpapp[CKMAXPATH+1] = { NUL, NUL }; /* ftp executable */
382 char ftpopts[128] = { NUL, NUL }; /* ftp command-line options */
383 #endif /* NOFTP */
384 extern struct keytab onoff[]; /* On/Off keyword table */
385
386 #ifdef CK_TMPDIR
387 int f_tmpdir = 0; /* Directory changed temporarily */
388 char savdir[TMPDIRLEN]; /* For saving current directory */
389 #endif /* CK_TMPDIR */
390
391 int activecmd = -1; /* Keyword index of active command */
392 int doconx = -1; /* CONNECT-class command active */
393 int ooflag = 0; /* User-settable on/off flag */
394
395 int rcflag = 0; /* Pointer to home directory string */
396 int repars, /* Reparse needed */
397 techo = 0; /* Take echo */
398 int secho = 1; /* SCRIPT echo */
399
400 int xitwarn = /* Warn about open connection on exit */
401 #ifdef NOWARN
402 0
403 #else
404 1
405 #endif /* NOWARN */
406 ;
407
408 struct keytab onoffsw[] = {
409 { "/off", 0, 0 },
410 { "/on", 1, 0 }
411 };
412
413 #ifdef CKEXEC
414 struct keytab redirsw[] = {
415 { "/redirect", 1, 0 }
416 };
417 #endif /* CKEXEC */
418
419 #ifndef NOXMIT
420 /* Variables for TRANSMIT command */
421
422 int xmitx = 1; /* Whether to echo during TRANSMIT */
423 int xmitf = 0; /* Character to fill empty lines */
424 int xmitl = 0; /* 0 = Don't send linefeed too */
425 int xmitp = LF; /* Host line prompt */
426 int xmits = 0; /* Use shift-in/shift-out, 0 = no */
427 int xmitw = 0; /* Milliseconds to pause during TRANSMIT */
428 int xmitt = 1; /* Seconds to wait for each char to echo */
429 int xmita = 1; /* Action upon timeout */
430
431 #define XMI_BIN 1
432 #define XMI_TXT 2
433 #define XMI_CMD 3
434 #define XMI_TRA 4
435 #define XMI_VRB 5
436 #define XMI_QUI 6
437 #define XMI_NOW 7
438 #define XMI_NOE 8
439
440 static struct keytab xmitsw[] = { /* TRANSMIT command options */
441 { "/binary", XMI_BIN, 0 },
442 #ifdef PIPESEND
443 { "/command", XMI_CMD, CM_INV|CM_PSH },
444 #endif /* PIPESEND */
445 { "/noecho", XMI_NOE, 0 },
446 { "/nowait", XMI_NOW, 0 },
447 #ifdef PIPESEND
448 { "/pipe", XMI_CMD, 0 },
449 #endif /* PIPESEND */
450 #ifdef COMMENT
451 { "/quiet", XMI_QUI, 0 },
452 #endif /* COMMENT */
453 { "/text", XMI_TXT, 0 },
454 { "/transparent", XMI_TRA, 0 },
455 #ifdef COMMENT
456 { "/verbose", XMI_VRB, 0 },
457 #endif /* COMMENT */
458 { "", 0, 0 }
459 };
460 #define NXMITSW sizeof(xmitsw)/sizeof(struct keytab) - 1
461 static int nxmitsw = NXMITSW;
462
463 #endif /* NOXMIT */
464
465 /* Declarations from ck?fio.c module */
466
467 extern char *SPACMD, *SPACM2; /* SPACE commands */
468
469 /* Command-oriented items */
470
471 #ifdef DCMDBUF
472 extern char *cmdbuf; /* Command buffers */
473 extern char *atmbuf;
474 extern char *line; /* Character buffer for anything */
475 extern char *tmpbuf; /* Short temporary string buffer */
476 extern int *ifcmd;
477 extern int *intime;
478 extern int *inpcas;
479 #else
480 extern char cmdbuf[]; /* Command buffers */
481 extern char atmbuf[];
482 extern char line[]; /* Character buffer for anything */
483 extern char tmpbuf[]; /* Temporary buffer */
484 extern int ifcmd[];
485 extern int intime[];
486 extern int inpcas[];
487 #endif /* DCMDBUF */
488
489 #ifndef NOSPL
490 extern char * prstring[];
491 #endif /* NOSPL */
492
493 char *lp; /* Pointer to line buffer */
494
495 #ifndef NOSPL
496 int vareval = 1; /* Evaluation method */
497 int unkmacro = 0; /* Flag for in ON_UNKNOWN_COMMAND */
498 int oldeval = 0;
499 char evalbuf[33]; /* EVALUATE result */
500 extern char * inpbuf; /* Buffer for INPUT and REINPUT */
501 char *inpbp; /* And pointer to same */
502 int m_found; /* MINPUT result */
503 int i_active = 0; /* INPUT command is active */
504 char *ms[MINPMAX]; /* Pointers to MINPUT strings */
505 static int mpinited = 0; /* Flag they have been initialized */
506 static int mp[MINPMAX]; /* and MINPUT flags */
507 extern int fndiags, fnerror, fnsuccess; /* Function diagnostics */
508 #ifndef NOSEXP
509 char * lastsexp = NULL; /* S-Expressions */
510 char * sexpval = NULL;
511 int sexpecho = SET_AUTO;
512 #endif /* NOSEXP */
513 #endif /* NOSPL */
514
515 char psave[PROMPTL] = { NUL }; /* For saving & restoring prompt */
516
517 extern int success; /* Command success/failure flag */
518 extern int cmdlvl; /* Current position in command stack */
519
520 #ifndef NOSPL
521 int /* SET INPUT parameters. */
522 /* Note, INPUT TIMEOUT, intime[], is on the command-level stack. */
523 inbufsize = 0, /* INPUT buffer size */
524 indef = 1, /* default timeout, seconds */
525 inecho = 1, /* 1 = echo on */
526 inautodl = 0, /* INPUT autodownload */
527 inintr = 1, /* INPUT interrupion allowed */
528 insilence = 0; /* 0 = no silence constraint */
529
530 #ifdef CKFLOAT
531 CKFLOAT inscale = 1.0; /* Timeout scale factor */
532 #endif /* CKFLOAT */
533
534 #ifdef OS2
535 int interm = 1; /* Terminal emulator displays input */
536 #endif /* OS2 */
537 int maclvl = -1; /* Macro nesting level */
538 int mecho = 0; /* Macro echo, 0 = don't */
539 char varnam[6]; /* For variable names */
540 extern int macargc[]; /* ARGC from macro invocation */
541
542 extern char *m_arg[MACLEVEL][NARGS]; /* Stack of macro arguments */
543 extern char *mrval[];
544
545 extern char **a_ptr[]; /* Array pointers */
546 extern int a_dim[]; /* Array dimensions */
547 extern int a_link[];
548
549 #ifdef DCMDBUF
550 extern struct cmdptr *cmdstk; /* The command stack itself */
551 #else
552 extern struct cmdptr cmdstk[]; /* The command stack itself */
553 #endif /* DCMDBUF */
554
555 long ck_alarm = 0; /* SET ALARM value */
556 char alrm_date[24] = { ' ',' ',' ',' ',' ',' ',' ',' ',' ' };
557 char alrm_time[24] = { ' ',' ',' ',' ',' ',' ',' ' };
558
559 struct keytab inputsw[] = {
560 { "/clear", INPSW_CLR, 0 },
561 { "/count", INPSW_COU, CM_ARG },
562 { "/nomatch", INPSW_NOM, 0 },
563 { "/nowrap", INPSW_NOW, 0 }
564 };
565 static int ninputsw = sizeof(inputsw)/sizeof(struct keytab);
566
567 /* The following should be reconciled with the above */
568
569 #ifdef COMMENT /* INPUT switches not used yet... */
570 static struct keytab inswtab[] = {
571 #ifdef COMMENT
572 { "/assign", IN_ASG, CM_ARG },
573 #endif /* COMMENT */
574 { "/autodownload", IN_ADL, CM_ARG },
575 { "/case", IN_CAS, CM_ARG },
576 { "/echo", IN_ECH, CM_ARG },
577 { "/interrupts", IN_NOI, CM_ARG },
578 { "/silence", IN_SIL, CM_ARG },
579 #ifdef COMMENT
580 { "/pattern", IN_PAT, CM_ARG },
581 #endif /* COMMENT */
582 { "", 0, 0 }
583 };
584 static int ninswtab = (sizeof(inswtab) / sizeof(struct keytab)) - 1;
585 #endif /* COMMENT */
586
587
588 #endif /* NOSPL */
589
590 static int x, y, z = 0; /* Local workers */
591 static char *s;
592
593 #ifdef CK_MINPUT
594 static char c1chars[] = { /* C1 control chars escept NUL */
595 001,002,003,004,005,006,007,010,011,012,013,014,015,016,017,020,
596 021,022,023,024,025,026,027,030,031,032,033,034,035,036,037
597 };
598 #endif /* CK_MINPUT */
599
600 #define xsystem(s) zsyscmd(s)
601
602 /* Top-Level Interactive Command Keyword Table */
603 /* Keywords must be in lowercase and in alphabetical order. */
604
605 struct keytab cmdtab[] = {
606 #ifndef NOPUSH
607 { "!", XXSHE, CM_INV|CM_PSH }, /* Shell escape */
608 #else
609 { "!", XXNOTAV, CM_INV|CM_PSH },
610 #endif /* NOPUSH */
611 { "#", XXCOM, CM_INV }, /* Comment */
612 #ifndef NOSPL
613 { "(", XXSEXP,CM_INV }, /* S-Expression */
614 { ".", XXDEF, CM_INV }, /* Assignment */
615 { ":", XXLBL, CM_INV }, /* Label */
616 #endif /* NOSPL */
617 #ifdef CK_REDIR
618 #ifndef NOPUSH
619 { "<", XXFUN, CM_INV|CM_PSH }, /* REDIRECT */
620 #else
621 { "<", XXNOTAV, CM_INV|CM_PSH }, /* REDIRECT */
622 #endif /* NOPUSH */
623 #endif /* CK_REDIR */
624 #ifndef NOPUSH
625 { "@", XXSHE, CM_INV|CM_PSH }, /* DCL escape */
626 #else
627 { "@", XXNOTAV, CM_INV|CM_PSH }, /* DCL escape */
628 #endif /* NOPUSH */
629
630 #ifdef CK_RECALL
631 { "^", XXREDO,CM_INV|CM_NOR }, /* Synonym for REDO */
632 #endif /* CK_RECALL */
633 #ifndef NOSPL
634 { "_asg", XXASX, CM_INV }, /* Used internally by FOR, etc */
635 { "_assign", XXASX, CM_INV }, /* Used internally by FOR, etc */
636 { "_decrement", XX_DECR, CM_INV },
637 { "_define", XXDFX, CM_INV }, /* Used internally by FOR, etc */
638 { "_evaluate", XX_EVAL, CM_INV },
639 { "_forward", XXXFWD, CM_INV }, /* Used internally by SWITCH */
640 { "_getargs", XXGTA, CM_INV }, /* Used internally by FOR, etc */
641 { "_increment", XX_INCR, CM_INV },
642 { "_putargs", XXPTA, CM_INV }, /* Used internally by FOR, etc */
643 { "_undefine", XXUNDFX, CM_INV },
644 #endif /* NOSPL */
645
646 { "about", XXVER, CM_INV }, /* Synonym for VERSION */
647 #ifndef NOSPL
648 #ifdef NEWFTP
649 { "account", XXACCT, CM_INV }, /* (FTP) Account */
650 #endif /* NEWFTP */
651 #ifdef ADDCMD
652 { "add", XXADD, 0 }, /* ADD */
653 #endif /* ADDCMD */
654 #ifndef NODIAL
655 { "answer", XXANSW, CM_LOC }, /* ANSWER the phone */
656 #else
657 { "answer", XXNOTAV, CM_INV|CM_LOC }, /* ANSWER the phone */
658 #endif /* NODIAL */
659 { "apc", XXAPC, 0 }, /* Application Program Command */
660 #ifndef NOSPL
661 { "array", XXARRAY, 0 }, /* Array operations */
662 #endif /* NOSPL */
663 { "ascii", XXASC, CM_INV }, /* == SET FILE TYPE TEXT */
664 { "asg", XXASS, CM_INV }, /* Invisible synonym for ASSIGN */
665 { "ask", XXASK, 0 }, /* ASK for text, assign to variable */
666 { "askq", XXASKQ,0 }, /* ASK quietly (no echo) */
667 #ifndef NOSPL
668 { "ass", XXASS, CM_INV|CM_ABR }, /* ASSIGN */
669 { "assert", XXASSER, CM_INV }, /* ASSERT */
670 { "assign", XXASS, 0 }, /* ASSIGN */
671 #endif /* NOSPL */
672 #ifndef NOXFER
673 #ifndef NOCSETS
674 { "associate", XXASSOC, 0 }, /* ASSOCIATE */
675 #else
676 { "associate", XXNOTAV, CM_INV }, /* ASSOCIATE */
677 #endif /* NOCSETS */
678 #endif /* NOXFER */
679 #ifdef CK_KERBEROS
680 #ifdef CK_AUTHENTICATION
681 { "authenticate",XXAUTH, 0 }, /* Authentication */
682 #else
683 { "authenticate",XXAUTH, CM_INV },
684 #endif /* CK_AUTHENTICATION */
685 #endif /* CK_KERBEROS */
686 #endif /* NOSPL */
687 #ifndef NOFRILLS
688 { "back", XXBACK, 0 }, /* BACK to previous directory */
689 #else
690 { "back", XXNOTAV,CM_INV },
691 #endif /* NOFRILLS */
692 { "beep", XXBEEP,CM_INV }, /* BEEP */
693 #ifndef NOXFER
694 { "binary", XXBIN, CM_INV }, /* == SET FILE TYPE BINARY */
695 #endif /* NOXFER */
696 #ifndef NOFRILLS
697 { "bug", XXBUG, CM_INV }, /* BUG report instructions */
698 #else
699 { "bug", XXNOTAV, CM_INV },
700 #endif /* NOFRILLS */
701 #ifdef BROWSER
702 { "browse", XXBROWS, CM_PSH|CM_LOC }, /* BROWSE (start browser) */
703 #else
704 { "browse", XXNOTAV, CM_INV|CM_PSH|CM_LOC },
705 #endif /* BROWSER */
706 #ifndef NOXFER
707 { "bye", XXBYE, 0 }, /* BYE to remote server */
708 #endif /* NOXFER */
709 #ifndef NOLOCAL
710 { "c", XXCON, CM_INV|CM_ABR|CM_LOC }, /* (CONNECT) */
711 #endif /* NOLOCAL */
712 #ifndef NOFRILLS
713 { "cat", XXCAT, CM_INV }, /* Invisible synonym for TYPE */
714 #endif /* NOFRILLS */
715 #ifndef NOSPL
716
717 #ifndef NOXFER
718 { "cautious", XXCAU, CM_INV },
719 #endif /* NOXFER */
720
721 #endif /* NOSPL */
722
723 { "cd", XXCWD, 0 }, /* Change Directory */
724 { "cdup", XXCDUP, CM_INV }, /* Change Directory Up */
725
726 #ifndef NOXFER
727 #ifdef PIPESEND
728 { "cget", XXCGET, CM_INV|CM_PSH }, /* CGET */
729 #else
730 { "cget", XXNOTAV, CM_INV|CM_PSH }, /* CGET */
731 #endif /* PIPESEND */
732 #endif /* NOXFER */
733 { "ch", XXCHK, CM_INV|CM_ABR },
734 { "change", XXCHG, 0 }, /* CHANGE strings in file 2013-04-18 */
735 { "check", XXCHK, 0 }, /* CHECK for a feature */
736 #ifdef CK_PERMS
737 #ifdef UNIX
738 { "chmod", XXCHMOD, 0 }, /* CHMOD */
739 #else
740 { "chmod", XXNOTAV, CM_INV },
741 #endif /* UNIX */
742 #else
743 { "chmod", XXNOTAV, CM_INV },
744 #endif /* CK_PERMS */
745 #ifdef CKROOT
746 { "chroot", XXCHRT, CM_INV }, /* CHROOT */
747 #endif /* CKROOT */
748 { "ckermit", XXKERMI, CM_INV }, /* CKERMIT (like KERMIT) */
749 { "cl", XXCLO, CM_ABR|CM_INV },
750 #ifndef NOFRILLS
751 { "clear", XXCLE, 0 }, /* CLEAR input and/or device buffer */
752 #else
753 { "clear", XXNOTAV, CM_INV },
754 #endif /* NOFRILLS */
755 { "close", XXCLO, 0 }, /* CLOSE a log or other file */
756 { "cls", XXCLS, CM_INV }, /* Clear Screen (CLS) */
757 { "comment", XXCOM, CM_INV }, /* Introduce a comment */
758 #ifndef NOLOCAL
759 { "connect", XXCON, CM_LOC }, /* Begin terminal connection */
760 #else
761 { "connect", XXNOTAV, CM_LOC },
762 #endif /* NOLOCAL */
763 { "continue", XXCONT, CM_INV }, /* CONTINUE */
764 #ifndef NOFRILLS
765 #ifdef ZCOPY
766 { "co", XXCPY, CM_INV|CM_ABR },
767 { "cop", XXCPY, CM_INV|CM_ABR },
768 { "copy", XXCPY, 0 }, /* COPY a file */
769 #else
770 { "copy", XXNOTAV, CM_INV },
771 #endif /* ZCOPY */
772 { "copyright", XXCPR, CM_INV }, /* COPYRIGHT */
773 #ifdef ZCOPY
774 { "cp", XXCPY, CM_INV }, /* COPY a file */
775 #endif /* ZCOPY */
776 #ifndef NOLOCAL
777 #ifndef OS2
778 { "cq", XXCQ, CM_INV|CM_LOC }, /* CQ (connect quietly) */
779 #endif /* OS2 */
780 #endif /* NOLOCAL */
781 #ifndef NOXFER
782 #ifdef PIPESEND
783 { "creceive", XXCREC,CM_INV|CM_PSH }, /* RECEIVE to a command */
784 { "csend", XXCSEN,CM_INV|CM_PSH }, /* SEND from command */
785 #else
786 { "creceive", XXNOTAV,CM_INV|CM_PSH },
787 { "csend", XXNOTAV,CM_INV|CM_PSH },
788 #endif /* PIPESEND */
789 #endif /* NOXFER */
790 #endif /* NOFRILLS */
791
792 { "cwd", XXCWD, CM_INV }, /* Traditional synonym for cd */
793
794 #ifndef NOSPL
795 { "date", XXDATE, 0 }, /* DATE */
796 { "dcl", XXDCL, CM_INV }, /* DECLARE an array (see ARRAY) */
797 { "debug", XXDEBUG, 0 }, /* Print a debugging msg [9.0] */
798 { "declare", XXDCL, CM_INV }, /* DECLARE an array (see ARRAY) */
799 { "decrement", XXDEC, 0 }, /* DECREMENT a numeric variable */
800 { "define", XXDEF, 0 }, /* DEFINE a macro or variable */
801 #else
802 { "date", XXNOTAV, CM_INV },
803 { "dcl", XXNOTAV, CM_INV },
804 { "declare", XXNOTAV, CM_INV },
805 { "decrement", XXNOTAV, CM_INV },
806 { "define", XXNOTAV, CM_INV },
807 #endif /* NOSPL */
808
809 #ifndef NOFRILLS
810 { "delete", XXDEL, 0 }, /* DELETE a file */
811 #else
812 { "delete", XXNOTAV, CM_INV },
813 #endif /* NOFRILLS */
814
815 #ifndef NODIAL
816 { "dial", XXDIAL, CM_LOC }, /* DIAL a phone number */
817 #else
818 { "dial", XXNOTAV, CM_INV|CM_LOC },
819 #endif /* NODIAL */
820
821 #ifdef NT
822 { "dialer", XXDIALER, CM_INV }, /* K95 Dialer */
823 #endif /* NT */
824
825 { "directory", XXDIR, 0 }, /* DIRECTORY of files */
826
827 #ifndef NOFRILLS
828 #ifndef NOSERVER
829 { "disable", XXDIS, 0 }, /* DISABLE a server function */
830 #else
831 { "disable", XXNOTAV, CM_INV },
832 #endif /* NOSERVER */
833 #endif /* NOFRILLS */
834
835 #ifndef NOSPL
836 { "do", XXDO, 0 }, /* DO (execute) a macro */
837 #else
838 { "do", XXNOTAV, CM_INV },
839 #endif /* NOSPL */
840
841 { "e", XXEXI, CM_INV|CM_ABR },
842
843 #ifndef NOFRILLS
844 #ifndef NOXFER
845 { "e-packet", XXERR, CM_INV }, /* Send an Error-Packet */
846 #endif /* NOXFER */
847 #endif /* NOFRILLS */
848
849 { "echo", XXECH, 0 }, /* ECHO text */
850
851 #ifndef NOFRILLS
852 #ifndef NOPUSH
853 { "edit", XXEDIT, CM_PSH }, /* EDIT */
854 #else
855 { "edit", XXNOTAV, CM_INV|CM_PSH }, /* EDIT */
856 #endif /* NOPUSH */
857 #endif /* NOFRILLS */
858
859 { "eightbit", XXEIGHT, CM_INV }, /* EIGHTBIT */
860
861 #ifndef NOSPL
862 { "else", XXELS, CM_INV }, /* ELSE part of IF statement */
863 #else
864 { "else", XXNOTAV, CM_INV }, /* ELSE part of IF statement */
865 #endif /* NOSPL */
866
867 #ifndef NOSERVER
868 #ifndef NOFRILLS
869 { "enable", XXENA, 0 }, /* ENABLE a server function */
870 #else
871 { "enable", XXNOTAV, CM_INV },
872 #endif /* NOFRILLS */
873 #endif /* NOSERVER */
874
875 #ifndef NOSPL
876 { "end", XXEND, 0 }, /* END command file or macro */
877 #else
878 { "end", XXNOTAV, CM_INV },
879 #endif /* NOSPL */
880
881 { "erase", XXDEL, CM_INV }, /* Synonym for DELETE */
882
883 #ifndef NOSPL
884 { "evaluate", XXEVAL, 0 }, /* EVALUATE */
885 #else
886 { "evaluate", XXNOTAV, CM_INV },
887 #endif /* NOSPL */
888
889 { "ex", XXEXI, CM_INV|CM_ABR }, /* Let "ex" still be EXIT */
890
891 #ifdef CKEXEC
892 { "exec", XXEXEC, CM_INV|CM_LOC }, /* exec() */
893 #else
894 { "exec", XXNOTAV, CM_INV|CM_LOC },
895 #endif /* CKEXEC */
896
897 { "exit", XXEXI, 0 }, /* EXIT from C-Kermit */
898 { "extended-options", XXXOPTS,CM_INV|CM_HLP }, /* Extended-Options */
899
900 #ifdef OS2
901 { "extproc", XXCOM, CM_INV }, /* Dummy command for OS/2 */
902 #endif /* OS2 */
903
904 #ifndef NOXFER
905 { "f", XXFIN, CM_INV|CM_ABR }, /* Invisible abbrev for FIN */
906 #endif /* NOXFER */
907
908 #ifndef NOSPL
909 { "fail", XXFAIL, CM_INV }, /* FAIL */
910
911 #ifndef NOXFER
912 { "fast", XXFAST, CM_INV },
913 #endif /* NOXFER */
914
915 #ifdef CKCHANNELIO
916 { "fclose", XXF_CL, CM_INV }, /* FCLOSE */
917 { "fcount", XXF_CO, CM_INV }, /* FCOUNT */
918 { "fflush", XXF_FL, CM_INV }, /* FFLUSH */
919 #endif /* CKCHANNELIO */
920
921 #ifndef NOXFER
922 { "fi", XXFIN, CM_INV|CM_ABR }, /* FINISH */
923 #endif /* NOXFER */
924
925 #ifdef CKCHANNELIO
926 { "file", XXFILE, 0 }, /* FILE */
927 #endif /* CKCHANNELIO */
928 #endif /* NOSPL */
929
930 #ifndef NOXFER
931 { "fin", XXFIN, CM_INV|CM_ABR }, /* FINISH */
932 #endif /* NOXFER */
933
934 #ifndef UNIXOROSK
935 { "find", XXGREP, 0 }, /* FIND (grep) */
936 #else
937 { "find", XXGREP,CM_INV },
938 #endif /* UNIXOROSK */
939
940 #ifndef NOXFER
941 { "finish", XXFIN, 0 }, /* FINISH */
942 #endif /* NOXFER */
943
944 #ifdef TCPSOCKET
945 { "firewall", XXFIREW, CM_INV|CM_HLP },
946 #endif /* TCPSOCKET */
947
948 #ifdef CKCHANNELIO
949 { "flist", XXF_LI, CM_INV }, /* FLIST */
950 { "fopen", XXF_OP, CM_INV }, /* FOPEN */
951 #endif /* CKCHANNELIO */
952
953 #ifndef NOSPL
954 { "fo", XXFOR, CM_INV|CM_ABR }, /* Invisible abbrev for... */
955 { "for", XXFOR, 0 }, /* FOR loop */
956 { "forward", XXFWD, CM_INV }, /* FORWARD */
957 #endif /* NOSPL */
958 #ifndef NOFRILLS
959 { "fot", XXDIR, CM_INV }, /* "fot" = "dir" (for Chris) */
960 #endif /* NOFRILLS */
961
962 #ifdef CKCHANNELIO
963 { "fread", XXF_RE, CM_INV }, /* FREAD */
964 { "frewind", XXF_RW, CM_INV }, /* FREWIND */
965 { "fseek", XXF_SE, CM_INV }, /* FSEEK */
966 { "fstatus", XXF_ST, CM_INV }, /* FSTATUS */
967 #endif /* CKCHANNELIO */
968
969 #ifdef TCPSOCKET
970 #ifndef NOFTP
971 #ifdef SYSFTP
972 #ifndef NOPUSH
973 { "ftp", XXFTP, CM_INV|CM_PSH|CM_LOC }, /* System FTP */
974 #else
975 { "ftp", XXNOTAV, CM_INV|CM_PSH|CM_LOC },
976 #endif /* NOPUSH */
977 #else /* SYSFTP */
978 { "ftp", XXFTP, 0 }, /* Built-in FTP */
979 #endif /* SYSFTP */
980 #else /* NOFTP */
981 { "ftp", XXNOTAV, CM_INV }, /* No FTP */
982 #endif /* NOFTP */
983 #endif /* TCPSOCKET */
984
985 #ifndef NOSPL
986 { "function", XXFUNC, CM_INV|CM_HLP }, /* (for HELP FUNCTION) */
987 #endif /* NOSPL */
988
989 #ifdef CKCHANNELIO
990 { "fwrite", XXF_WR, CM_INV }, /* FWRITE */
991 #endif /* CKCHANNELIO */
992
993 #ifndef NOXFER
994 { "g", XXGET, CM_INV|CM_ABR }, /* Invisible abbrev for GET */
995 #ifndef NOSPL
996 { "ge", XXGET, CM_INV|CM_ABR }, /* Ditto */
997 #endif /* NOSPL */
998 { "get", XXGET, 0 }, /* GET */
999 #endif /* NOXFER */
1000 #ifndef NOSPL
1001 { "getc", XXGETC, 0 }, /* GETC */
1002 #ifdef OS2
1003 { "getkeycode", XXGETK, 0 }, /* GETKEYCODE */
1004 #endif /* OS2 */
1005 #ifndef NOFRILLS
1006 { "getok", XXGOK, 0 }, /* GETOK (ask for Yes/No/OK) */
1007 #endif /* NOFRILLS */
1008 #endif /* NOSPL */
1009 #ifndef NOSPL
1010 { "goto", XXGOTO,0 }, /* GOTO label in take file or macro */
1011 #endif /* NOSPL */
1012 #ifdef UNIXOROSK
1013 { "grep", XXGREP,0 }, /* GREP (find) */
1014 #else
1015 { "grep", XXGREP,CM_INV }, /* GREP (find) */
1016 #endif /* UNIXOROSK */
1017 { "h", XXHLP, CM_INV|CM_ABR }, /* Invisible synonym for HELP */
1018 { "he", XXHLP, CM_INV|CM_ABR }, /* Invisible synonym for HELP */
1019 #ifndef NOFRILLS
1020 { "head", XXHEAD, 0 },
1021 #endif /* NOFRILLS */
1022 #ifndef NOLOCAL
1023 { "hangup", XXHAN, CM_LOC }, /* HANGUP the connection */
1024 #endif /* NOLOCAL */
1025 { "hdirectory", XXHDIR, CM_INV }, /* DIR sorted by size biggest first */
1026 { "HELP", XXHLP, 0 }, /* Display HELP text */
1027 #ifndef NOHTTP
1028 #ifdef TCPSOCKET
1029 { "http", XXHTTP, 0 }, /* HTTP operations */
1030 #endif /* TCPSOCKET */
1031 #endif /* NOHTTP */
1032 #ifndef NOSPL
1033 { "i", XXINP, CM_INV|CM_ABR }, /* Invisible synonym for INPUT */
1034 { "if", XXIF, 0 }, /* IF ( condition ) command */
1035 #ifdef TCPSOCKET
1036 { "iksd", XXIKSD, CM_INV }, /* Make connection to IKSD */
1037 #else
1038 { "iksd", XXNOTAV, CM_INV },
1039 #endif /* TCPSOCKET */
1040 { "in", XXINP, CM_INV|CM_ABR }, /* Invisible synonym for INPUT */
1041 { "increment", XXINC, 0 }, /* Increment a numeric variable */
1042 { "input", XXINP, 0 }, /* INPUT text from comm device */
1043 #endif /* NOSPL */
1044
1045 #ifndef NOHELP
1046 { "int", XXINT, CM_INV|CM_ABR },
1047 { "intr", XXINT, CM_INV|CM_ABR },
1048 { "INTRO", XXINT, 0 },
1049 { "introduction",XXINT, CM_INV }, /* Print introductory text */
1050 #else
1051 { "intro", XXNOTAV, CM_INV },
1052 { "introduction",XXNOTAV, CM_INV },
1053 #endif /* NOHELP */
1054
1055 #ifdef OS2
1056 { "k95", XXKERMI, CM_INV }, /* Hmmm what's this... */
1057 #endif /* OS2 */
1058
1059 #ifndef NOSPL
1060 { "kcd", XXKCD, 0 },
1061 #endif /* NOSPL */
1062
1063 { "kermit", XXKERMI, CM_INV },
1064
1065 #ifdef OS2
1066 #ifndef NOKVERBS
1067 { "kverb", XXKVRB, CM_INV|CM_HLP }, /* Keyboard verb */
1068 #endif /* NOKVERBS */
1069 #endif /* OS2 */
1070
1071 #ifndef NOFRILLS
1072 { "l", XXLOG, CM_INV|CM_ABR }, /* Invisible synonym for log */
1073 #endif /* NOFRILLS */
1074
1075 { "lcd", XXLCWD, CM_INV },
1076 { "lcdup", XXLCDU, CM_INV },
1077 { "lcwd", XXLCWD, CM_INV },
1078 { "ldelete", XXLDEL, CM_INV },
1079 { "ldirectory", XXLDIR, CM_INV },
1080
1081 #ifdef CKLEARN
1082 { "learn", XXLEARN, 0 }, /* LEARN - automatic script writing */
1083 #else
1084 { "learn", XXNOTAV, CM_INV },
1085 #endif /* CKLEARN */
1086
1087 { "li", XXLNOUT, CM_INV|CM_ABR },
1088 { "LICENSE", XXCPR, 0 }, /* LICENSE */
1089
1090 #ifndef NOSPL
1091 { "lineout", XXLNOUT, 0 }, /* LINEOUT = OUTPUT + eol */
1092 #endif /* NOSPL */
1093
1094 #ifdef NT
1095 { "link", XXLINK, 0 }, /* LINK source destination */
1096 #endif /* NT */
1097
1098 { "lmkdir", XXLMKD, CM_INV },
1099 { "lmv", XXLREN, CM_INV },
1100
1101 #ifndef NOFRILLS
1102 { "lo", XXLOG, CM_INV|CM_ABR }, /* Invisible synonym for log */
1103 #endif /* NOFRILLS */
1104
1105 #ifndef NOSPL
1106 { "local", XXLOCAL, CM_INV }, /* LOCAL variable declaration */
1107 #else
1108 { "local", XXNOTAV, CM_INV },
1109 #endif /* NOSPL */
1110
1111 { "locus", XXLOCU, CM_INV|CM_HLP }, /* "help locus" */
1112
1113 { "log", XXLOG, 0 }, /* Open a log file */
1114
1115 { "login", XXLOGIN, 0 }, /* (REMOTE) LOGIN to server or IKSD */
1116 { "logout", XXLOGOUT, 0 }, /* LOGOUT from server or IKSD */
1117
1118 #ifndef NOFRILLS
1119 #ifndef NODIAL
1120 { "lookup", XXLOOK, 0 }, /* LOOKUP */
1121 #else
1122 { "lookup", XXNOTAV, CM_INV },
1123 #endif /* NODIAL */
1124
1125 { "lpwd", XXLPWD, CM_INV },
1126 { "lrename", XXLREN, CM_INV },
1127 { "lrmdir", XXLRMD, CM_INV },
1128
1129 #ifdef UNIXOROSK
1130 { "ls", XXLS, CM_INV|CM_PSH }, /* UNIX ls command */
1131 #else
1132 { "ls", XXDIR, CM_INV }, /* Invisible synonym for DIR */
1133 #endif /* UNIXOROSK */
1134 #ifndef NOXFER
1135 { "mail", XXMAI, 0 }, /* Send a file as e-mail */
1136 #endif /* NOXFER */
1137 #ifndef NOHELP
1138 { "manual", XXMAN, CM_PSH }, /* MAN(UAL) */
1139 #else
1140 { "manual", XXNOTAV, CM_INV|CM_PSH },
1141 #endif /* NOHELP */
1142 #endif /* NOFRILLS */
1143 #ifdef CK_MKDIR
1144 { "md", XXMKDIR, CM_INV }, /* Synonym for MKDIR */
1145 #endif /* CK_MKDIR */
1146 { "message", XXMSG, 0 }, /* Print debugging message */
1147 #ifdef CK_MINPUT
1148 { "minput", XXMINP, 0 }, /* MINPUT */
1149 #else
1150 { "minput", XXNOTAV, CM_INV },
1151 #endif /* CK_MINPUT */
1152 #ifndef NOMSEND
1153 { "mget", XXMGET, 0 }, /* MGET */
1154 #else
1155 { "mget", XXNOTAV, CM_INV },
1156 #endif /* NOMSEND */
1157 #ifdef CK_MKDIR
1158 { "mkdir", XXMKDIR, 0 }, /* MKDIR */
1159 #else
1160 { "mkdir", XXNOTAV, CM_INV },
1161 #endif /* CK_MKDIR */
1162
1163 #ifndef NOXFER
1164 #ifndef NOMSEND
1165 { "mmove", XXMMOVE, 0 }, /* MMOVE */
1166 #else
1167 { "mmove", XXNOTAV, CM_INV },
1168 #endif /* NOMSEND */
1169 #endif /* NOXFER */
1170
1171 #ifndef NOFRILLS
1172 { "more", XXMORE, CM_INV }, /* MORE */
1173 #endif /* NOFRILLS */
1174
1175 #ifdef OLDMOVE
1176 #ifndef NOXFER
1177 { "move", XXMOVE, 0 }, /* MOVE = SEND /DELETE */
1178 #endif /* NOXFER */
1179 #else
1180 { "move", XXREN, CM_INV }, /* MOVE = RENAME */
1181 #endif /* OLDMOVE */
1182
1183 #ifndef NOSPL
1184 { "mpause", XXMSL, CM_INV }, /* Millisecond sleep */
1185 #else
1186 { "mpause", XXNOTAV, CM_INV },
1187 #endif /* NOSPL */
1188
1189 #ifndef NOXFER
1190 #ifndef NOMSEND
1191 { "mput", XXMSE, CM_INV }, /* MPUT = MSEND */
1192 { "ms", XXMSE, CM_INV|CM_ABR },
1193 { "msend", XXMSE, 0 }, /* Multiple SEND */
1194 #else
1195 { "mput", XXNOTAV, CM_INV },
1196 { "msend", XXNOTAV, CM_INV },
1197 #endif /* NOMSEND */
1198 #endif /* NOXFER */
1199 { "msg", XXMSG, CM_INV }, /* Print debugging message */
1200 #ifndef NOSPL
1201 { "msleep", XXMSL, 0 }, /* Millisecond sleep */
1202 #else
1203 { "msleep", XXNOTAV, CM_INV },
1204 #endif /* NOSPL */
1205 #ifndef NOFRILLS
1206 { "mv", XXREN, CM_INV }, /* Synonym for rename */
1207 #endif /* NOFRILLS */
1208 #ifndef NOHELP
1209 { "news", XXNEW, CM_INV }, /* Display NEWS of new features */
1210 #else
1211 { "news", XXNOTAV, CM_INV },
1212 #endif /* NOHELP */
1213 { "nolocal", XXNLCL, CM_INV }, /* Disable SET LINE / SET HOST */
1214 { "nopush", XXNPSH, CM_INV }, /* Disable PUSH command/features */
1215 #ifdef OS2
1216 { "noscroll", XXNSCR, CM_INV }, /* Disable scroll operations */
1217 #endif /* OS2 */
1218 #ifndef NOSPL
1219 { "o", XXOUT, CM_INV|CM_ABR }, /* Invisible synonym for OUTPUT */
1220 { "open", XXOPE, 0 }, /* OPEN file for reading or writing */
1221 #else
1222 { "open", XXOPE, CM_INV }, /* OPEN */
1223 #endif /* NOSPL */
1224 #ifndef NOHELP
1225 { "options", XXOPTS,CM_INV|CM_HLP }, /* Options */
1226 #endif /* NOHELP */
1227 { "orientation", XXORIE, 0 },
1228 #ifndef NOSPL
1229 { "output", XXOUT, 0 }, /* OUTPUT text to comm device */
1230 #else
1231 { "output", XXNOTAV, CM_INV },
1232 #endif /* NOSPL */
1233 #ifdef ANYX25
1234 #ifndef IBMX25
1235 { "pad", XXPAD, CM_LOC }, /* X.3 PAD commands */
1236 #endif /* IBMX25 */
1237 #endif /* ANYX25 */
1238
1239 #ifdef NEWFTP
1240 { "passive", XXPASV, CM_INV }, /* (FTP) PASSIVE */
1241 #endif /* NEWFTP */
1242
1243 #ifndef NOHELP
1244 { "patterns", XXPAT,CM_INV|CM_HLP }, /* Pattern syntax */
1245 #endif /* NOHELP */
1246
1247 #ifndef NOSPL
1248 { "pause", XXPAU, 0 }, /* Sleep for specified interval */
1249 #else
1250 { "pause", XXNOTAV, CM_INV },
1251 #endif /* NOSPL */
1252 #ifndef NODIAL
1253 { "pdial", XXPDIA, CM_LOC }, /* PDIAL (partial dial) */
1254 #else
1255 { "pdial", XXNOTAV, CM_INV|CM_LOC },
1256 #endif /* NODIAL */
1257 #ifdef TCPSOCKET
1258 #ifndef NOPUSH
1259 { "ping", XXPNG, CM_INV|CM_PSH|CM_LOC }, /* PING */
1260 #else
1261 { "ping", XXNOTAV, CM_INV|CM_PSH|CM_LOC },
1262 #endif /* NOPUSH */
1263 #endif /* TCPSOCKET */
1264 #ifdef NETCMD
1265 #ifndef NOPUSH
1266 { "pipe", XXPIPE, CM_PSH }, /* PIPE */
1267 #else
1268 { "pipe", XXNOTAV, CM_INV|CM_PSH }, /* PIPE */
1269 #endif /* NOPUSH */
1270 #endif /* NETCMD */
1271
1272 #ifndef NOSPL
1273 { "pop", XXEND, CM_INV }, /* Invisible synonym for END */
1274 #endif /* NOSPL */
1275 #ifndef NOFRILLS
1276 { "print", XXPRI, 0 }, /* PRINT a file locally */
1277 #endif /* NOFRILLS */
1278
1279 { "prompt", XXPROMP, CM_INV }, /* Go interactive (from script) */
1280
1281 #ifndef NOXFER
1282 #ifdef CK_RESEND
1283 { "psend", XXPSEN, CM_INV }, /* PSEND */
1284 #else
1285 { "psend", XXNOTAV, CM_INV },
1286 #endif /* CK_RESEND */
1287 #endif /* NOXFER */
1288
1289 #ifdef NETPTY
1290 { "pty", XXPTY, CM_PSH }, /* PTY */
1291 #else
1292 { "pty", XXNOTAV, CM_INV|CM_PSH },
1293 #endif /* NETPTY */
1294
1295 #ifndef NOPUSH
1296 { "pu", XXSHE, CM_INV|CM_ABR|CM_PSH }, /* PU = PUSH */
1297 #endif /* NOPUSH */
1298
1299 #ifdef CKPURGE
1300 { "purge", XXPURGE, 0 }, /* PURGE (real) */
1301 #else
1302 #ifdef VMS
1303 { "purge", XXPURGE, 0 }, /* PURGE (fake) */
1304 #else
1305 { "purge", XXNOTAV, CM_INV },
1306 #endif /* VMS */
1307 #endif /* CKPURGE */
1308
1309 #ifndef NOPUSH
1310 { "push", XXSHE, CM_PSH }, /* PUSH command (like RUN, !) */
1311 #else
1312 { "push", XXNOTAV, CM_INV|CM_PSH },
1313 #endif /* NOPUSH */
1314
1315 #ifndef NOXFER
1316 { "put", XXSEN, CM_INV }, /* PUT = SEND */
1317 #endif /* NOXFER */
1318
1319 #ifdef UNIX
1320 #ifndef NOPUTENV
1321 { "putenv", XXPUTE, CM_INV }, /* PUTENV */
1322 #endif /* NOPUTENV */
1323 #endif /* UNIX */
1324
1325 { "pwd", XXPWD, 0 }, /* Print Working Directory */
1326 { "q", XXQUI, CM_INV|CM_ABR }, /* Invisible synonym for QUIT */
1327
1328 #ifndef NOXFER
1329 { "query", XXRQUE,CM_INV }, /* (= REMOTE QUERY) */
1330 #endif /* NOXFER */
1331
1332 { "quit", XXQUI, 0 }, /* QUIT from program = EXIT */
1333
1334 #ifndef NOXFER
1335 { "r", XXREC, CM_INV|CM_ABR }, /* Inv synonym for RECEIVE */
1336 #endif /* NOXFER */
1337
1338 #ifndef NOXFER
1339 { "rasg", XXRASG, CM_INV }, /* REMOTE ASSIGN */
1340 { "rassign", XXRASG, CM_INV }, /* ditto */
1341 { "rcd", XXRCWD, CM_INV }, /* REMOTE CD */
1342 { "rcdup", XXRCDUP,CM_INV }, /* REMOTE CD */
1343 { "rcopy", XXRCPY, CM_INV }, /* REMOTE COPY */
1344 { "rcwd", XXRCWD, CM_INV }, /* REMOTE CWD */
1345 { "rdelete", XXRDEL, CM_INV }, /* REMOTE DELETE */
1346 { "rdirectory", XXRDIR, CM_INV }, /* REMODE DIRECTORY */
1347 #endif /* NOXFER */
1348
1349 #ifndef NOSPL
1350 { "read", XXREA, 0 }, /* READ a line from a file */
1351 #else
1352 { "read", XXNOTAV, CM_INV },
1353 #endif /* NOSPL */
1354
1355 #ifndef NOXFER
1356 { "receive", XXREC, 0 }, /* RECEIVE files */
1357 #endif /* NOXFER */
1358
1359 #ifndef NODIAL
1360 { "red", XXRED, CM_INV|CM_ABR|CM_LOC }, /* Inv syn for REDIAL */
1361 { "redi", XXRED, CM_INV|CM_ABR|CM_LOC }, /* ditto */
1362 { "redial", XXRED, CM_LOC }, /* REDIAL last DIAL number */
1363 #else
1364 { "red", XXNOTAV, CM_INV|CM_LOC },
1365 { "redi", XXNOTAV, CM_INV|CM_LOC },
1366 { "redial", XXNOTAV, CM_INV|CM_LOC },
1367 #endif /* NODIAL */
1368
1369 #ifdef CK_REDIR
1370 #ifdef OS2
1371 #ifndef NOPUSH
1372 { "redirect", XXFUN, CM_INV|CM_PSH }, /* REDIRECT */
1373 #else
1374 { "redirect", XXNOTAV, CM_INV|CM_PSH },
1375 #endif /* NOPUSH */
1376 #else /* OS2 */
1377 #ifndef NOPUSH
1378 { "redirect", XXFUN, CM_PSH }, /* REDIRECT */
1379 #else
1380 { "redirect", XXNOTAV, CM_INV|CM_PSH },
1381 #endif /* NOPUSH */
1382 #endif /* OS2 */
1383 #endif /* CK_REDIR */
1384
1385 #ifdef CK_RECALL
1386 { "redo", XXREDO, CM_NOR }, /* REDO */
1387 #else
1388 { "redo", XXNOTAV, CM_INV },
1389 #endif /* CK_RECALL */
1390
1391 #ifndef NOXFER
1392 #ifdef CK_RESEND
1393 { "reget", XXREGET, 0 }, /* REGET */
1394 #else
1395 { "reget", XXNOTAV, CM_INV },
1396 #endif /* CK_RESEND */
1397 #endif /* NOXFER */
1398
1399 #ifndef NOSPL
1400 { "reinput", XXREI, CM_INV }, /* REINPUT (from INPUT buffer) */
1401 #else
1402 { "reinput", XXNOTAV, CM_INV },
1403 #endif /* NOSPL */
1404
1405 #ifndef NOXFER
1406 #ifdef ADDCMD
1407 { "rem", XXREM, CM_INV|CM_ABR },
1408 { "remo", XXREM, CM_INV|CM_ABR },
1409 #endif /* ADDCMD */
1410 { "remote", XXREM, 0 }, /* Send REMOTE command to server */
1411 #endif /* NOXFER */
1412
1413 #ifdef ADDCMD
1414 { "remove", XXREMV,0 }, /* REMOVE (something from a list) */
1415 #else
1416 { "remove", XXNOTAV, CM_INV },
1417 #endif /* ADDCMD */
1418
1419 #ifndef NOFRILLS
1420 #ifndef NORENAME
1421 { "rename", XXREN, 0 }, /* RENAME a local file */
1422 #else
1423 { "rename", XXNOTAV, CM_INV },
1424 #endif /* NORENAME */
1425 { "replay", XXTYP, CM_INV }, /* REPLAY (for now, just type) */
1426 #endif /* NOFRILLS */
1427
1428 #ifndef NOXFER
1429 #ifdef CK_RESEND
1430 { "rep", XXTYP, CM_INV|CM_ABR }, /* REPLAY abbreviation */
1431 { "reput", XXRSEN, CM_INV }, /* REPUT = RESEND */
1432 { "res", XXRSEN, CM_INV|CM_ABR }, /* RESEND */
1433 { "rese", XXRSEN, CM_INV|CM_ABR }, /* RESEND */
1434 { "resend", XXRSEN, 0 }, /* RESEND */
1435 #else
1436 { "reput", XXNOTAV, CM_INV },
1437 { "res", XXNOTAV, CM_INV },
1438 { "rese", XXNOTAV, CM_INV },
1439 { "resend", XXNOTAV, CM_INV },
1440 #endif /* CK_RESEND */
1441 #endif /* NOXFER */
1442
1443 { "reset", XXRESET, CM_INV }, /* RESET */
1444
1445 #ifdef CK_RESEND
1446 #ifndef NOSPL
1447 { "ret", XXRET, CM_INV|CM_ABR },
1448 #endif /* NOSPL */
1449 #endif /* CK_RESEND */
1450
1451 #ifndef NOXFER
1452 { "retrieve", XXRETR, CM_INV }, /* RETRIEVE */
1453 #endif /* NOXFER */
1454
1455 #ifndef NOSPL
1456 { "return", XXRET, 0 }, /* RETURN from a function */
1457 #else
1458 { "return", XXNOTAV, CM_INV },
1459 #endif /* NOSPL */
1460
1461 #ifndef NOXFER
1462 { "rexit", XXRXIT, CM_INV }, /* REMOTE EXIT */
1463 #endif /* NOXFER */
1464
1465 #ifdef CK_REXX
1466 #ifndef NOPUSH
1467 { "rexx", XXREXX, CM_PSH }, /* Execute a Rexx command */
1468 #else
1469 { "rexx", XXNOTAV, CM_INV|CM_PSH },
1470 #endif /* NOPUSH */
1471 #endif /* CK_REXX */
1472
1473 #ifndef NOXFER
1474 { "rhelp", XXRHLP, CM_INV }, /* REMOTE HELP */
1475 { "rhost", XXRHOS, CM_INV }, /* REMOTE HOST */
1476 { "rkermit", XXRKER, CM_INV }, /* REMOTE KERMIT */
1477 #endif /* NOXFER */
1478
1479 #ifdef TCPSOCKET
1480 { "rlogin", XXRLOG, CM_LOC }, /* Make an Rlogin connection */
1481 #else
1482 { "rlogin", XXNOTAV, CM_INV|CM_LOC },
1483 #endif /* TCPSOCKET */
1484
1485 #ifndef NOFRILLS
1486 { "rm", XXDEL, CM_INV }, /* Invisible synonym for delete */
1487 #endif /* NOFRILLS */
1488
1489 #ifdef CK_MKDIR
1490 { "rmdir", XXRMDIR, 0 }, /* RMDIR */
1491 #else
1492 { "rmdir", XXNOTAV, CM_INV },
1493 #endif /* CK_MKDIR */
1494
1495 #ifndef NOXFER
1496 { "rmessage", XXRMSG, CM_INV }, /* REMOTE MESSAGE */
1497 { "rmkdir", XXRMKD, CM_INV }, /* REMOTE MKDIR */
1498 { "rmsg", XXRMSG, CM_INV }, /* REMOTE MESSAGE */
1499 #ifndef NOSPL
1500 { "robust", XXROB, CM_INV },
1501 #else
1502 { "robust", XXNOTAV, CM_INV },
1503 #endif /* NOSPL */
1504 { "rprint", XXRPRI, CM_INV }, /* REMOTE PRINT */
1505 { "rpwd", XXRPWD, CM_INV }, /* REMOTE PWD */
1506 { "rquery", XXRQUE, CM_INV }, /* REMOTE QUERY */
1507 #endif /* NOXFER */
1508
1509 #ifdef CK_RECALL
1510 { "rr", XXREDO, CM_INV|CM_NOR },
1511 #endif /* CK_RECALL */
1512
1513 #ifndef NOXFER
1514 { "rrename", XXRREN, CM_INV }, /* REMOTE RENAME */
1515 { "rrmdir", XXRRMD, CM_INV }, /* REMOTE REMDIR */
1516 { "rset", XXRSET, CM_INV }, /* REMOTE SET */
1517 { "rspace", XXRSPA, CM_INV }, /* REMOTE SPACE */
1518 { "rtype", XXRTYP, CM_INV }, /* REMOTE TYPE */
1519 #endif /* NOXFER */
1520
1521 #ifndef NOPUSH
1522 { "run", XXSHE, CM_PSH }, /* RUN a program or command */
1523 #else
1524 { "run", XXNOTAV, CM_INV|CM_PSH },
1525 #endif /* NOPUSH */
1526
1527 #ifndef NOXFER
1528 { "rwho", XXRWHO, CM_INV }, /* REMOTE WHO */
1529 { "s", XXSEN, CM_INV|CM_ABR }, /* Invisible synonym for send */
1530 #endif /* NOXFER */
1531
1532 #ifndef NOSETKEY
1533 #ifdef OS2
1534 { "save", XXSAVE, 0 }, /* SAVE something */
1535 #else
1536 { "save", XXSAVE, CM_INV },
1537 #endif /* OS2 */
1538 #else
1539 { "save", XXNOTAV, CM_INV },
1540 #endif /* NOSETKEY */
1541
1542 #ifndef NOSCRIPT
1543 { "sc", XXLOGI, CM_INV|CM_ABR|CM_LOC },
1544 { "scr", XXLOGI, CM_INV|CM_ABR|CM_LOC },
1545 #endif /* NOSCRIPT */
1546 { "screen", XXSCRN, 0 }, /* SCREEN actions */
1547 #ifndef NOSCRIPT
1548 { "script", XXLOGI, CM_LOC }, /* Expect-Send-style script line */
1549 #else
1550 { "script", XXNOTAV, CM_INV|CM_LOC },
1551 #endif /* NOSCRIPT */
1552
1553 { "search", XXGREP,CM_INV }, /* Synonym for GREP and FIND */
1554
1555 #ifndef NOXFER
1556 { "send", XXSEN, 0 }, /* Send (a) file(s) */
1557 #ifndef NOSERVER
1558 { "server", XXSER, 0 }, /* Be a SERVER */
1559 #else
1560 { "server", XXNOTAV, CM_INV },
1561 #endif /* NOSERVER */
1562 #endif /* NOXFER */
1563
1564 { "set", XXSET, 0 }, /* SET parameters */
1565
1566 #ifndef NOSPL
1567 #ifndef NOSEXP
1568 { "sexpression", XXSEXP, CM_INV|CM_HLP }, /* SEXPR */
1569 #endif /* NOSEXP */
1570
1571 #ifdef SFTP_BUILTIN
1572 { "sftp", XXSFTP, 0 }, /* SFTP */
1573 #endif /* SFTP_BUILTIN */
1574
1575 #ifndef NOSHOW
1576 { "sh", XXSHO, CM_INV|CM_ABR }, /* SHOW parameters */
1577 #endif /* NOSHOW */
1578 { "shift", XXSHIFT, 0 }, /* SHIFT args */
1579 #else
1580 { "shift", XXNOTAV, CM_INV },
1581 #endif /* NOSPL */
1582
1583 #ifndef NOSHOW
1584 { "show", XXSHO, 0 }, /* SHOW parameters */
1585 #else
1586 { "show", XXNOTAV, CM_INV },
1587 #endif /* NOSHOW */
1588
1589 #ifdef NEWFTP
1590 { "site", XXSITE, CM_INV }, /* (FTP) SITE */
1591 #endif /* NEWFTP */
1592
1593 #ifdef SSHBUILTIN
1594 { "skermit", XXSKRM, 0 }, /* SKERMIT */
1595 #endif /* SSHBUILTIN */
1596
1597 #ifndef NOSPL
1598 #ifndef NOFRILLS
1599 { "sleep", XXPAU, CM_INV }, /* SLEEP for specified interval */
1600 #endif /* NOFRILLS */
1601 #endif /* NOSPL */
1602
1603 #ifndef NOSPL
1604 { "sort", XXSORT, CM_INV }, /* (see ARRAY) */
1605 #else
1606 { "sort", XXNOTAV, CM_INV },
1607 #endif /* NOSPL */
1608
1609 #ifndef MAC
1610 #ifndef NOFRILLS
1611 { "sp", XXSPA, CM_INV|CM_ABR },
1612 { "spa", XXSPA, CM_INV|CM_ABR },
1613 #endif /* NOFRILLS */
1614 { "space", XXSPA, 0 }, /* Show available disk SPACE */
1615 #endif /* MAC */
1616
1617 #ifndef NOFRILLS
1618 #ifndef NOPUSH
1619 { "spawn", XXSHE, CM_INV|CM_PSH }, /* Synonym for PUSH, RUN */
1620 #else
1621 { "spawn", XXNOTAV, CM_INV|CM_PSH }, /* Synonym for PUSH, RUN */
1622 #endif /* NOPUSH */
1623 #endif /* NOFRILLS */
1624
1625 #ifdef ANYSSH
1626 { "ssh", XXSSH, 0 },
1627 #endif /* ANYSSH */
1628
1629 #ifndef NOXFER
1630 { "sta", XXSTA, CM_INV|CM_ABR },
1631 { "stat", XXSTA, CM_INV|CM_ABR },
1632 { "statistics", XXSTA, 0 }, /* Display file transfer stats */
1633 #endif /* NOXFER */
1634
1635 { "status", XXSTATUS,0 }, /* Show status of previous command */
1636
1637 #ifndef NOSPL
1638 { "stop", XXSTO, 0 }, /* STOP all take files and macros */
1639 { "succeed", XXSUCC, CM_INV }, /* SUCCEED */
1640 #else
1641 { "stop", XXNOTAV, CM_INV },
1642 { "succeed", XXNOTAV, CM_INV },
1643 #endif /* NOSPL */
1644
1645 #ifndef NOFRILLS
1646 { "SUPPORT", XXBUG, 0 }, /* Tech support instructions */
1647 #else
1648 { "support", XXNOTAV, CM_INV },
1649 #endif /* NOFRILLS */
1650
1651 #ifndef NOJC
1652 { "suspend", XXSUS, CM_PSH }, /* SUSPEND C-Kermit (UNIX only) */
1653 #else
1654 { "suspend", XXNOTAV, CM_INV|CM_PSH },
1655 #endif /* NOJC */
1656
1657 #ifndef NOSPL
1658 { "switch", XXSWIT, 0 }, /* SWITCH */
1659 #else
1660 { "switch", XXNOTAV, CM_INV },
1661 #endif /* NOSPL */
1662
1663 #ifdef CK_TAPI
1664 { "ta", XXTAK, CM_INV|CM_ABR }, /* (because of TAPI) */
1665 #endif /* CK_TAPI */
1666
1667 #ifndef NOFRILLS
1668 { "tail", XXTAIL, 0 }, /* Display end of a local file */
1669 #endif /* NOFRILLS */
1670
1671 { "take", XXTAK, 0 }, /* TAKE commands from a file */
1672
1673 #ifdef CK_TAPI
1674 { "tapi", XXTAPI, CM_LOC }, /* Microsoft TAPI commands */
1675 #else
1676 { "tapi", XXNOTAV, CM_INV|CM_LOC },
1677 #endif /* CK_TAPI */
1678
1679 #ifndef NOFRILLS
1680 #ifdef TCPSOCKET
1681 { "tel", XXTEL, CM_INV|CM_ABR|CM_LOC },
1682 { "telnet", XXTEL, CM_LOC }, /* TELNET (TCP/IP only) */
1683 { "telopt", XXTELOP, CM_INV }, /* TELOPT (ditto) */
1684 #else
1685 { "tel", XXNOTAV, CM_INV|CM_LOC },
1686 { "telnet", XXNOTAV, CM_INV|CM_LOC },
1687 { "telopt", XXNOTAV, CM_INV },
1688 #endif /* TCPSOCKET */
1689 #ifdef OS2
1690 { "terminal", XXTERM, CM_INV|CM_LOC }, /* == SET TERMINAL TYPE */
1691 #else
1692 { "terminal", XXTERM, CM_INV },
1693 #endif /* OS2 */
1694 #endif /* NOFRILLS */
1695 #ifndef NOXFER
1696 { "text", XXASC, CM_INV }, /* == SET FILE TYPE TEXT */
1697 #endif /* NOXFER */
1698 { "touch", XXTOUC, 0 }, /* TOUCH */
1699 #ifndef NOSPL
1700 { "trace", XXTRACE, 0 }, /* TRACE */
1701 #else
1702 { "trace", XXNOTAV, CM_INV },
1703 #endif /* NOSPL */
1704
1705 #ifndef NOCSETS
1706 { "translate", XXXLA, 0 }, /* TRANSLATE local file char sets */
1707 #else
1708 { "translate", XXNOTAV, CM_INV },
1709 #endif /* NOCSETS */
1710
1711 #ifndef NOXMIT
1712 { "transmit", XXTRA, 0 }, /* Send (upload) a file, no protocol */
1713 #else
1714 { "transmit", XXNOTAV, CM_INV },
1715 #endif /* NOXMIT */
1716
1717 #ifndef NOFRILLS
1718 { "type", XXTYP, 0 }, /* Display a local file */
1719 #endif /* NOFRILLS */
1720
1721 #ifndef NOSPL
1722 { "undcl", XXUNDCL, CM_INV },
1723 { "undeclare", XXUNDCL, 0 }, /* UNDECLARE an array */
1724 { "undefine", XXUNDEF, 0 }, /* UNDEFINE a variable or macro */
1725 #else
1726 { "undcl", XXNOTAV, CM_INV },
1727 { "undeclare", XXNOTAV, CM_INV },
1728 { "undefine", XXNOTAV, CM_INV },
1729 #endif /* NOSPL */
1730
1731 #ifdef NEWFTP
1732 { "user", XXUSER, CM_INV }, /* (FTP) USER */
1733 #endif /* NEWFTP */
1734
1735 { "version", XXVER, 0 }, /* VERSION-number display */
1736
1737 #ifdef OS2
1738 { "viewonly", XXVIEW, CM_LOC }, /* VIEWONLY Terminal Mode */
1739 #endif /* OS2 */
1740
1741 { "void", XXVOID, 0 }, /* VOID */
1742
1743 #ifndef NOSPL
1744 { "wait", XXWAI, 0 }, /* WAIT */
1745 #else
1746 { "wait", XXNOTAV, CM_INV },
1747 #endif /* NOSPL */
1748
1749 { "wdirectory", XXWDIR, CM_INV }, /* Like TOPS-20, reverse chron order */
1750 { "wermit", XXKERMI, CM_INV },
1751
1752 #ifndef NOXFER
1753 { "where", XXWHERE, 0 }, /* WHERE (did my file go?) */
1754 #endif /* NOXFER */
1755
1756 #ifndef NOSPL
1757 { "while", XXWHI, 0 }, /* WHILE loop */
1758 #else
1759 { "while", XXNOTAV, CM_INV },
1760 #endif /* NOSPL */
1761
1762 #ifndef OS2
1763 #ifndef MAC
1764 #ifndef NOFRILLS
1765 { "who", XXWHO, CM_PSH }, /* WHO's logged in? */
1766 #endif /* NOFRILLS */
1767 #endif /* MAC */
1768 #endif /* OS2 */
1769
1770 #ifndef NOHELP
1771 { "wildcards", XXWILD,CM_INV|CM_HLP }, /* Wildcard syntax */
1772 #endif /* NOHELP */
1773
1774 #ifndef NOSPL
1775 { "wr", XXWRI, CM_INV|CM_ABR },
1776 { "wri", XXWRI, CM_INV|CM_ABR },
1777 { "writ", XXWRI, CM_INV|CM_ABR },
1778 { "write", XXWRI, 0 }, /* WRITE characters to a file */
1779 { "write-line", XXWRL, CM_INV }, /* WRITE a line to a file */
1780 { "writeln", XXWRL, CM_INV }, /* Pascalisch synonym for write-line */
1781 #else
1782 { "wr", XXNOTAV, CM_INV },
1783 { "wri", XXNOTAV, CM_INV },
1784 { "writ", XXNOTAV, CM_INV },
1785 { "write", XXNOTAV, CM_INV },
1786 { "write-line", XXNOTAV, CM_INV },
1787 { "writeln", XXNOTAV, CM_INV },
1788 #endif /* NOSPL */
1789
1790 #ifndef NOFRILLS
1791 { "xecho", XXXECH,0 }, /* XECHO */
1792 #endif /* NOFRILLS */
1793
1794 #ifndef NOSPL
1795 { "xif", XXIFX, CM_INV }, /* Extended IF command (obsolete) */
1796 #else
1797 { "xif", XXNOTAV, CM_INV },
1798 #endif /* NOSPL */
1799
1800 #ifndef NOCSETS
1801 { "xlate", XXXLA, CM_INV }, /* Synonym for TRANSLATE */
1802 #else
1803 { "xlate", XXNOTAV, CM_INV },
1804 #endif /* NOCSETS */
1805
1806 #ifndef NOXMIT
1807 { "xm", XXTRA, CM_INV|CM_ABR }, /* Avoid conflict with XMESSAGE */
1808 #else
1809 { "xm", XXNOTAV, CM_INV|CM_ABR }, /* Synonym for TRANSMIT */
1810 #endif /* NOXMIT */
1811
1812 { "xmessage", XXXMSG, 0 }, /* Print debugging message */
1813
1814 #ifndef NOXMIT
1815 { "xmit", XXTRA, CM_INV }, /* Synonym for TRANSMIT */
1816 #else
1817 { "xmit", XXNOTAV, CM_INV },
1818 #endif /* NOXMIT */
1819
1820 { "xmsg", XXXMSG, CM_INV }, /* Synonym for XMESSAGE */
1821
1822 #ifndef OS2
1823 #ifndef NOJC
1824 { "z", XXSUS, CM_INV|CM_PSH }, /* Synonym for SUSPEND */
1825 #else
1826 { "z", XXNOTAV, CM_INV|CM_PSH },
1827 #endif /* NOJC */
1828 #endif /* OS2 */
1829
1830 #ifndef NOSPL
1831 { "{", XXMACRO, CM_INV }, /* Immediate macro */
1832 #endif /* NOSPL */
1833 { "", 0, 0 }
1834 };
1835 int ncmd = (sizeof(cmdtab) / sizeof(struct keytab)) - 1;
1836
1837 /* NOTE: Tokens must also be entered above into cmdtab[]. */
1838
1839 char toktab[] = {
1840 #ifndef NOPUSH
1841 '!', /* Shell escape */
1842 #endif /* NOPUSH */
1843 '#', /* Comment */
1844 #ifndef NOSPL
1845 '(', /* S-Expression */
1846 '.', /* Assignment */
1847 #endif /* NOSPL */
1848 ';', /* Comment */
1849 #ifndef NOSPL
1850 ':', /* Label */
1851 #endif /* NOSPL */
1852 #ifndef NOPUSH
1853 #ifdef CK_REDIR
1854 '<', /* REDIRECT */
1855 #endif /* CK_REDIR */
1856 '@', /* DCL escape */
1857 #endif /* NOPUSH */
1858 #ifdef CK_RECALL
1859 '^', /* Command recall */
1860 #endif /* CK_RECALL */
1861 #ifndef NOSPL
1862 '{', /* Immediate macro */
1863 #endif /* NOSPL */
1864 '\0' /* End of this string */
1865 };
1866 int xxdot = 0; /* Used with "." token */
1867
1868 struct keytab yesno[] = { /* Yes/No keyword table */
1869 { "no", 0, 0 },
1870 { "ok", 1, 0 },
1871 { "yes", 1, 0 }
1872 };
1873 int nyesno = (sizeof(yesno) / sizeof(struct keytab));
1874
1875 /* Save keyword table */
1876
1877 struct keytab savtab[] = {
1878 #ifdef OS2
1879 { "command", XSCMD, 0 },
1880 #else
1881 #ifdef CK_RECALL
1882 { "command", XSCMD, 0 },
1883 #endif /* CK_RECALL */
1884 #endif /* OS2 */
1885 #ifndef NOSETKEY
1886 { "keymap", XSKEY, 0 },
1887 #endif /* NOSETKEY */
1888 #ifdef OS2
1889 { "terminal", XSTERM, 0 },
1890 #endif /* OS2 */
1891 { "", 0, 0 }
1892 };
1893 int nsav = (sizeof(savtab) / sizeof(struct keytab)) - 1;
1894
1895 /* Parameter keyword table */
1896
1897 struct keytab prmtab[] = {
1898 { "alarm", XYALRM, 0 },
1899 #ifdef COMMENT /* SET ANSWER not implemented yet */
1900 #ifndef NODIAL
1901 { "answer", XYANSWER,0 },
1902 #endif /* NODIAL */
1903 #endif /* COMMENT */
1904 { "ask-timer", XYTIMER, 0 },
1905 #ifndef NOXFER
1906 { "attributes", XYATTR, 0 },
1907 #endif /* NOXFER */
1908 #ifdef CK_AUTHENTICATION
1909 { "authentication", XYAUTH, 0 },
1910 #else /* CK_AUTHENTICATION */
1911 #ifdef CK_SSL
1912 { "authentication", XYAUTH, 0 },
1913 #endif /* CK_SSL */
1914 #endif /* CK_AUTHENTICATION */
1915 { "b", XYBACK, CM_INV|CM_ABR|CM_PSH },
1916 { "ba", XYBACK, CM_INV|CM_ABR|CM_PSH },
1917 #ifdef VMS
1918 { "background", XYBACK, CM_INV|CM_PSH },
1919 { "batch", XYBACK, CM_PSH },
1920 #else
1921 { "background", XYBACK, CM_PSH },
1922 { "batch", XYBACK, CM_INV|CM_PSH },
1923 #endif /* VMS */
1924 #ifndef NOLOCAL
1925 { "baud", XYSPEE, CM_INV|CM_LOC },
1926 #endif /* NOLOCAL */
1927 { "bell", XYBELL, 0 },
1928 #ifndef NOXFER
1929 { "block-check", XYCHKT, 0 },
1930 #endif /* NOXFER */
1931 #ifdef OS2
1932 #ifdef BPRINT
1933 { "bprinter", XYBDCP, CM_INV },
1934 #endif /* BPRINT */
1935 #endif /* OS2 */
1936 #ifdef BROWSER
1937 { "browser", XYBROWSE,CM_PSH|CM_LOC },
1938 #endif /* BROWSER */
1939 #ifndef NOXFER
1940 #ifdef DYNAMIC
1941 { "buffers", XYBUF, 0 },
1942 #endif /* DYNAMIC */
1943 #endif /* NOXFER */
1944 #ifndef NOLOCAL
1945 #ifndef MAC
1946 { "carrier-watch", XYCARR, CM_LOC },
1947 #endif /* MAC */
1948 #endif /* NOLOCAL */
1949 #ifndef NOSPL
1950 { "case", XYCASE, 0 },
1951 #endif /* NOSPL */
1952 { "cd", XYCD, 0 },
1953 #ifndef NOXFER
1954 { "cl", XYCLEAR, CM_INV|CM_ABR },
1955 { "cle", XYCLEAR, CM_INV|CM_ABR },
1956 { "clea", XYCLEAR, CM_INV|CM_ABR },
1957 { "clear", XYCLEAR, CM_INV|CM_ABR },
1958 { "clear-channel", XYCLEAR, 0 },
1959 { "clearchannel", XYCLEAR, CM_INV },
1960 #endif /* NOXFER */
1961 #ifndef NOLOCAL
1962 { "close-on-disconnect", XYDISC, CM_INV|CM_LOC },
1963 #endif /* NOLOCAL */
1964 { "cmd", XYCMD, CM_INV },
1965 { "command", XYCMD, 0 },
1966 #ifdef CK_SPEED
1967 { "con", XYQCTL, CM_INV|CM_ABR },
1968 #endif /* CK_SPEED */
1969 { "console", XYCMD, CM_INV },
1970 #ifdef CK_SPEED
1971 { "control-character",XYQCTL, 0 },
1972 #endif /* CK_SPEED */
1973 #ifndef NOSPL
1974 { "count", XYCOUN, 0 },
1975 #endif /* NOSPL */
1976 #ifndef NOXFER
1977 { "d", XYDELA, CM_INV|CM_ABR },
1978 { "de", XYDELA, CM_INV|CM_ABR },
1979 #endif /* NOXFER */
1980 { "debug", XYDEBU, 0 },
1981 #ifdef VMS
1982 { "default", XYDFLT, 0 },
1983 #else
1984 #ifndef MAC
1985 { "default", XYDFLT, CM_INV },
1986 #endif /* MAC */
1987 #endif /* VMS */
1988 #ifndef NOXFER
1989 { "delay", XYDELA, 0 },
1990 { "destination", XYDEST, 0 },
1991 #endif /* NOXFER */
1992 #ifndef NODIAL
1993 { "di", XYDIAL, CM_INV|CM_ABR|CM_LOC },
1994 { "dia", XYDIAL, CM_INV|CM_ABR|CM_LOC },
1995 { "dial", XYDIAL, CM_LOC },
1996 #endif /* NODIAL */
1997 #ifdef OS2
1998 { "dialer", XYDLR, CM_INV },
1999 #endif /* OS2 */
2000 #ifndef NOLOCAL
2001 { "disconnect", XYDISC, CM_LOC },
2002 { "duplex", XYDUPL, CM_LOC },
2003 #endif /* NOLOCAL */
2004 #ifndef NOPUSH
2005 #ifndef NOFRILLS
2006 { "editor", XYEDIT, CM_PSH },
2007 #endif /* NOFRILLS */
2008 #endif /* NOPUSH */
2009 #ifdef CK_CTRLZ
2010 { "eof", XYEOF, CM_INV },
2011 #endif /* CK_CTRLZ */
2012 #ifndef NOLOCAL
2013 { "escape-character", XYESC, CM_LOC },
2014 #endif /* NOLOCAL */
2015 #ifndef NOSPL
2016 { "evaluate", XYEVAL, CM_INV },
2017 #endif /* NOSPL */
2018 { "exit", XYEXIT, 0 },
2019 #ifndef NOXFER
2020 #ifdef CK_XYZ
2021 #ifndef NOPUSH
2022 #ifndef XYZ_INTERNAL
2023 { "external-protocol",XYEXTRN, 0 },
2024 #endif /* XYZ_INTERNAL */
2025 #endif /* NOPUSH */
2026 #endif /* CK_XYZ */
2027 { "f-ack-bug", XYFACKB, CM_INV },
2028 { "f-ack-path", XYFACKP, CM_INV },
2029 #endif /* NOXFER */
2030 { "file", XYFILE, 0 },
2031 { "fl", XYFLOW, CM_INV|CM_ABR },
2032 #ifndef NOSPL
2033 { "flag", XYFLAG, 0 },
2034 #endif /* NOSPL */
2035 #ifdef TCPSOCKET
2036 #ifndef SYSFTP
2037 #ifndef NOFTP
2038 { "ft", XYFTPX, CM_INV|CM_ABR },
2039 { "ftp", XYFTPX, 0 },
2040 #endif /* NOFTP */
2041 #endif /* SYSFTP */
2042 #endif /* TCPSOCKET */
2043 #ifdef BROWSER
2044 { "ftp-client", XYFTP, CM_PSH },
2045 #endif /* BROWSER */
2046 { "flow-control", XYFLOW, 0 },
2047 #ifndef NOSPL
2048 { "function", XYFUNC, 0 },
2049 #endif /* NOSPL */
2050 #ifdef NEWFTP
2051 { "get-put-remote", XYGPR, 0 },
2052 #endif /* NEWFTP */
2053 #ifdef KUI
2054 { "gui", XYGUI, 0 },
2055 #endif /* KUI */
2056 { "handshake", XYHAND, 0 },
2057 { "hints", XYHINTS, 0 },
2058 #ifdef NETCONN
2059 { "host", XYHOST, CM_LOC },
2060 #endif /* NETCONN */
2061 #ifndef NOSPL
2062 { "i", XYINPU, CM_INV|CM_ABR },
2063 #endif /* NOSPL */
2064 #ifdef IKSD
2065 { "iks", XYIKS, 0 },
2066 #else
2067 { "iks", XYIKS, CM_INV },
2068 #endif /* IKSD */
2069 #ifndef NOSPL
2070 { "in", XYINPU, CM_INV|CM_ABR },
2071 #endif /* NOSPL */
2072 #ifndef NOXFER
2073 { "incomplete", XYIFD, CM_INV },
2074 #endif /* NOXFER */
2075 #ifndef NOSPL
2076 { "input", XYINPU, 0 },
2077 #endif /* NOSPL */
2078 #ifndef NOSETKEY
2079 { "key", XYKEY, 0 },
2080 #endif /* NOSETKEY */
2081 { "l", XYLINE, CM_INV|CM_ABR },
2082 #ifndef NOCSETS
2083 { "language", XYLANG, 0 },
2084 #endif /* NOCSETS */
2085 #ifndef NOLOCAL
2086 { "line", XYLINE, CM_LOC },
2087 { "local-echo", XYLCLE, CM_INV|CM_LOC },
2088 #endif /* NOLOCAL */
2089 #ifdef HAVE_LOCALE
2090 { "locale", XYLOCALE,0 },
2091 #endif /* HAVE_LOCALE */
2092 #ifdef LOCUS
2093 { "locus", XYLOCUS, 0 },
2094 #endif /* LOCUS */
2095 #ifndef NOSPL
2096 { "login", XYLOGIN, CM_LOC },
2097 #endif /* NOSPL */
2098 #ifndef NOSPL
2099 { "macro", XYMACR, 0 },
2100 #endif /* NOSPL */
2101 { "match", XYMATCH, 0 },
2102 #ifdef COMMENT
2103 #ifdef VMS
2104 { "messages", XYMSGS, 0 },
2105 #endif /* VMS */
2106 #endif /* COMMENT */
2107 #ifndef NODIAL
2108 { "modem", XYMODM, CM_LOC },
2109 #endif /* NODIAL */
2110 #ifndef NOLOCAL
2111 #ifdef OS2MOUSE
2112 { "mouse", XYMOUSE, 0 },
2113 #endif /* OS2MOUSE */
2114 #endif /* NOLOCAL */
2115 #ifdef OS2
2116 { "mskermit", XYMSK, 0 },
2117 #endif /* OS2 */
2118 #ifdef NETCONN
2119 { "network", XYNET, CM_LOC },
2120 #endif /* NETCONN */
2121 #ifndef NOSPL
2122 { "output", XYOUTP, 0 },
2123 #endif /* NOSPL */
2124 { "options", XYOPTS, 0 },
2125 { "pause", XYSLEEP, CM_INV },
2126 #ifdef ANYX25
2127 #ifndef IBMX25
2128 { "pad", XYPAD, CM_LOC },
2129 #endif /* IBMX25 */
2130 #endif /* ANYX25 */
2131 { "parity", XYPARI, 0 },
2132 #ifndef NOLOCAL
2133 #ifdef OS2
2134 { "port", XYLINE, CM_LOC },
2135 #else
2136 { "port", XYLINE, CM_INV|CM_LOC },
2137 #endif /* OS2 */
2138 #endif /* NOLOCAL */
2139 #ifndef NOFRILLS
2140 { "pr", XYPROM, CM_INV|CM_ABR },
2141 { "printer", XYPRTR, 0 },
2142 #endif /* NOFRILLS */
2143 #ifdef OS2
2144 { "priority", XYPRTY, 0 },
2145 #endif /* OS2 */
2146 #ifdef CK_SPEED
2147 { "prefixing", XYPREFIX, 0 },
2148 #endif /* CK_SPEED */
2149 #ifndef NOFRILLS
2150 { "prompt", XYPROM, 0 },
2151 #endif /* NOFRILLS */
2152 #ifndef NOXFER
2153 { "protocol", XYPROTO, 0 },
2154 #endif /* NOXFER */
2155 { "q", XYQUIE, CM_INV|CM_ABR },
2156 #ifndef NOXFER
2157 { "q8flag", XYQ8FLG, CM_INV },
2158 #endif /* NOXFER */
2159 #ifdef QNX
2160 { "qnx-port-lock", XYQNXPL, 0 },
2161 #else
2162 { "qnx-port-lock", XYQNXPL, CM_INV },
2163 #endif /* QNX */
2164 { "quiet", XYQUIE, 0 },
2165 #ifndef NOXFER
2166 { "rec", XYRECV, CM_INV|CM_ABR },
2167 { "receive", XYRECV, 0 },
2168 { "recv", XYRECV, CM_INV },
2169 #endif /* NOXFER */
2170 { "reliable", XYRELY, 0 },
2171 { "rename", XY_REN, 0 },
2172 #ifndef NOXFER
2173 { "repeat", XYREPT, 0 },
2174 { "retry-limit", XYRETR, 0 },
2175 #endif /* NOXFER */
2176 #ifdef CKROOT
2177 { "root", XYROOT, 0 },
2178 #endif /* CKROOT */
2179 #ifndef NOSCRIPT
2180 { "script", XYSCRI, CM_LOC },
2181 #endif /* NOSCRIPT */
2182 #ifndef NOXFER
2183 { "send", XYSEND, 0 },
2184 #ifndef NOLOCAL
2185 #ifndef NOSERVER
2186 { "ser", XYSERV, CM_INV|CM_ABR },
2187 #endif /* NOSERVER */
2188 #endif /* NOXFER */
2189 { "serial", XYSERIAL,CM_LOC },
2190 #endif /* NOLOCAL */
2191 #ifndef NOSERVER
2192 { "server", XYSERV, 0 },
2193 #endif /* NOSERVER */
2194 #ifdef SESLIMIT
2195 #ifndef NOLOCAL
2196 { "session-l", XYSESS, CM_INV|CM_ABR },
2197 #endif /* NOLOCAL */
2198 { "session-limit", XYLIMIT, CM_INV|CM_LOC }, /* Session Limit */
2199 #endif /* SESLIMIT */
2200
2201 #ifndef NOLOCAL
2202 { "session-log", XYSESS, CM_LOC },
2203 #endif /* NOLOCAL */
2204
2205 #ifndef NOSPL
2206 #ifndef NOSEXP
2207 { "sexpression", XYSEXP, CM_INV },
2208 #endif /* NOSEXP */
2209 #endif /* NOSPL */
2210
2211 { "sleep", XYSLEEP, 0 },
2212
2213 #ifndef NOLOCAL
2214 { "speed", XYSPEE, CM_LOC },
2215 #endif /* NOLOCAL */
2216
2217 #ifdef ANYSSH
2218 { "ssh", XYSSH, 0 },
2219 #endif /* ANYSSH */
2220
2221 #ifndef NOSPL
2222 { "startup-file", XYSTARTUP, CM_INV },
2223 #endif /* NOSPL */
2224
2225 #ifndef NOLOCAL
2226 #ifdef HWPARITY
2227 { "stop-bits", XYSTOP, CM_LOC },
2228 #else
2229 #ifdef TN_COMPORT
2230 { "stop-bits", XYSTOP, CM_LOC },
2231 #endif /* TN_COMPORT */
2232 #endif /* HWPARITY */
2233 #endif /* NOLOCAL */
2234
2235 #ifndef NOXFER
2236 #ifdef STREAMING
2237 { "streaming", XYSTREAM, 0 },
2238 #endif /* STREAMING */
2239 #endif /* NOXFER */
2240
2241 #ifndef NOJC
2242 { "suspend", XYSUSP, CM_PSH },
2243 #endif /* NOJC */
2244 #ifdef CKSYSLOG
2245 { "syslog", XYSYSL, CM_INV },
2246 #endif /* CKSYSLOG */
2247 { "take", XYTAKE, 0 },
2248
2249 #ifdef CK_TAPI
2250 { "tapi", XYTAPI, CM_LOC },
2251 #endif /* CK_TAPI */
2252
2253 #ifndef NOTCPOPTS
2254 #ifdef TCPSOCKET
2255 { "tcp", XYTCP, CM_LOC },
2256 #endif /* TCPSOCKET */
2257 #endif /* NOTCPOPTS */
2258
2259 #ifdef TNCODE
2260 { "tel", XYTEL, CM_INV|CM_ABR },
2261 { "telnet", XYTEL, 0 },
2262 { "telopt", XYTELOP, 0 },
2263 #endif /* TNCODE */
2264
2265 #ifndef NOSPL
2266 { "temp-directory", XYTMPDIR,0 },
2267 #endif /* NOSPL */
2268
2269 #ifndef NOLOCAL
2270 { "terminal", XYTERM, CM_LOC },
2271 #endif /* NOLOCAL */
2272
2273 #ifdef OS2
2274 { "title", XYTITLE, CM_LOC },
2275 #endif /* OS2 */
2276 #ifndef NOSPL
2277 { "tmp-directory", XYTMPDIR,CM_INV },
2278 #endif /* NOSPL */
2279 #ifdef TLOG
2280 { "transaction-log", XYTLOG, 0 },
2281 #endif /* TLOG */
2282 #ifndef NOXFER
2283 { "transfer", XYXFER, 0 },
2284 #endif /* NOXFER */
2285 #ifndef NOXMIT
2286 { "transmit", XYXMIT, 0 },
2287 #endif /* NOXMIT */
2288 #ifndef NOXFER
2289 #ifndef NOCSETS
2290 { "unknown-char-set", XYUNCS, 0 },
2291 #endif /* NOCSETS */
2292 #ifndef NOSPL
2293 { "variable-evaluation", XYVAREV, CM_INV },
2294 #endif /* NOSPL */
2295 #endif /* NOXFER */
2296 { "wait", XYSLEEP, CM_INV },
2297 #ifndef NOPUSH
2298 #ifdef UNIX
2299 { "wildcard-expansion", XYWILD, 0 },
2300 #endif /* UNIX */
2301 #endif /* NOPUSH */
2302 #ifdef NT
2303 { "w", XYWIND, CM_INV|CM_ABR },
2304 { "wi", XYWIND, CM_INV|CM_ABR },
2305 { "win", XYWIND, CM_INV|CM_ABR },
2306 #endif /* NT */
2307 { "window-size", XYWIND, 0 },
2308 #ifdef NT
2309 { "win95", XYWIN95, 0 },
2310 #endif /* NT */
2311 #ifdef ANYX25
2312 { "x.25", XYX25, CM_LOC },
2313 { "x25", XYX25, CM_INV|CM_LOC },
2314 #endif /* ANYX25 */
2315 { "xfer", XYXFER, CM_INV },
2316 #ifndef NOXMIT
2317 { "xmit", XYXMIT, CM_INV },
2318 #endif /* NOXMIT */
2319 { "", 0, 0 }
2320 };
2321 int nprm = (sizeof(prmtab) / sizeof(struct keytab)) - 1; /* How many */
2322
2323 struct keytab scntab[] = { /* Screen commands */
2324 { "clear", SCN_CLR, 0 },
2325 { "cleol", SCN_CLE, 0 },
2326 { "move-to", SCN_MOV, 0 }
2327 };
2328 int nscntab = (sizeof(scntab) / sizeof(struct keytab)); /* How many */
2329
2330 #ifdef ANYSSH /* SSH command table */
2331 #ifdef SSHBUILTIN
2332 int ssh_pf_lcl_n = 0,
2333 ssh_pf_rmt_n = 0;
2334 struct ssh_pf ssh_pf_lcl[32] = { 0, NULL, 0 }; /* SSH Port Forwarding */
2335 struct ssh_pf ssh_pf_rmt[32] = { 0, NULL, 0 }; /* structs... */
2336 extern char * ssh_hst, * ssh_cmd, * ssh_prt;
2337 extern int ssh_ver, ssh_xfw;
2338 char * ssh_tmpuid = NULL, *ssh_tmpcmd = NULL, *ssh_tmpport = NULL,
2339 * ssh_tmpstr = NULL;
2340
2341 int
2342 sshk_type = SSHKT_2D, /* SSH KEY CREATE /TYPE:x */
2343 sshk_bits = 1024, /* SSH KEY CREATE /BITS:n */
2344 sshk_din = SKDF_OSSH, /* SSH KEY DISPLAY /IN-FORMAT: */
2345 sshk_dout = SKDF_OSSH; /* SSH KEY DISPLAY /OUT-FORMAT: */
2346
2347 char
2348 * sshk1_comment = NULL, /* SSH V1 COMMENT */
2349 * sshkp_old = NULL, /* Old key passphrase */
2350 * sshkp_new = NULL, /* New key passphrase */
2351 * sshkc_pass = NULL, /* KEY CREATE /PASS:xxx */
2352 * sshkc_comm = NULL, /* KEY CREATE /V1-RSA-COMMENT:xxx */
2353 * sshd_file = NULL, /* DISPLAY file */
2354 * sshk_file = NULL; /* SSH CREATE KEY file */
2355
2356 static struct keytab sshclr[] = {
2357 { "local-port-forward", SSHC_LPF, 0 },
2358 { "remote-port-forward", SSHC_RPF, 0 },
2359 { "", 0, 0 }
2360 };
2361 static int nsshclr = (sizeof(sshclr) / sizeof(struct keytab)) - 1;
2362
2363 struct keytab sshopnsw[] = {
2364 { "/command", SSHSW_CMD, CM_ARG },
2365 { "/password", SSHSW_PWD, CM_ARG },
2366 { "/subsystem", SSHSW_SUB, CM_ARG },
2367 { "/user", SSHSW_USR, CM_ARG },
2368 { "/version", SSHSW_VER, CM_ARG },
2369 { "/x11-forwarding", SSHSW_X11, CM_ARG },
2370 { "", 0, 0 }
2371 };
2372 int nsshopnsw = (sizeof(sshopnsw) / sizeof(struct keytab)) - 1;
2373
2374 static struct keytab sshkwtab[] = {
2375 { "add", XSSH_ADD, 0 },
2376 { "agent", XSSH_AGT, 0 },
2377 { "clear", XSSH_CLR, 0 },
2378 { "forward-local-port", XSSH_FLP, CM_INV },
2379 { "forward-remote-port", XSSH_FRP, CM_INV },
2380 { "key", XSSH_KEY, 0 },
2381 { "open", XSSH_OPN, 0 },
2382 { "v2", XSSH_V2, 0 },
2383 { "", 0, 0 }
2384 };
2385 static int nsshcmd = (sizeof(sshkwtab) / sizeof(struct keytab)) - 1;
2386
2387 static struct keytab ssh2tab[] = {
2388 { "rekey", XSSH2_RKE, 0 },
2389 { "", 0, 0 }
2390 };
2391 static int nssh2tab = (sizeof(ssh2tab) / sizeof(struct keytab));
2392
2393 static struct keytab addfwd[] = { /* SET SSH ADD command table */
2394 { "local-port-forward", SSHF_LCL, 0 },
2395 { "remote-port-forward", SSHF_RMT, 0 },
2396 { "", 0, 0 }
2397 };
2398 static int naddfwd = (sizeof(addfwd) / sizeof(struct keytab)) - 1;
2399
2400 static struct keytab sshagent[] = { /* SET SSH AGENT command table */
2401 { "add", SSHA_ADD, 0 },
2402 { "delete", SSHA_DEL, 0 },
2403 { "list", SSHA_LST, 0 },
2404 { "", 0, 0 }
2405 };
2406 static int nsshagent = (sizeof(sshagent) / sizeof(struct keytab)) - 1;
2407
2408 static struct keytab sshagtsw[] = { /* SET SSH AGENT LIST switch table */
2409 { "/fingerprint", SSHASW_FP, 0 },
2410 { "", 0, 0 }
2411 };
2412 static int nsshagtsw = (sizeof(sshagtsw) / sizeof(struct keytab)) - 1;
2413
2414 static struct keytab sshkey[] = { /* SET SSH KEY command table */
2415 { "change-passphrase", SSHK_PASS, 0 },
2416 { "create", SSHK_CREA, 0 },
2417 { "display", SSHK_DISP, 0 },
2418 { "v1", SSHK_V1, 0 },
2419 { "", 0, 0 }
2420 };
2421 static int nsshkey = (sizeof(sshkey) / sizeof(struct keytab)) - 1;
2422
2423 static struct keytab sshkv1[] = { /* SET SSH KEY V1 command table */
2424 { "set-comment", 1, 0 }
2425 };
2426
2427 static struct keytab sshkpsw[] = { /* SET SSH KEY PASSPHRASE table */
2428 { "/new-passphrase", 2, CM_ARG },
2429 { "/old-passphrase", 1, CM_ARG }
2430 };
2431
2432 static struct keytab sshkcrea[] = { /* SSH KEY CREATE table */
2433 { "/bits", SSHKC_BI, CM_ARG },
2434 { "/passphrase", SSHKC_PP, CM_ARG },
2435 { "/type", SSHKC_TY, CM_ARG },
2436 { "/v1-rsa-comment", SSHKC_1R, CM_ARG }
2437 };
2438 static int nsshkcrea = (sizeof(sshkcrea) / sizeof(struct keytab));
2439
2440 static struct keytab sshkcty[] = { /* SSH KEY CREATE /TYPE:xxx */
2441 { "srp", SSHKT_SRP, 0 },
2442 { "v1-rsa", SSHKT_1R, 0 },
2443 { "v2-dsa", SSHKT_2D, 0 },
2444 { "v2-rsa", SSHKT_2R, 0 }
2445 };
2446 static int nsshkcty = (sizeof(sshkcty) / sizeof(struct keytab));
2447
2448 static struct keytab sshdswi[] = { /* SET SSH KEY DISPLAY /switches */
2449 { "/format", SSHKD_OUT, CM_ARG }
2450 };
2451 static int nsshdswi = (sizeof(sshdswi) / sizeof(struct keytab));
2452
2453 #ifdef COMMENT
2454 static struct keytab sshdifmt[] = { /* SSH KEY DISPLAY /IN-FORMAT: */
2455 { "openssh", SKDF_OSSH, 0 },
2456 { "ssh.com", SKDF_SSHC, 0 }
2457 };
2458 static int nsshdifmt = (sizeof(sshdifmt) / sizeof(struct keytab));
2459 #endif /* COMMENT */
2460
2461 static struct keytab sshdofmt[] = { /* SSH KEY DISPLAY /IN-FORMAT: */
2462 { "fingerprint", SKDF_FING, 0 },
2463 { "ietf", SKDF_IETF, 0 },
2464 { "openssh", SKDF_OSSH, 0 },
2465 { "ssh.com", SKDF_SSHC, 0 }
2466 };
2467 static int nsshdofmt = (sizeof(sshdofmt) / sizeof(struct keytab));
2468
2469 static struct keytab sshkermit[] = { /* SKERMIT */
2470 { "open", SKRM_OPN, 0 }
2471 };
2472 static int nsshkermit = (sizeof(sshkermit) / sizeof(struct keytab));
2473
2474 struct keytab sshkrmopnsw[] = {
2475 { "/password", SSHSW_PWD, CM_ARG },
2476 { "/user", SSHSW_USR, CM_ARG },
2477 { "/version", SSHSW_VER, CM_ARG },
2478 { "", 0, 0 }
2479 };
2480 int nsshkrmopnsw = (sizeof(sshkrmopnsw) / sizeof(struct keytab)) - 1;
2481 #endif /* SSHBUILTIN */
2482
2483 #ifdef SFTP_BUILTIN
2484 static struct keytab sftpkwtab[] = { /* SFTP */
2485 { "cd", SFTP_CD, 0 },
2486 { "chgrp", SFTP_CHGRP, 0 },
2487 { "chmod", SFTP_CHMOD, 0 },
2488 { "chown", SFTP_CHOWN, 0 },
2489 { "delete", SFTP_RM, 0 },
2490 { "dir", SFTP_DIR, 0 },
2491 { "get", SFTP_GET, 0 },
2492 { "mkdir", SFTP_MKDIR, 0 },
2493 { "open", SFTP_OPN, 0 },
2494 { "put", SFTP_PUT, 0 },
2495 { "pwd", SFTP_PWD, 0 },
2496 { "rename", SFTP_REN, 0 },
2497 { "rm", SFTP_RM, CM_INV },
2498 { "rmdir", SFTP_RMDIR, 0 },
2499 { "symlink", SFTP_LINK, 0 },
2500 { "version", SFTP_VER, 0 }
2501 };
2502 static int nsftpkwtab = (sizeof(sftpkwtab) / sizeof(struct keytab));
2503 #endif /* SFTP_BUILTIN */
2504 #endif /* ANYSSH */
2505
2506 #ifdef NETCONN
2507 struct keytab netkey[] = { /* SET NETWORK table */
2508 { "directory", XYNET_D, 0 },
2509 { "type", XYNET_T, 0 }
2510 };
2511 int nnetkey = (sizeof(netkey) / sizeof(struct keytab));
2512
2513 struct keytab netcmd[] = {
2514 /*
2515 These are the network types.
2516 */
2517 #ifdef NETCMD
2518 { "command", NET_CMD, CM_INV }, /* Command */
2519 #endif /* NETCMD */
2520
2521 #ifdef DECNET /* DECnet / PATHWORKS */
2522 { "decnet", NET_DEC, 0 },
2523 #endif /* DECNET */
2524
2525 #ifdef NETDLL
2526 { "dll", NET_DLL, CM_INV }, /* DLL to be loaded */
2527 #endif /* NETDLL */
2528
2529 #ifdef NETFILE
2530 { "file", NET_FILE, CM_INV }, /* FILE (real crude) */
2531 #endif /* NETFILE */
2532
2533 #ifdef NPIPE /* Named Pipes */
2534 { "named-pipe", NET_PIPE, 0 },
2535 #endif /* NPIPE */
2536
2537 #ifdef CK_NETBIOS
2538 { "netbios", NET_BIOS, 0 }, /* NETBIOS */
2539 #endif /* CK_NETBIOS */
2540
2541 #ifdef DECNET /* DECnet / PATHWORKS (alias) */
2542 { "pathworks", NET_DEC, CM_INV },
2543 #endif /* DECNET */
2544
2545 #ifdef NETCMD
2546 { "pipe", NET_CMD, 0 }, /* Pipe */
2547 #endif /* NETCMD */
2548
2549 #ifdef NETPTY
2550 { "pseudoterminal",NET_PTY, 0 }, /* Pseudoterminal */
2551 #endif /* NETPTY */
2552
2553 #ifdef NETPTY
2554 { "pty", NET_PTY, CM_INV }, /* Inv syn for pseudoterm */
2555 #endif /* NETPTY */
2556
2557 #ifdef SSHBUILTIN
2558 { "ssh", NET_SSH, 0 },
2559 #endif /* SSHBUILTIN */
2560
2561 #ifdef SUPERLAT
2562 { "superlat", NET_SLAT, 0 }, /* Meridian Technologies' SuperLAT */
2563 #endif /* SUPERLAT */
2564
2565 #ifdef TCPSOCKET /* TCP/IP sockets library */
2566 { "tcp/ip", NET_TCPB, 0 },
2567 #endif /* TCPSOCKET */
2568 #ifdef SUPERLAT
2569 { "tes32", NET_SLAT, 0 }, /* Emulux TES32 */
2570 #endif /* SUPERLAT */
2571 #ifdef ANYX25 /* X.25 */
2572 #ifdef SUNX25
2573 { "x", NET_SX25, CM_INV|CM_ABR },
2574 { "x.25", NET_SX25, 0 },
2575 { "x25", NET_SX25, CM_INV },
2576 #else
2577 #ifdef STRATUSX25
2578 { "x", NET_VX25, CM_INV|CM_ABR },
2579 { "x.25", NET_VX25, 0 },
2580 { "x25", NET_VX25, CM_INV },
2581 #endif /* STRATUSX25 */
2582 #endif /* SUNX25 */
2583 #ifdef IBMX25
2584 { "x", NET_IX25, CM_INV|CM_ABR },
2585 { "x.25", NET_IX25, CM_INV },
2586 { "x25", NET_IX25, CM_INV },
2587 #endif /* IBMX25 */
2588 #ifdef HPX25
2589 { "x", NET_IX25, CM_INV|CM_ABR },
2590 { "x.25", NET_IX25, 0 },
2591 { "x25", NET_IX25, CM_INV },
2592 #endif /* HPX25 */
2593 #endif /* ANYX25 */
2594 { "", 0, 0 }
2595 };
2596 int nnets = (sizeof(netcmd) / sizeof(struct keytab));
2597
2598 #ifndef NOTCPOPTS
2599 #ifdef TCPSOCKET
2600
2601 /* TCP options */
2602
2603 struct keytab tcpopt[] = {
2604 { "address", XYTCP_ADDRESS, 0 },
2605 #ifdef CK_DNS_SRV
2606 { "dns-service-records", XYTCP_DNS_SRV, 0 },
2607 #endif /* CK_DNS_SRV */
2608 #ifdef SO_DONTROUTE
2609 { "dontroute", XYTCP_DONTROUTE, 0 },
2610 #endif /* SO_DONTROUTE */
2611 #ifndef NOHTTP
2612 { "http-proxy", XYTCP_HTTP_PROXY, 0 },
2613 #endif /* NOHTTP */
2614 #ifdef SO_KEEPALIVE
2615 { "keepalive", XYTCP_KEEPALIVE, 0 },
2616 #endif /* SO_KEEPALIVE */
2617 #ifdef SO_LINGER
2618 { "linger", XYTCP_LINGER, 0 },
2619 #endif /* SO_LINGER */
2620 #ifdef TCP_NODELAY
2621 { "nagle", XYTCP_NAGLE, CM_INV },
2622 { "nodelay", XYTCP_NODELAY, 0 },
2623 #endif /* TCP_NODELAY */
2624 { "reverse-dns-lookup", XYTCP_RDNS, 0 },
2625 #ifdef SO_RCVBUF
2626 { "recvbuf", XYTCP_RECVBUF, 0 },
2627 #endif /* SO_RCVBUF */
2628 #ifdef SO_SNDBUF
2629 { "sendbuf", XYTCP_SENDBUF, 0 },
2630 #endif /* SO_SNDBUF */
2631 #ifdef NT
2632 #ifdef CK_SOCKS
2633 { "socks-server", XYTCP_SOCKS_SVR, 0 },
2634 #endif /* CK_SOCKS */
2635 #endif /* NT */
2636 #ifdef VMS
2637 #ifdef DEC_TCPIP
2638 { "ucx-port-bug", XYTCP_UCX, 0 },
2639 #endif /* DEC_TCPIP */
2640 #endif /* VMS */
2641 { "",0,0 }
2642 };
2643 int ntcpopt = (sizeof(tcpopt) / sizeof(struct keytab));
2644 #endif /* TCPSOCKET */
2645 #endif /* NOTCPOPTS */
2646 #endif /* NETCONN */
2647
2648 #ifdef OS2
2649 /* K95 Manual Chapter Table -- Keep these two tables in sync! */
2650
2651 static char * linktbl[] = { /* Internal links in k95.htm */
2652 "#top", /* 00 */
2653 "#what", /* 01 */
2654 "#install", /* 02 */
2655 "#start", /* 03 */
2656 "#dialer", /* 04 */
2657 "#entries", /* 05 */
2658 "#command", /* 06 */
2659 "#terminal", /* 07 */
2660 "#transfer", /* 08 */
2661 "#hostmode" /* 09 */
2662 };
2663
2664 static struct keytab chaptbl[] = {
2665 { "Command-Screen", 6, 0 },
2666 { "Contents", 0, 0 },
2667 { "Dialer-Entries", 5, 0 },
2668 { "File-Transfer", 8, 0 },
2669 { "Getting-Started", 3, 0 },
2670 { "Host-Mode", 9, 0 },
2671 { "Installation", 2, 0 },
2672 { "Terminal-Emulation", 7, 0 },
2673 { "Using-The-Dialer", 4, 0 },
2674 { "What-Is-K95", 1, 0 },
2675 { "", 0, 0 }
2676 };
2677 static int nchaptbl = (sizeof(chaptbl) / sizeof(struct keytab) - 1);
2678 #endif /* OS2 */
2679
2680 #ifndef NOXFER
2681 /* Remote Command Table */
2682
2683 struct keytab remcmd[] = {
2684 #ifndef NOSPL
2685 { "as", XZASG, CM_INV|CM_ABR },
2686 { "asg", XZASG, CM_INV },
2687 { "assign", XZASG, 0 },
2688 #endif /* NOSPL */
2689 { "cd", XZCWD, 0 },
2690 { "cdup", XZCDU, CM_INV },
2691 { "copy", XZCPY, 0 },
2692 { "cwd", XZCWD, CM_INV },
2693 { "delete", XZDEL, 0 },
2694 { "directory", XZDIR, 0 },
2695 { "e", XZXIT, CM_ABR|CM_INV },
2696 { "erase", XZDEL, CM_INV },
2697 { "exit", XZXIT, 0 },
2698 { "help", XZHLP, 0 },
2699 #ifndef NOPUSH
2700 { "host", XZHOS, 0 },
2701 #endif /* NOPUSH */
2702 #ifndef NOFRILLS
2703 { "kermit", XZKER, 0 },
2704 { "l", XZLGI, CM_ABR|CM_INV },
2705 { "lo", XZLGI, CM_ABR|CM_INV },
2706 { "log", XZLGI, CM_ABR|CM_INV },
2707 { "login", XZLGI, 0 },
2708 { "logout", XZLGO, 0 },
2709 { "message", XZMSG, 0 },
2710 { "mkdir", XZMKD, 0 },
2711 { "print", XZPRI, 0 },
2712 #endif /* NOFRILLS */
2713 { "pwd", XZPWD, 0 },
2714 #ifndef NOSPL
2715 { "query", XZQUE, 0 },
2716 #endif /* NOSPL */
2717 { "rename", XZREN, 0 },
2718 { "rmdir", XZRMD, 0 },
2719 { "set", XZSET, 0 },
2720 { "space", XZSPA, 0 },
2721 #ifndef NOFRILLS
2722 { "type", XZTYP, 0 },
2723 { "who", XZWHO, 0 },
2724 #endif /* NOFRILLS */
2725 { "", 0, 0}
2726 };
2727 int nrmt = (sizeof(remcmd) / sizeof(struct keytab)) - 1;
2728 #endif /* NOXFER */
2729
2730 struct keytab logtab[] = {
2731 #ifdef CKLOGDIAL
2732 { "connections", LOGM, CM_INV },
2733 { "cx", LOGM, 0 },
2734 #endif /* CKLOGDIAL */
2735 #ifdef DEBUG
2736 { "debugging", LOGD, 0 },
2737 #endif /* DEBUG */
2738 { "packets", LOGP, 0 },
2739 #ifndef NOLOCAL
2740 { "session", LOGS, 0 },
2741 #endif /* NOLOCAL */
2742 #ifdef TLOG
2743 { "transactions", LOGT, 0 },
2744 #endif /* TLOG */
2745 { "", 0, 0 }
2746 };
2747 int nlog = (sizeof(logtab) / sizeof(struct keytab)) - 1;
2748
2749 struct keytab writab[] = {
2750 #ifndef NOSPL
2751 { "append-file", LOGW, CM_INV },
2752 #endif /* NOSPL */
2753 { "debug-log", LOGD, 0 },
2754 { "error", LOGE, 0 },
2755 #ifndef NOSPL
2756 { "file", LOGW, 0 },
2757 #endif /* NOSPL */
2758 { "packet-log", LOGP, 0 },
2759 { "screen", LOGX, 0 },
2760 #ifndef NOLOCAL
2761 { "session-log", LOGS, 0 },
2762 #endif /* NOLOCAL */
2763 { "sys$output", LOGX, CM_INV },
2764 { "t", LOGT, CM_ABR|CM_INV }, /* Because of a typo in */
2765 { "tr", LOGT, CM_ABR|CM_INV }, /* the book... */
2766 { "tra", LOGT, CM_ABR|CM_INV },
2767 { "tran", LOGT, CM_ABR|CM_INV },
2768 { "trans", LOGT, CM_ABR|CM_INV },
2769 { "transa", LOGT, CM_ABR|CM_INV },
2770 { "transac", LOGT, CM_ABR|CM_INV },
2771 { "transact", LOGT, CM_ABR|CM_INV },
2772 { "transacti", LOGT, CM_ABR|CM_INV },
2773 { "transactio", LOGT, CM_ABR|CM_INV },
2774 { "transaction", LOGT, CM_ABR|CM_INV },
2775 { "transaction-log", LOGT, 0 },
2776 { "transactions", LOGT, CM_INV }
2777 };
2778 int nwri = (sizeof(writab) / sizeof(struct keytab));
2779
2780 static struct keytab clrtab[] = { /* Keywords for CLEAR command */
2781 #ifndef NOSPL
2782 { "alarm", CLR_ALR, 0 },
2783 #ifdef CK_APC
2784 { "apc", CLR_APC, 0 },
2785 #endif /* CK_APC */
2786 #ifdef PATTERNS
2787 { "binary-patterns", CLR_BIN, 0 },
2788 #endif /* PATTERNS */
2789 { "both", CLR_DEV|CLR_INP, CM_INV },
2790 #endif /* NOSPL */
2791 #ifdef OS2
2792 { "command-screen", CLR_CMD, 0 },
2793 #endif /* OS2 */
2794 #ifndef NOSPL
2795 { "device", CLR_DEV, CM_INV|CM_ABR },
2796 { "device-and-input", CLR_DEV|CLR_INP, 0 },
2797 #endif /* NOSPL */
2798 { "device-buffer", CLR_DEV, 0 },
2799 #ifndef NODIAL
2800 { "dial-status", CLR_DIA, 0 },
2801 #endif /* NODIAL */
2802 #ifndef NOSPL
2803 { "input-buffer", CLR_INP, 0 },
2804 #endif /* NOSPL */
2805 { "keyboard-buffer", CLR_KBD, 0 },
2806 { "send-list", CLR_SFL, 0 },
2807 #ifdef OS2
2808 { "scr", CLR_SCL, CM_INV|CM_ABR },
2809 #endif /* OS2 */
2810 { "screen", CLR_SCR, 0 },
2811 #ifdef OS2
2812 { "scrollback", CLR_SCL, CM_INV },
2813 { "terminal-screen", CLR_TRM, 0 },
2814 #endif /* OS2 */
2815 #ifdef PATTERNS
2816 { "text-patterns", CLR_TXT, 0 },
2817 #endif /* PATTERNS */
2818 { "", 0, 0 }
2819 };
2820 int nclear = (sizeof(clrtab) / sizeof(struct keytab)) - 1;
2821
2822 struct keytab clstab[] = { /* Keywords for CLOSE command */
2823 #ifndef NOSPL
2824 { "!read", LOGR, CM_INV },
2825 { "!write", LOGW, CM_INV },
2826 #ifndef NOPUSH
2827 #endif /* NOPUSH */
2828 #endif /* NOSPL */
2829 #ifndef NOSPL
2830 { "append-file", LOGW, CM_INV },
2831 #endif /* NOSPL */
2832 #ifndef NOLOCAL
2833 { "connection", 9999, 0 },
2834 #endif /* NOLOCAL */
2835 #ifdef CKLOGDIAL
2836 { "cx-log", LOGM, 0 },
2837 #endif /* CKLOGDIAL */
2838 #ifdef DEBUG
2839 { "debug-log", LOGD, 0 },
2840 #endif /* DEBUG */
2841 { "host", 9999, CM_INV }, /* Synonym for CLOSE CONNECTION */
2842 { "line", 9999, CM_INV }, /* Synonym for CLOSE CONNECTION */
2843 { "p", LOGP, CM_INV|CM_ABR },
2844 { "packet-log", LOGP, 0 },
2845 { "port", 9999, CM_INV }, /* Synonym for CLOSE CONNECTION */
2846 #ifndef NOSPL
2847 { "read-file", LOGR, 0 },
2848 #endif /* NOSPL */
2849 #ifndef NOLOCAL
2850 { "session-log", LOGS, 0 },
2851 #endif /* NOLOCAL */
2852 #ifdef TLOG
2853 { "t", LOGT, CM_ABR|CM_INV }, /* Because of a typo in */
2854 { "tr", LOGT, CM_ABR|CM_INV }, /* the book... */
2855 { "tra", LOGT, CM_ABR|CM_INV },
2856 { "tran", LOGT, CM_ABR|CM_INV },
2857 { "trans", LOGT, CM_ABR|CM_INV },
2858 { "transa", LOGT, CM_ABR|CM_INV },
2859 { "transac", LOGT, CM_ABR|CM_INV },
2860 { "transact", LOGT, CM_ABR|CM_INV },
2861 { "transacti", LOGT, CM_ABR|CM_INV },
2862 { "transactio", LOGT, CM_ABR|CM_INV },
2863 { "transaction", LOGT, CM_ABR|CM_INV },
2864 { "transaction-log", LOGT, 0 },
2865 { "transactions", LOGT, CM_INV },
2866 #endif /* TLOG */
2867 #ifndef NOSPL
2868 { "write-file", LOGW, 0 },
2869 #endif /* NOSPL */
2870 { "", 0, 0 }
2871 };
2872 int ncls = (sizeof(clstab) / sizeof(struct keytab)) - 1;
2873
2874 /* SHOW command arguments */
2875
2876 #ifndef NOSHOW
2877 struct keytab shotab[] = {
2878 #ifndef NOSPL
2879 { "alarm", SHALRM, 0 },
2880 { "arg", SHARG, CM_INV|CM_ABR },
2881 { "arguments", SHARG, 0 },
2882 { "args", SHARG, CM_INV },
2883 { "arrays", SHARR, 0 },
2884 #endif /* NOSPL */
2885
2886 #ifndef NOCSETS
2887 { "associations", SHASSOC, 0 },
2888 #endif /* NOCSETS */
2889
2890 #ifndef NOXFER
2891 { "attributes", SHATT, 0 },
2892 #endif /* NOXFER */
2893
2894 #ifdef CK_AUTHENTICATION
2895 { "authentication", SHOAUTH, CM_INV },
2896 #endif /* CK_AUTHENTICATION */
2897
2898 #ifndef NOPUSH
2899 #ifdef BROWSER
2900 { "browser", SHBROWSE, CM_PSH|CM_LOC },
2901 #endif /* BROWSER */
2902 #endif /* NOPUSH */
2903 { "cd", SHCD, 0 },
2904 { "character-sets", SHCSE, 0 },
2905 { "cmd", SHCMD, CM_INV },
2906 #ifndef NOLOCAL
2907 { "com", SHCOM, CM_INV|CM_ABR },
2908 { "comm", SHCOM, CM_INV|CM_ABR },
2909 { "communications", SHCOM, 0 },
2910 #endif /* NOLOCAL */
2911 { "command", SHCMD, 0 },
2912 { "connection", SHCONNX, 0 },
2913 #ifdef CK_SPEED
2914 { "control-prefixing", SHCTL, 0 },
2915 #endif /* CK_SPEED */
2916 #ifdef CKLOGDIAL
2917 { "cx", SHCONNX, CM_INV },
2918 #endif /* CKLOGDIAL */
2919 #ifndef NOSPL
2920 { "count", SHCOU, 0 },
2921 #endif /* NOSPL */
2922 { "d", SHDIA, CM_INV|CM_ABR },
2923 #ifdef VMS
2924 { "default", SHDFLT, 0 },
2925 #else
2926 { "default", SHDFLT, CM_INV },
2927 #endif /* VMS */
2928 #ifndef NODIAL
2929 { "dial", SHDIA, CM_LOC },
2930 #endif /* NODIAL */
2931 { "double/ignore",SHDBL, 0 },
2932 #ifndef NOPUSH
2933 #ifndef NOFRILLS
2934 { "editor", SHEDIT, CM_PSH },
2935 #endif /* NOFRILLS */
2936 #endif /* NOPUSH */
2937 #ifndef NOLOCAL
2938 { "escape", SHESC, CM_LOC },
2939 #endif /* NOLOCAL */
2940 { "exit", SHEXI, 0 },
2941 { "extended-options", SHXOPT, CM_INV },
2942 { "features", SHFEA, 0 },
2943 { "file", SHFIL, 0 },
2944 #ifndef NOLOCAL
2945 { "flow-control", SHOFLO, 0 },
2946 #endif /* NOLOCAL */
2947 #ifdef BROWSER
2948 { "ftp", SHOFTP, CM_PSH|CM_LOC },
2949 #else
2950 #ifndef NOFTP
2951 #ifndef SYSFTP
2952 #ifdef TCPSOCKET
2953 { "ftp", SHOFTP, 0 }, /* (built-in ftp) */
2954 #endif /* TCPSOCKET */
2955 #endif /* SYSFTP */
2956 #endif /* NOFTP */
2957 #endif /* BROWSER */
2958 #ifndef NOSPL
2959 { "functions", SHFUN, 0 },
2960 { "globals", SHVAR, 0 },
2961 #endif /* NOSPL */
2962 #ifdef KUI
2963 { "gui", SHOGUI, 0 },
2964 #endif /* KUI */
2965 #ifdef CK_RECALL
2966 { "history", SHHISTORY, 0 },
2967 #endif /* CK_RECALL */
2968 { "ignore/double",SHDBL, CM_INV },
2969 { "iksd", SHOIKS, CM_INV },
2970 #ifndef NOSPL
2971 { "input", SHINP, 0 },
2972 #endif /* NOSPL */
2973 #ifndef NOSETKEY
2974 { "k", SHKEY, CM_INV|CM_ABR },
2975 { "key", SHKEY, 0 },
2976 #ifndef NOKVERBS
2977 { "kverbs", SHKVB, 0 },
2978 #endif /* NOKVERBS */
2979 #endif /* NOSETKEY */
2980 #ifdef CK_LABELED
2981 { "labeled-file-info", SHLBL, 0 },
2982 #endif /* CK_LABELED */
2983 #ifndef NOCSETS
2984 { "languages", SHLNG, 0 },
2985 #ifndef NO_LOCALE
2986 { "locale", SHOLOC,0 },
2987 #endif /* NO_LOCALE */
2988 #endif /* NOCSETS */
2989 { "log", SHLOG, CM_INV|CM_ABR },
2990 { "logs", SHLOG, 0 },
2991 #ifndef NOSPL
2992 { "macros", SHMAC, 0 },
2993 #endif /* NOSPL */
2994 #ifndef NODIAL
2995 { "modem", SHMOD, CM_LOC },
2996 #else
2997 { "modem-signals",SHCOM, CM_INV|CM_LOC },
2998 #endif /* NODIAL */
2999 #ifndef NOLOCAL
3000 #ifdef OS2MOUSE
3001 { "mouse", SHMOU, CM_LOC },
3002 #endif /* OS2MOUSE */
3003 #endif /* NOLOCAL */
3004 #ifdef NETCONN
3005 { "network", SHNET, CM_LOC },
3006 #else
3007 { "network", SHNET, CM_INV|CM_LOC },
3008 #endif /* NETCONN */
3009 { "options", SHOPTS, 0 },
3010 #ifndef NOSPL
3011 { "output", SHOUTP, CM_INV },
3012 #endif /* NOSPL */
3013 #ifdef ANYX25
3014 #ifndef IBMX25
3015 { "pad", SHPAD, CM_LOC },
3016 #endif /* IBMX25 */
3017 #endif /* ANYX25 */
3018 { "parameters", SHPAR, CM_INV },
3019 #ifdef PATTERNS
3020 { "patterns", SHOPAT, 0 },
3021 #endif /* PATTERNS */
3022 { "printer", SHPRT, 0 },
3023 #ifdef CK_SPEED
3024 { "prefixing", SHCTL, CM_INV },
3025 #endif /* CK_SPEED */
3026 #ifndef NOXFER
3027 { "protocol", SHPRO, 0 },
3028 #endif /* NOXFER */
3029 { "rename", SHOREN, 0 },
3030 #ifndef NOSPL
3031 { "scripts", SHSCR, CM_LOC },
3032 #endif /* NOSPL */
3033 { "send-list", SHSFL, 0 },
3034 #ifndef NOSERVER
3035 { "server", SHSER, 0 },
3036 #endif /* NOSERVER */
3037 #ifndef NOSEXP
3038 { "sexpression", SHSEXP, 0 },
3039 #endif /* NOSEXP */
3040 #ifdef ANYSSH
3041 { "ssh", SHOSSH, 0 },
3042 #endif /* ANYSSH */
3043 { "stack", SHSTK, 0 },
3044 { "status", SHSTA, 0 },
3045 #ifdef STREAMING
3046 { "streaming", SHOSTR, 0 },
3047 #endif /* STREAMING */
3048 #ifndef NOLOCAL
3049 #ifdef OS2
3050 { "tabs", SHTAB, CM_INV|CM_LOC },
3051 #endif /* OS2 */
3052 #ifdef CK_TAPI
3053 { "tapi", SHTAPI, CM_LOC },
3054 { "tapi-comm", SHTAPI_C, CM_INV|CM_LOC },
3055 { "tapi-location", SHTAPI_L, CM_INV|CM_LOC },
3056 { "tapi-modem", SHTAPI_M, CM_INV|CM_LOC },
3057 #endif /* CK_TAPI */
3058 { "tcp", SHTCP, CM_LOC },
3059 #ifdef TNCODE
3060 { "tel", SHTEL, CM_INV|CM_ABR },
3061 { "telnet", SHTEL, 0 },
3062 { "telopt", SHTOPT, 0 },
3063 { "temp-directory", SHOTMPDIR, 0 },
3064 #endif /* TNCODE */
3065 { "terminal", SHTER, CM_LOC },
3066 #endif /* NOLOCAL */
3067 #ifndef NOSPL
3068 { "tmp-directory", SHOTMPDIR, CM_INV },
3069 #endif /* NOSPL */
3070 #ifndef NOXMIT
3071 { "tr", SHXMI, CM_INV|CM_ABR },
3072 { "tra", SHXMI, CM_INV|CM_ABR },
3073 { "tran", SHXMI, CM_INV|CM_ABR },
3074 { "trans", SHXMI, CM_INV|CM_ABR },
3075 #endif /* NOXMIT */
3076 #ifndef NOXFER
3077 { "transfer", SHOXFER, 0 },
3078 #endif /* NOXFER */
3079 #ifndef NOXMIT
3080 { "transmit", SHXMI, 0 },
3081 #endif /* NOXMIT */
3082 #ifdef CK_TRIGGER
3083 { "trigger", SHTRIG, CM_LOC },
3084 #endif /* CK_TRIGGER */
3085 #ifndef NOSETKEY
3086 #ifndef NOKVERBS
3087 #ifdef OS2
3088 { "udk", SHUDK, CM_LOC },
3089 #endif /* OS2 */
3090 #endif /* NOKVERBS */
3091 #endif /* NOSETKEY */
3092 #ifndef NOSPL
3093 { "variables", SHBUI, 0 },
3094 #endif /* NOSPL */
3095 #ifndef NOFRILLS
3096 { "versions", SHVER, 0 },
3097 #endif /* NOFRILLS */
3098 #ifdef OS2
3099 { "vscrn", SHVSCRN, CM_INV|CM_LOC },
3100 #endif /* OS2 */
3101 { "xfer", SHOXFER, CM_INV },
3102 #ifndef NOXMIT
3103 { "xmit", SHXMI, CM_INV },
3104 #endif /* NOXMIT */
3105 { "", 0, 0 }
3106 };
3107 int nsho = (sizeof(shotab) / sizeof(struct keytab)) - 1;
3108 #endif /* NOSHOW */
3109
3110 #ifdef ANYX25
3111 #ifndef IBMX25
3112 struct keytab padtab[] = { /* PAD commands */
3113 { "clear", XYPADL, 0 },
3114 { "interrupt", XYPADI, 0 },
3115 { "reset", XYPADR, 0 },
3116 { "status", XYPADS, 0 }
3117 };
3118 int npadc = (sizeof(padtab) / sizeof(struct keytab));
3119 #endif /* IBMX25 */
3120 #endif /* ANYX25 */
3121
3122 #ifndef NOSERVER
3123 static struct keytab kmstab[] = {
3124 { "both", 3, 0 },
3125 { "local", 1, 0 },
3126 { "remote", 2, 0 }
3127 };
3128
3129 static struct keytab enatab[] = { /* ENABLE commands */
3130 { "all", EN_ALL, 0 },
3131 #ifndef NOSPL
3132 { "as", EN_ASG, CM_INV|CM_ABR },
3133 { "asg", EN_ASG, CM_INV },
3134 { "assign", EN_ASG, 0 },
3135 #endif /* NOSPL */
3136 #ifndef datageneral
3137 { "bye", EN_BYE, 0 },
3138 #endif /* datageneral */
3139 { "cd", EN_CWD, 0 },
3140 #ifdef ZCOPY
3141 { "copy", EN_CPY, 0 },
3142 #endif /* ZCOPY */
3143 { "cwd", EN_CWD, CM_INV },
3144 { "delete", EN_DEL, 0 },
3145 { "directory", EN_DIR, 0 },
3146 { "enable", EN_ENA, CM_INV },
3147 { "exit", EN_XIT, 0 },
3148 { "finish", EN_FIN, 0 },
3149 { "get", EN_GET, 0 },
3150 { "host", EN_HOS, 0 },
3151 { "mail", EN_MAI, 0 },
3152 { "mkdir", EN_MKD, 0 },
3153 { "print", EN_PRI, 0 },
3154 #ifndef NOSPL
3155 { "query", EN_QUE, 0 },
3156 #endif /* NOSPL */
3157 { "rename", EN_REN, 0 },
3158 { "retrieve", EN_RET, CM_INV },
3159 { "rmdir", EN_RMD, 0 },
3160 { "send", EN_SEN, 0 },
3161 { "set", EN_SET, 0 },
3162 { "space", EN_SPA, 0 },
3163 { "type", EN_TYP, 0 },
3164 { "who", EN_WHO, 0 }
3165 };
3166 static int nena = (sizeof(enatab) / sizeof(struct keytab));
3167 #endif /* NOSERVER */
3168
3169 struct keytab txtbin[] = {
3170 { "all", 2, 0 },
3171 { "binary", 1, 0 },
3172 { "text", 0, 0 }
3173 };
3174
3175 #ifndef NOXFER
3176 static struct keytab sndtab[] = { /* SEND command options */
3177 { "/after", SND_AFT, CM_ARG },
3178 #ifndef NOSPL
3179 { "/array", SND_ARR, CM_ARG },
3180 #endif /* NOSPL */
3181 { "/as-name", SND_ASN, CM_ARG },
3182 { "/b", SND_BIN, CM_INV|CM_ABR },
3183 { "/before", SND_BEF, CM_ARG },
3184 { "/binary", SND_BIN, 0 },
3185 #ifdef CALIBRATE
3186 { "/c", SND_CMD, CM_INV|CM_ABR },
3187 { "/calibrate", SND_CAL, CM_INV|CM_ARG },
3188 #endif /* CALIBRATE */
3189 { "/command", SND_CMD, CM_PSH },
3190 { "/delete", SND_DEL, 0 },
3191 #ifdef UNIXOROSK
3192 { "/dotfiles", SND_DOT, 0 },
3193 #endif /* UNIXOROSK */
3194 { "/except", SND_EXC, CM_ARG },
3195 #ifdef PIPESEND
3196 { "/filter", SND_FLT, CM_ARG|CM_PSH },
3197 #endif /* PIPESEND */
3198 { "/filenames", SND_NAM, CM_ARG },
3199 #ifdef CKSYMLINK
3200 { "/followlinks", SND_LNK, 0 },
3201 #endif /* CKSYMLINK */
3202 #ifdef VMS
3203 { "/image", SND_IMG, 0 },
3204 #else
3205 { "/image", SND_BIN, CM_INV },
3206 #endif /* VMS */
3207 #ifdef CK_LABELED
3208 { "/labeled", SND_LBL, 0 },
3209 #endif /* CK_LABELED */
3210 { "/larger-than", SND_LAR, CM_ARG },
3211 { "/listfile", SND_FIL, CM_ARG },
3212 #ifndef NOFRILLS
3213 { "/mail", SND_MAI, CM_ARG },
3214 #endif /* NOFRILLS */
3215 #ifdef CK_TMPDIR
3216 { "/move-to", SND_MOV, CM_ARG },
3217 #endif /* CK_TMPDIR */
3218 { "/nobackupfiles", SND_NOB, 0 },
3219 #ifdef UNIXOROSK
3220 { "/nodotfiles", SND_NOD, 0 },
3221 #endif /* UNIXOROSK */
3222 #ifdef CKSYMLINK
3223 { "/nofollowlinks", SND_NLK, 0 },
3224 #endif /* CKSYMLINK */
3225 { "/not-after", SND_NAF, CM_ARG },
3226 { "/not-before", SND_NBE, CM_ARG },
3227 { "/pathnames", SND_PTH, CM_ARG },
3228 { "/print", SND_PRI, CM_ARG },
3229 #ifdef CK_XYZ
3230 { "/protocol", SND_PRO, CM_ARG },
3231 #else
3232 { "/protocol", SND_PRO, CM_ARG|CM_INV },
3233 #endif /* CK_XYZ */
3234 { "/quiet", SND_SHH, 0 },
3235 { "/recover", SND_RES, 0 },
3236 #ifdef RECURSIVE
3237 /* Systems where we do recursion */
3238 { "/recursive", SND_REC, 0 },
3239 #else
3240 #ifdef VMS
3241 /* Systems that do recursion themselves without our assistance */
3242 /* if we give them the right kind of wildcard */
3243 { "/recursive", SND_REC, 0 },
3244 #else
3245 #ifdef datageneral
3246 { "/recursive", SND_REC, 0 },
3247 #else
3248 { "/recursive", SND_REC, CM_INV },
3249 #endif /* datageneral */
3250 #endif /* VMS */
3251 #endif /* RECURSIVE */
3252 { "/rename-to", SND_REN, CM_ARG },
3253 { "/since", SND_AFT, CM_INV|CM_ARG },
3254 { "/smaller-than", SND_SMA, CM_ARG },
3255 { "/starting-at", SND_STA, CM_ARG },
3256 #ifndef NOFRILLS
3257 { "/su", SND_ASN, CM_ARG|CM_INV|CM_ABR },
3258 { "/sub", SND_ASN, CM_ARG|CM_INV|CM_ABR },
3259 { "/subject", SND_ASN, CM_ARG },
3260 #endif /* NOFRILLS */
3261 #ifdef RECURSIVE
3262 { "/subdirectories", SND_REC, CM_INV },
3263 #endif /* RECURSIVE */
3264 { "/text", SND_TXT, 0 },
3265 { "/transparent", SND_XPA, 0 },
3266 { "/type", SND_TYP, CM_ARG }
3267 };
3268 #define NSNDTAB sizeof(sndtab)/sizeof(struct keytab)
3269 static int nsndtab = NSNDTAB;
3270
3271 #ifndef NOMSEND
3272 static struct keytab msndtab[] = { /* MSEND options */
3273 { "/after", SND_AFT, CM_ARG },
3274 { "/before", SND_BEF, CM_ARG },
3275 { "/binary", SND_BIN, 0 },
3276 { "/delete", SND_DEL, 0 },
3277 { "/except", SND_EXC, CM_ARG },
3278 { "/filenames", SND_NAM, CM_ARG },
3279 #ifdef CKSYMLINK
3280 { "/followlinks", SND_LNK, 0 },
3281 #endif /* CKSYMLINK */
3282 #ifdef VMS
3283 { "/image", SND_IMG, 0 },
3284 #else
3285 { "/image", SND_BIN, CM_INV },
3286 #endif /* VMS */
3287 #ifdef CK_LABELED
3288 { "/labeled", SND_LBL, 0 },
3289 #endif /* CK_LABELED */
3290 { "/larger-than", SND_LAR, CM_ARG },
3291 { "/list", SND_FIL, CM_ARG },
3292 #ifndef NOFRILLS
3293 { "/mail", SND_MAI, CM_ARG },
3294 #endif /* NOFRILLS */
3295 #ifdef CK_TMPDIR
3296 { "/move-to", SND_MOV, CM_ARG },
3297 #endif /* CK_TMPDIR */
3298 #ifdef CKSYMLINK
3299 { "/nofollowlinks", SND_NLK, 0 },
3300 #endif /* CKSYMLINK */
3301 { "/not-after", SND_NAF, CM_ARG },
3302 { "/not-before", SND_NBE, CM_ARG },
3303 { "/pathnames", SND_PTH, CM_ARG },
3304 { "/print", SND_PRI, CM_ARG },
3305 #ifdef CK_XYZ
3306 { "/protocol", SND_PRO, CM_ARG },
3307 #endif /* CK_XYZ */
3308 { "/quiet", SND_SHH, 0 },
3309 { "/recover", SND_RES, 0 },
3310 { "/rename-to", SND_REN, CM_ARG },
3311 { "/since", SND_AFT, CM_INV|CM_ARG },
3312 { "/smaller-than", SND_SMA, CM_ARG },
3313 { "/starting-at", SND_STA, CM_ARG },
3314 #ifndef NOFRILLS
3315 { "/subject", SND_ASN, CM_ARG },
3316 #endif /* NOFRILLS */
3317 { "/text", SND_TXT, 0 },
3318 { "/transparent", SND_XPA, 0 },
3319 { "/type", SND_TYP, CM_ARG }
3320 };
3321 #define NMSNDTAB sizeof(msndtab)/sizeof(struct keytab)
3322 static int nmsndtab = NMSNDTAB;
3323 #endif /* NOMSEND */
3324 #endif /* NOXFER */
3325
3326 /* CONNECT command switches */
3327
3328 #define CONN_II 0 /* Idle interval */
3329 #define CONN_IS 1 /* Idle string */
3330 #define CONN_IL 2 /* Idle limit */
3331 #define CONN_NV 3 /* Non-Verbose */
3332 #define CONN_TL 4 /* Time limit */
3333 #define CONN_TS 5 /* Trigger string */
3334 #define CONN_AS 6 /* Asynchronous */
3335 #define CONN_SY 7 /* Synchronous */
3336 #define CONN_MAX 7 /* Number of CONNECT switches */
3337
3338 #ifndef NOLOCAL
3339 static struct keytab conntab[] = {
3340 #ifdef OS2
3341 { "/asynchronous", CONN_AS, CM_INV },
3342 #endif /* OS2 */
3343 #ifdef XLIMITS
3344 { "/idle-interval", CONN_II, CM_ARG },
3345 { "/idle-limit", CONN_IL, CM_ARG },
3346 { "/idle-string", CONN_IS, CM_ARG },
3347 { "/quietly", CONN_NV, CM_INV },
3348 #else
3349 { "/quietly", CONN_NV, 0 },
3350 #endif /* XLIMITS */
3351 #ifdef OS2
3352 { "/synchronous", CONN_SY, CM_INV },
3353 #endif /* OS2 */
3354 #ifdef XLIMITS
3355 { "/time-limit", CONN_TL, CM_ARG },
3356 #endif /* XLIMITS */
3357 #ifdef CK_TRIGGER
3358 { "/trigger", CONN_TS, CM_ARG },
3359 #endif /* CK_TRIGGER */
3360 { "",0,0 }
3361 };
3362 #define NCONNTAB sizeof(conntab)/sizeof(struct keytab)
3363 static int nconntab = NCONNTAB;
3364 #endif /* NOLOCAL */
3365
3366 #ifndef NOXFER
3367 static struct keytab stattab[] = { /* STATISTICS command switches */
3368 { "/brief", 1, 0 },
3369 { "/verbose", 0, 0 }
3370 };
3371 #endif /* NOXFER */
3372
3373 #ifndef NOSPL
3374 #ifdef COMMENT
3375 struct mtab mactab[MAC_MAX] = { /* Preinitialized macro table */
3376 { NULL, NULL, 0 }
3377 };
3378 #else
3379 struct mtab *mactab; /* Dynamically allocated macro table */
3380 #endif /* COMMENT */
3381 int nmac = 0;
3382
3383 struct keytab mackey[MAC_MAX]; /* Macro names as command keywords */
3384 #endif /* NOSPL */
3385
3386 #ifndef NOSPL
3387 #ifdef OS2
3388 struct keytab beeptab[] = { /* Beep options */
3389 { "error", BP_FAIL, 0 },
3390 { "information", BP_NOTE, 0 },
3391 { "warning", BP_WARN, 0 }
3392 };
3393 int nbeeptab = sizeof(beeptab)/sizeof(struct keytab);
3394
3395 /* CLEAR COMMMAND-SCREEN options */
3396
3397 #define CLR_C_ALL 0
3398 #define CLR_C_BOL 1
3399 #define CLR_C_BOS 2
3400 #define CLR_C_EOL 3
3401 #define CLR_C_EOS 4
3402 #define CLR_C_LIN 5
3403 #define CLR_C_SCR 6
3404
3405 struct keytab clrcmdtab[] = {
3406 { "all", CLR_C_ALL, 0 },
3407 { "bol", CLR_C_BOL, 0 },
3408 { "bos", CLR_C_BOS, 0 },
3409 { "eol", CLR_C_EOL, 0 },
3410 { "eos", CLR_C_EOS, 0 },
3411 { "line", CLR_C_LIN, 0 },
3412 { "scrollback", CLR_C_SCR, 0 }
3413 };
3414 int nclrcmd = sizeof(clrcmdtab)/sizeof(struct keytab);
3415 #endif /* OS2 */
3416 #endif /* NOSPL */
3417
3418 #ifdef COMMENT
3419 /* Not used at present */
3420 static struct keytab pagetab[] = {
3421 { "/more", 1, CM_INV },
3422 { "/nopage", 0, 0 },
3423 { "/page", 1, 0 }
3424 };
3425 int npagetab = sizeof(pagetab)/sizeof(struct keytab);
3426 #endif /* COMMENT */
3427
3428 #define TYP_NOP 0 /* /NOPAGE */
3429 #define TYP_PAG 1 /* /PAGE */
3430 #define TYP_HEA 2 /* /HEAD:n */
3431 #define TYP_TAI 3 /* /TAIL:n */
3432 #define TYP_PAT 4 /* /MATCH:pattern */
3433 #define TYP_WID 5 /* /WIDTH:cols */
3434 #define TYP_COU 6 /* /COUNT */
3435 #define TYP_OUT 7 /* /OUTPUT:file */
3436 #define TYP_PFX 8 /* /PREFIX:string */
3437 #ifdef UNICODE
3438 #define TYP_XIN 9 /* /TRANSLATE-FROM:charset */
3439 #define TYP_XUT 10 /* /TRANSLATE-TO:charset */
3440 #define TYP_XPA 11 /* /TRANSPARENT */
3441 #endif /* UNICODE */
3442 #ifdef KUI
3443 #define TYP_GUI 12 /* /GUI:title */
3444 #define TYP_HIG 13 /* /HEIGHT:rows */
3445 #endif /* KUI */
3446 #define TYP_NUM 14 /* /NUMBER */
3447
3448 static struct keytab typetab[] = { /* TYPE command switches */
3449 { "/count", TYP_COU, 0 },
3450 #ifdef UNICODE
3451 { "/character-set", TYP_XIN, CM_ARG },
3452 #endif /* UNICODE */
3453 #ifdef KUI
3454 { "/gui", TYP_GUI, CM_ARG },
3455 #endif /* KUI */
3456 { "/head", TYP_HEA, CM_ARG },
3457 #ifdef KUI
3458 { "/height", TYP_HIG, CM_ARG },
3459 #endif /* KUI */
3460 { "/match", TYP_PAT, CM_ARG },
3461 #ifdef CK_TTGWSIZ
3462 { "/more", TYP_PAG, CM_INV },
3463 { "/nopage", TYP_NOP, 0 },
3464 { "/number", TYP_NUM, 0 },
3465 { "/output", TYP_OUT, CM_ARG },
3466 { "/page", TYP_PAG, 0 },
3467 #endif /* CK_TTGWSIZ */
3468 { "/prefix", TYP_PFX, CM_ARG },
3469 { "/tail", TYP_TAI, CM_ARG },
3470 #ifdef UNICODE
3471 { "/translate-to", TYP_XUT, CM_ARG },
3472 { "/transparent", TYP_XPA, 0 },
3473 #endif /* UNICODE */
3474 { "/width", TYP_WID, CM_ARG },
3475 #ifdef UNICODE
3476 { "/xlate-to", TYP_XUT, CM_INV|CM_ARG },
3477 #endif /* UNICODE */
3478 { "", 0, 0 }
3479 };
3480 int ntypetab = sizeof(typetab)/sizeof(struct keytab) - 1;
3481
3482 int typ_page = -1; /* TYPE /[NO]PAGE default */
3483 int typ_wid = -1;
3484
3485 #ifndef NOSPL
3486 #define TRA_ALL 999 /* TRACE command */
3487 #define TRA_ASG 0
3488 #define TRA_CMD 1
3489
3490 int tra_asg = 0;
3491 int tra_cmd = 0;
3492
3493 static struct keytab tracetab[] = { /* TRACE options */
3494 { "all", TRA_ALL, 0 },
3495 { "assignments", TRA_ASG, 0 },
3496 { "command-level", TRA_CMD, 0 }
3497 };
3498 static int ntracetab = sizeof(tracetab)/sizeof(struct keytab);
3499 #endif /* NOSPL */
3500
3501 #ifndef NOSHOW
3502 VOID
showtypopts()3503 showtypopts() {
3504 printf(" TYPE ");
3505 if (typ_page > -1) {
3506 prtopt(&optlines,typ_page ? "/PAGE" : "/NOPAGE");
3507 } else
3508 prtopt(&optlines,"(no options set)");
3509 if (typ_wid > -1) {
3510 ckmakmsg(tmpbuf,TMPBUFSIZ,"/WIDTH:",ckitoa(typ_wid),NULL,NULL);
3511 prtopt(&optlines,tmpbuf);
3512 }
3513 prtopt(&optlines,"");
3514 }
3515 #endif /* NOSHOW */
3516
3517 #ifdef LOCUS
3518 /* isauto == 1 if locus is being switched automatically */
3519
3520 VOID
setlocus(x,isauto)3521 setlocus(x, isauto) int x, isauto; {
3522 extern int quitting;
3523 if (x) x = 1;
3524 if (x && locus) return;
3525 if (!x && !locus) return;
3526 /* Get here if it actually needs to be changed */
3527 #ifdef OS2
3528 if (isauto && /* Automatically switching */
3529 !quitting && /* not exiting */
3530 autolocus == 2) { /* and AUTOLOCUS is set to ASK */
3531 char locmsg[300];
3532 ckmakmsg(locmsg,300,
3533 "Switching Locus to ",
3534 x ? "LOCAL" : "REMOTE",
3535 " for file management commands\n"
3536 "such as CD, DIRECTORY, DELETE, RENAME. Type HELP SET\n"
3537 "LOCUS at the K-95> prompt for further info. Use the\n"
3538 #ifdef KUI
3539 "Actions menu or SET LOCUS command to disable automatic\n"
3540 "Locus switching or to disable these queries.",
3541 #else /* KUI */
3542 "SET LOCUS command to disable automatic locus switching\n"
3543 "or to disable these queries.",
3544 #endif /* KUI */
3545 NULL);
3546 if (uq_ok(locmsg,"OK to switch Locus?",3,NULL,1)) {
3547 locus = x;
3548 #ifdef KUI
3549 KuiSetProperty(KUI_LOCUS,x,0);
3550 #endif /* KUI */
3551 return;
3552 }
3553 } else {
3554 #endif /* OS2 */
3555 if (isauto && msgflg && !quitting)
3556 printf("Switching LOCUS for file-management commands to %s %s.\n",
3557 x ? "LOCAL" : "REMOTE",
3558 "(HELP LOCUS for info)"
3559 );
3560 locus = x;
3561 #ifdef OS2
3562 #ifdef KUI
3563 KuiSetProperty(KUI_LOCUS,x,0);
3564 #endif /* KUI */
3565 }
3566 #endif /* OS2 */
3567 }
3568
3569 VOID
setautolocus(x)3570 setautolocus(x) int x; {
3571 autolocus = x;
3572 #ifdef KUI
3573 KuiSetProperty(KUI_AUTO_LOCUS,x,0);
3574 #endif /* KUI */
3575 }
3576 #endif /* LOCUS */
3577
3578 int
settypopts()3579 settypopts() { /* Set TYPE option defaults */
3580 int xp = -1;
3581 int c, getval;
3582 while (1) {
3583 if ((y = cmswi(typetab,ntypetab,"Switch","",xxstring)) < 0) {
3584 if (y == -3)
3585 break;
3586 else
3587 return(y);
3588 }
3589 c = cmgbrk();
3590 if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
3591 printf("?This switch does not take an argument\n");
3592 return(-9);
3593 }
3594 switch (y) {
3595 case TYP_NOP: xp = 0; break;
3596 case TYP_PAG: xp = 1; break;
3597 case TYP_WID:
3598 if (getval)
3599 if ((x = cmnum("Column at which to truncate",
3600 ckitoa(cmd_cols),10,&y,xxstring)) < 0)
3601 return(x);
3602 typ_wid = y;
3603 break;
3604
3605 default:
3606 printf("?Sorry, this option can not be set\n");
3607 return(-9);
3608 }
3609 }
3610 if ((x = cmcfm()) < 0) /* Get confirmation */
3611 return(x);
3612 if (xp > -1) typ_page = xp; /* Confirmed, save defaults */
3613 return(success = 1);
3614 }
3615
3616 _PROTOTYP (char * getbasename, ( char * ) );
3617
3618 /* Forward declarations of functions local to this module */
3619
3620 #ifdef UNIX
3621 _PROTOTYP (int douchmod, ( void ) );
3622 #endif /* UNIX */
3623 #ifdef CKPURGE
3624 _PROTOTYP (int dopurge, ( void ) );
3625 #endif /* CKPURGE */
3626 #ifndef NOSPL
3627 _PROTOTYP (int doundef, ( int ) );
3628 _PROTOTYP (int doask, ( int ) );
3629 _PROTOTYP (int dodef, ( int ) );
3630 _PROTOTYP (int doelse, ( void ) );
3631 _PROTOTYP (int dofor, ( void ) );
3632 #endif /* NOSPL */
3633 #ifndef NODIAL
3634 _PROTOTYP (int dodial, ( int ) );
3635 #endif /* NODIAL */
3636 _PROTOTYP (int dodel, ( void ) );
3637 _PROTOTYP (int dopaus, ( int ) );
3638 #ifndef NOPUSH
3639 #ifdef TCPSOCKET
3640 _PROTOTYP (int doping, ( void ) );
3641 _PROTOTYP (int doftp, ( void ) );
3642 #endif /* TCPSOCKET */
3643 #endif /* NOPUSH */
3644 #ifndef NORENAME
3645 #ifndef NOFRILLS
3646 _PROTOTYP (int dorenam, ( void ) );
3647 #endif /* NOFRILLS */
3648 #endif /* NORENAME */
3649 #ifdef ZCOPY
3650 _PROTOTYP (int docopy, ( void ) );
3651 #endif /* ZCOPY */
3652 #ifdef NT
3653 _PROTOTYP (int dolink, ( void ));
3654 #endif /* NT */
3655 #ifdef CK_REXX
3656 _PROTOTYP (int dorexx, ( void ) );
3657 #endif /* CK_REXX */
3658
3659 #ifdef TNCODE
3660 static struct keytab telcmd[] = {
3661 { "abort", TN_ABORT, CM_INV }, /* Emotionally toned - don't show */
3662 { "ao", TN_AO, 0 },
3663 { "ayt", TN_AYT, 0 },
3664 { "break", BREAK, 0 },
3665 { "cancel",TN_ABORT, 0 },
3666 { "dmark", TN_DM, 0 },
3667 { "do", DO, 0 },
3668 { "dont", DONT, 0 },
3669 { "ec", TN_EC, 0 },
3670 { "el", TN_EL, 0 },
3671 { "eof", TN_EOF, 0 },
3672 { "eor", TN_EOR, 0 },
3673 #ifdef CK_KERBEROS
3674 #ifdef KRB5
3675 #define TN_FWD 1
3676 { "forward", TN_FWD, CM_INV },
3677 #endif /* KRB5 */
3678 #endif /* CK_KERBEROS */
3679 { "ga", TN_GA, 0 },
3680 { "ip", TN_IP, 0 },
3681 { "nop", TN_NOP, 0 },
3682 { "sak", TN_SAK, CM_INV },
3683 { "sb", SB, 0 },
3684 { "se", SE, 0 },
3685 { "susp", TN_SUSP, 0 },
3686 { "will", WILL, 0 },
3687 { "wont", WONT, 0 }
3688 };
3689 static int ntelcmd = (sizeof(telcmd) / sizeof(struct keytab));
3690
3691 static struct keytab tnopts[] = {
3692 #ifdef CK_AUTHENTICATION
3693 { "auth", TELOPT_AUTHENTICATION, 0 },
3694 #else
3695 { "auth", TELOPT_AUTHENTICATION, CM_INV },
3696 #endif /* CK_AUTHENTICATION */
3697 { "binary", TELOPT_BINARY, 0 },
3698 #ifdef TN_COMPORT
3699 { "c", TELOPT_COMPORT, CM_INV|CM_ABR},
3700 { "co", TELOPT_COMPORT, CM_INV|CM_ABR},
3701 { "com", TELOPT_COMPORT, CM_INV|CM_ABR},
3702 { "com-port-control", TELOPT_COMPORT, 0 },
3703 { "comport-control", TELOPT_COMPORT, CM_INV},
3704 #else /* TN_COMPORT */
3705 { "com-port-control", TELOPT_COMPORT, CM_INV },
3706 { "comport-control", TELOPT_COMPORT, CM_INV},
3707 #endif /* TN_COMPORT */
3708 { "echo", TELOPT_ECHO, 0 },
3709 #ifdef CK_ENCRYPTION
3710 { "encrypt", TELOPT_ENCRYPTION, 0 },
3711 #else
3712 { "encrypt", TELOPT_ENCRYPTION, CM_INV },
3713 #endif /* CK_ENCRYPTION */
3714 #ifdef CK_FORWARD_X
3715 { "forward-x", TELOPT_FORWARD_X, 0 },
3716 #else
3717 { "forward-x", TELOPT_FORWARD_X, CM_INV },
3718 #endif /* CK_FORWARD_X */
3719 #ifdef IKS_OPTION
3720 { "kermit", TELOPT_KERMIT, 0 },
3721 #else
3722 { "kermit", TELOPT_KERMIT, CM_INV },
3723 #endif /* IKS_OPTION */
3724 { "lflow", TELOPT_LFLOW, CM_INV },
3725 { "logout", TELOPT_LOGOUT, CM_INV },
3726 #ifdef CK_NAWS
3727 { "naws", TELOPT_NAWS, 0 },
3728 #else
3729 { "naws", TELOPT_NAWS, CM_INV },
3730 #endif /* CK_NAWS */
3731 #ifdef CK_ENVIRONMENT
3732 { "new-environment", TELOPT_NEWENVIRON, 0 },
3733 #else
3734 { "new-environment", TELOPT_NEWENVIRON, CM_INV },
3735 #endif /* CK_ENVIRONMENT */
3736 { "pragma-heartbeat",TELOPT_PRAGMA_HEARTBEAT, CM_INV },
3737 { "pragma-logon", TELOPT_PRAGMA_LOGON, CM_INV },
3738 { "pragma-sspi", TELOPT_SSPI_LOGON, CM_INV },
3739 { "sak", TELOPT_IBM_SAK, CM_INV },
3740 #ifdef CK_SNDLOC
3741 { "send-location", TELOPT_SNDLOC, 0 },
3742 #else
3743 { "send-location", TELOPT_SNDLOC, CM_INV },
3744 #endif /* CK_SNDLOC */
3745 { "sga", TELOPT_SGA, 0 },
3746 #ifdef CK_SSL
3747 { "start-tls", TELOPT_START_TLS, 0 },
3748 #else
3749 { "start-tls", TELOPT_START_TLS, CM_INV },
3750 #endif /* CK_SSL */
3751 { "ttype", TELOPT_TTYPE, 0 },
3752 #ifdef CK_ENVIRONMENT
3753 { "xdisplay-location", TELOPT_XDISPLOC, 0 },
3754 #else
3755 { "xdisplay-location", TELOPT_XDISPLOC, CM_INV },
3756 #endif /* CK_ENVIRONMENT */
3757 { "", 0, 0 }
3758 };
3759 static int ntnopts = (sizeof(tnopts) / sizeof(struct keytab)) - 1;
3760
3761 static struct keytab tnsbopts[] = {
3762 #ifdef CK_NAWS
3763 { "naws", TELOPT_NAWS, 0 },
3764 #endif /* CK_NAWS */
3765 { "", 0, 0 }
3766 };
3767 static int ntnsbopts = (sizeof(tnsbopts) / sizeof(struct keytab)) - 1;
3768 #endif /* TNCODE */
3769
3770 #ifdef TCPSOCKET
3771 #ifndef NOPUSH
3772 #ifdef SYSFTP
3773 int
doftp()3774 doftp() { /* (External) FTP command */
3775 char *p, *f; /* (See doxftp() for internal one) */
3776 int x;
3777
3778 if (network) /* If we have a current connection */
3779 ckstrncpy(line,ttname,LINBUFSIZ); /* get the host name */
3780 else *line = '\0'; /* as default host */
3781 for (p = line; *p; p++) /* Remove ":service" from end. */
3782 if (*p == ':') { *p = '\0'; break; }
3783 if ((x = cmtxt("IP host name or number", line, &s, xxstring)) < 0)
3784 return(x);
3785 if (nopush) {
3786 printf("?Sorry, FTP command disabled\n");
3787 return(success = 0);
3788 }
3789 /* Construct FTP command */
3790 #ifdef VMS
3791 #ifdef MULTINET /* TGV MultiNet */
3792 ckmakmsg(line,LINBUFSIZ,"multinet ftp ",s,NULL,NULL);
3793 #else
3794 ckmakmsg(line,LINBUFSIZ,"ftp ",s,NULL,NULL);
3795 #endif /* MULTINET */
3796 #else /* Not VMS */
3797 #ifdef OS2ORUNIX
3798 #ifndef NOFTP
3799 f = ftpapp;
3800 if (!f) f = "";
3801 if (!f[0]) f = "ftp";
3802 ckmakmsg(line,LINBUFSIZ,f," ",s,NULL);
3803 #ifdef OS2
3804 p = line + strlen(ftpapp);
3805 while (p != line) {
3806 if (*p == '/') *p = '\\';
3807 p--;
3808 }
3809 #endif /* OS2 */
3810 #else /* NOFTP */
3811 ckmakmsg(line,LINBUFSIZ,"ftp ",s,NULL,NULL);
3812 #endif /* NOFTP */
3813 #else /* OS2ORUNIX */
3814 ckmakmsg(line,LINBUFSIZ,"ftp ",s,NULL,NULL);
3815 #endif /* OS2ORUNIX */
3816 #endif /* VMS */
3817 conres(); /* Make console normal */
3818 #ifdef DEC_TCPIP
3819 printf("\n"); /* Prevent prompt-stomping */
3820 #endif /* DEC_TCPIP */
3821 x = zshcmd(line);
3822 concb((char)escape);
3823 return(success = x);
3824 }
3825 #endif /* SYSFTP */
3826
3827 int
doping()3828 doping() { /* PING command */
3829 char *p; /* just runs ping program */
3830 int x;
3831
3832 if (network) /* If we have a current connection */
3833 ckstrncpy(line,ttname,LINBUFSIZ); /* get the host name */
3834 else *line = '\0'; /* as default host to be pinged. */
3835 for (p = line; *p; p++) /* Remove ":service" from end. */
3836 if (*p == ':') { *p = '\0'; break; }
3837 if ((x = cmtxt("IP host name or number", line, &s, xxstring)) < 0)
3838 return(x);
3839 if (nopush) {
3840 printf("?Sorry, PING command disabled\n");
3841 return(success = 0);
3842 }
3843
3844 /* Construct PING command */
3845 #ifdef VMS
3846 #ifdef MULTINET /* TGV MultiNet */
3847 ckmakmsg(line,LINBUFSIZ,"multinet ping ",s," /num=1",NULL);
3848 #else
3849 ckmakmsg(line,LINBUFSIZ,"ping ",s," 56 1",NULL); /* Other VMS TCP/IP's */
3850 #endif /* MULTINET */
3851 #else /* Not VMS */
3852 ckmakmsg(line,LINBUFSIZ,"ping ",s,NULL,NULL);
3853 #endif /* VMS */
3854 conres(); /* Make console normal */
3855 #ifdef DEC_TCPIP
3856 printf("\n"); /* Prevent prompt-stomping */
3857 #endif /* DEC_TCPIP */
3858 x = zshcmd(line);
3859 concb((char)escape);
3860 return(success = x);
3861 }
3862 #endif /* NOPUSH */
3863 #endif /* TCPSOCKET */
3864
3865 static VOID
doend(x)3866 doend(x) int x; {
3867 #ifndef NOSPL
3868 /* Pop from all FOR/WHILE/XIF/SWITCH's */
3869 debug(F101,"doend maclvl 1","",maclvl);
3870 while ((maclvl > 0) &&
3871 (m_arg[maclvl-1][0]) &&
3872 (cmdstk[cmdlvl].src == CMD_MD) &&
3873 (!strncmp(m_arg[maclvl-1][0],"_xif",4) ||
3874 !strncmp(m_arg[maclvl-1][0],"_for",4) ||
3875 !strncmp(m_arg[maclvl-1][0],"_whi",4) ||
3876 !strncmp(m_arg[maclvl-1][0],"_swi",4))) {
3877 debug(F110,"END popping",m_arg[maclvl-1][0],0);
3878 dogta(XXPTA); /* Put args back */
3879 popclvl(); /* Pop up two levels */
3880 popclvl();
3881 debug(F101,"doend maclvl 2","",maclvl);
3882 }
3883 if (maclvl > -1) {
3884 if (mrval[maclvl]) /* Free previous retval if any */
3885 free(mrval[maclvl]);
3886 mrval[maclvl] = malloc(16); /* Room for up to 15 digits */
3887 if (mrval[maclvl]) /* Record current retval */
3888 ckmakmsg(mrval[maclvl],16,ckitoa(x),NULL,NULL,NULL);
3889 }
3890 #endif /* NOSPL */
3891 popclvl(); /* Now pop out of macro or TAKE file */
3892 #ifndef NOSPL
3893 #ifdef DEBUG
3894 if (deblog) {
3895 debug(F101,"END maclvl 3","",maclvl);
3896 debug(F111,"END mrval[maclvl]",mrval[maclvl],maclvl);
3897 debug(F111,"END mrval[maclvl+1]",mrval[maclvl+1],maclvl+1);
3898 }
3899 #endif /* DEBUG */
3900 #endif /* NOSPL */
3901 }
3902
3903 #ifdef CKROOT
3904 int
dochroot()3905 dochroot() {
3906 if ((x = cmdir("Name of new root directory","",&s,xxstring)) < 0) {
3907 if (x == -3) {
3908 printf("?Directory name required\n");
3909 return(-9);
3910 }
3911 return(x);
3912 }
3913 ckstrncpy(line,s,LINBUFSIZ);
3914 s = line;
3915 if ((x = cmcfm()) < 0) return(x);
3916 s = brstrip(s);
3917 x = zsetroot(s);
3918 if (x < 0) {
3919 char * m = NULL;
3920 switch (x) {
3921 case -1:
3922 case -2: m = "Not a directory"; break;
3923 case -3: m = "Internal error"; break;
3924 case -4: m = "Access denied"; break;
3925 case -5: m = "Off limits"; break;
3926 }
3927 if (m) printf("%s: \"%s\"\n", m, s);
3928 return(m ? -9 : -2);
3929 } else {
3930 nopush = 1;
3931 return(success = 1);
3932 }
3933 }
3934 #endif /* CKROOT */
3935
3936 #ifndef NOXFER
3937 static char * asnbuf = NULL; /* As-name buffer pointer */
3938
3939 char sndxnam[] = { "_array_x_" }; /* (with replaceable x!) */
3940
3941 /*
3942 The new SEND command, replacing BSEND, CSEND, PSEND, etc etc.
3943 Call with cx = top-level keyword value. Returns:
3944 < 0 On parse error.
3945 0 On other type of failure (e.g. requested operation not allowed).
3946 1 On success with sstate set to 's' so protocol will begin.
3947 */
3948
3949 /* D O X S E N D -- Parse SEND and related commands with switches */
3950
3951 int
doxsend(cx)3952 doxsend(cx) int cx; {
3953 int c, i, n, wild, confirmed = 0; /* Workers */
3954 int x, y; /* of the world... */
3955 int getval = 0; /* Whether to get switch value */
3956 extern char * snd_move; /* Directory to move sent files to */
3957 extern char * snd_rename; /* What to rename sent files to */
3958 extern char * filefile; /* File containing filenames to send */
3959 extern int xfiletype; /* Send only text (or binary) files */
3960 extern struct keytab pathtab[]; /* PATHNAMES option keywords */
3961 extern int npathtab; /* How many of them */
3962 extern int recursive; /* Recursive directory traversal */
3963 extern int rprintf; /* REMOTE PRINT flag */
3964 extern int fdispla; /* TRANSFER DISPLAY setting */
3965 extern int skipbup; /* Skip backup files when sending */
3966 struct stringint pv[SND_MAX+1]; /* Temporary array for switch values */
3967 struct FDB sf, sw, fl, cm; /* FDBs for each parse function */
3968 int mlist = 0; /* Flag for MSEND or MMOVE */
3969 char * m; /* For making help messages */
3970 extern struct keytab protos[]; /* File transfer protocols */
3971 extern int xfrxla, g_xfrxla, nprotos;
3972 extern char sndbefore[], sndafter[], *sndexcept[]; /* Selection criteria */
3973 extern char sndnbefore[], sndnafter[];
3974 extern CK_OFF_T sndsmaller, sndlarger, calibrate;
3975 #ifndef NOSPL
3976 int range[2]; /* Array range */
3977 char ** ap = NULL; /* Array pointer */
3978 int arrayx = -1; /* Array index */
3979 #endif /* NOSPL */
3980
3981 #ifdef NEWFTP
3982 if ((ftpget == 1) || ((ftpget == 2) && ftpisopen())) {
3983 if (cx == XXMAI) {
3984 printf("?Sorry, No MAIL with FTP\n");
3985 return(-9);
3986 }
3987 return(doftpput(cx,0));
3988 }
3989 #endif /* NEWFTP */
3990
3991 for (i = 0; i <= SND_MAX; i++) { /* Initialize switch values */
3992 pv[i].sval = NULL; /* to null pointers */
3993 pv[i].ival = -1; /* and -1 int values */
3994 pv[i].wval = (CK_OFF_T)-1; /* and -1 wide values */
3995 }
3996 #ifndef NOSPL
3997 range[0] = -1;
3998 range[1] = -1;
3999 sndxin = -1; /* Array index */
4000 #endif /* NOSPL */
4001 sndarray = NULL; /* Array pointer */
4002
4003 #ifdef UNIXOROSK
4004 g_matchdot = matchdot; /* Match dot files */
4005 #endif /* UNIXOROSK */
4006 g_recursive = recursive; /* Recursive sending */
4007 recursive = 0; /* Save global value, set local */
4008 debug(F101,"xsend entry fncnv","",fncnv);
4009
4010 /* Preset switch values based on top-level command that called us */
4011
4012 switch (cx) {
4013 case XXMSE: /* MSEND */
4014 mlist = 1; break;
4015 case XXCSEN: /* CSEND */
4016 pv[SND_CMD].ival = 1; break;
4017 case XXMMOVE: /* MMOVE */
4018 mlist = 1;
4019 case XXMOVE: /* MOVE */
4020 pv[SND_DEL].ival = 1; break;
4021 case XXRSEN: /* RESEND */
4022 pv[SND_BIN].ival = 1; /* Implies /BINARY */
4023 pv[SND_RES].ival = 1; break;
4024 case XXMAI: /* MAIL */
4025 pv[SND_MAI].ival = 1; break;
4026 }
4027
4028 /* Set up chained parse functions... */
4029
4030 cmfdbi(&sw, /* First FDB - command switches */
4031 _CMKEY, /* fcode */
4032 "Filename, or switch", /* hlpmsg */
4033 "", /* default */
4034 "", /* addtl string data */
4035 #ifdef NOMSEND
4036 nsndtab, /* addtl numeric data 1: tbl size */
4037 #else
4038 mlist ? nmsndtab : nsndtab, /* addtl numeric data 1: tbl size */
4039 #endif /* NOMSEND */
4040 4, /* addtl numeric data 2: 4 = cmswi */
4041 xxstring, /* Processing function */
4042 #ifdef NOMSEND
4043 sndtab, /* Keyword table */
4044 #else
4045 mlist ? msndtab : sndtab,
4046 #endif /* NOMSEND */
4047 &sf /* Pointer to next FDB */
4048 );
4049 cmfdbi(&sf, /* 2nd FDB - file to send */
4050 _CMIFI, /* fcode */
4051 "File(s) to send", /* hlpmsg */
4052 "", /* default */
4053 "", /* addtl string data */
4054 nolinks, /* addtl numeric data 1 */
4055 0, /* addtl numeric data 2 */
4056 xxstring,
4057 NULL,
4058 mlist ? &cm : &fl
4059 );
4060 cmfdbi(&fl, /* 3rd FDB - command to send from */
4061 _CMFLD, /* fcode */
4062 "Command", /* hlpmsg */
4063 "", /* default */
4064 "", /* addtl string data */
4065 0, /* addtl numeric data 1 */
4066 0, /* addtl numeric data 2 */
4067 xxstring,
4068 NULL,
4069 &cm
4070 );
4071 cmfdbi(&cm, /* 4th FDB - Confirmation */
4072 _CMCFM, /* fcode */
4073 "", /* hlpmsg */
4074 "", /* default */
4075 "", /* addtl string data */
4076 0, /* addtl numeric data 1 */
4077 0, /* addtl numeric data 2 */
4078 NULL,
4079 NULL,
4080 NULL
4081 );
4082
4083 while (1) { /* Parse 0 or more switches */
4084 x = cmfdb(&sw); /* Parse something */
4085 debug(F101,"xsend cmfdb","",x);
4086 if (x < 0) /* Error */
4087 goto xsendx; /* or reparse needed */
4088 if (cmresult.fcode != _CMKEY) /* Break out if not a switch */
4089 break;
4090 /*
4091 They gave a switch, but let's see how they terminated it.
4092 If they ended it with : or =, then we must parse a value.
4093 If they ended it with anything else, then we must NOT parse a value.
4094 */
4095 c = cmgbrk(); /* Get break character */
4096 getval = (c == ':' || c == '='); /* to see how they ended the switch */
4097 if (getval && !(cmresult.kflags & CM_ARG)) {
4098 printf("?This switch does not take arguments\n");
4099 x = -9;
4100 goto xsendx;
4101 }
4102 if (!getval && (cmgkwflgs() & CM_ARG)) {
4103 printf("?This switch requires an argument\n");
4104 x = -9;
4105 goto xsendx;
4106 }
4107 n = cmresult.nresult; /* Numeric result = switch value */
4108 debug(F101,"xsend switch","",n);
4109
4110 switch (n) { /* Process the switch */
4111 case SND_CMD: /* These take no args */
4112 if (nopush) {
4113 printf("?Sorry, system command access is disabled\n");
4114 x = -9;
4115 goto xsendx;
4116 }
4117 #ifdef PIPESEND
4118 else if (sndfilter) {
4119 printf(
4120 "?Sorry, no SEND /COMMAND or CSEND when SEND FILTER selected\n");
4121 x = -9;
4122 goto xsendx;
4123 }
4124 #endif /* PIPESEND */
4125 sw.hlpmsg = "Command, or switch"; /* Change help message */
4126 pv[n].ival = 1; /* Just set the flag */
4127 pv[SND_ARR].ival = 0;
4128 break;
4129
4130 case SND_REC: /* /RECURSIVE */
4131 recursive = 2; /* Set the real variable */
4132 pv[SND_PTH].ival = PATH_REL; /* Give them relative pathnames */
4133 pv[n].ival = 1; /* Just set the flag */
4134 break;
4135
4136 case SND_RES: /* /RECOVER (resend) */
4137 pv[SND_ARR].ival = 0;
4138 pv[SND_BIN].ival = 1; /* Implies /BINARY */
4139 case SND_NOB: /* /NOBACKUP */
4140 case SND_DEL: /* /DELETE */
4141 case SND_SHH: /* /QUIET */
4142 pv[n].ival = 1; /* Just set the flag */
4143 break;
4144
4145 #ifdef UNIXOROSK
4146 /* Like recursive, these are set immediately because they affect cmifi() */
4147 case SND_DOT: /* /DOTFILES */
4148 matchdot = 1;
4149 break;
4150 case SND_NOD: /* /NODOTFILES */
4151 matchdot = 0;
4152 break;
4153 #endif /* UNIXOROSK */
4154
4155 /* File transfer modes - each undoes the others */
4156
4157 case SND_BIN: /* Binary */
4158 case SND_TXT: /* Text */
4159 case SND_IMG: /* Image */
4160 case SND_LBL: /* Labeled */
4161 pv[SND_BIN].ival = 0;
4162 pv[SND_TXT].ival = 0;
4163 pv[SND_IMG].ival = 0;
4164 pv[SND_LBL].ival = 0;
4165 pv[n].ival = 1;
4166 break;
4167
4168 #ifdef CKSYMLINK
4169 case SND_LNK:
4170 case SND_NLK:
4171 nolinks = (n == SND_NLK) ? 2 : 0;
4172 cmfdbi(&sf, /* Redo cmifi() */
4173 _CMIFI, /* fcode */
4174 "File(s) to send", /* hlpmsg */
4175 "", /* default */
4176 "", /* addtl string data */
4177 nolinks, /* addtl numeric data 1 */
4178 0, /* addtl numeric data 2 */
4179 xxstring,
4180 NULL,
4181 mlist ? &cm : &fl
4182 );
4183 break;
4184 #endif /* CKSYMLINK */
4185
4186 case SND_EXC: /* Excludes */
4187 if (!getval) break;
4188 if ((x = cmfld("Pattern","",&s,xxstring)) < 0) {
4189 if (x == -3) {
4190 printf("?Pattern required\n");
4191 x = -9;
4192 }
4193 goto xsendx;
4194 }
4195 if (pv[n].sval) free(pv[n].sval);
4196 y = strlen(s);
4197 if (y > 256) {
4198 printf("?Pattern too long - 256 max\n");
4199 x = -9;
4200 goto xsendx;
4201 }
4202 pv[n].sval = malloc(y+1);
4203 if (pv[n].sval) {
4204 strcpy(pv[n].sval,s); /* safe */
4205 pv[n].ival = 1;
4206 }
4207 break;
4208
4209 case SND_MOV: /* MOVE after */
4210 case SND_REN: /* RENAME after */
4211 if (!getval) break;
4212 if ((x = cmfld(n == SND_MOV ?
4213 "device and/or directory for source file after sending" :
4214 "new name for source file after sending",
4215 "",
4216 &s,
4217 n == SND_MOV ? xxstring : NULL
4218 )) < 0) {
4219 if (x == -3) {
4220 printf("%s\n", n == SND_MOV ?
4221 "?Destination required" :
4222 "?New name required"
4223 );
4224 x = -9;
4225 }
4226 goto xsendx;
4227 }
4228 if (pv[n].sval) free(pv[n].sval);
4229 s = brstrip(s);
4230 y = strlen(s);
4231 if (y > 0) {
4232 pv[n].sval = malloc(y+1);
4233 if (pv[n].sval) {
4234 strcpy(pv[n].sval,s); /* safe */
4235 pv[n].ival = 1;
4236 }
4237 }
4238 break;
4239
4240 case SND_SMA: /* Smaller / larger than */
4241 case SND_LAR: {
4242 CK_OFF_T w;
4243 if (!getval) break;
4244 if ((x = cmnumw("Size in bytes","0",10,&w,xxstring)) < 0)
4245 goto xsendx;
4246 pv[n].wval = w;
4247 break;
4248 }
4249 case SND_AFT: /* Send /AFTER:date-time */
4250 case SND_BEF: /* Send /BEFORE:date-time */
4251 case SND_NAF: /* Send /NOT-AFTER:date-time */
4252 case SND_NBE: /* Send /NOT-BEFORE:date-time */
4253 if (!getval) break;
4254 if ((x = cmdate("File date-time","",&s,0,xxstring)) < 0) {
4255 if (x == -3) {
4256 printf("?Date-time required\n");
4257 x = -9;
4258 }
4259 goto xsendx;
4260 }
4261 if (pv[n].sval) free(pv[n].sval);
4262 pv[n].sval = malloc((int)strlen(s)+1);
4263 if (pv[n].sval) {
4264 strcpy(pv[n].sval,s); /* safe */
4265 pv[n].ival = 1;
4266 }
4267 break;
4268
4269 case SND_MAI: /* Send as mail (= MAIL) */
4270 #ifdef IKSD
4271 if (inserver && !ENABLED(en_mai)) {
4272 printf("?Sorry, sending files as mail is disabled\n");
4273 return(-9);
4274 }
4275 #endif /* IKSD */
4276 pv[n].ival = 1;
4277 if (!getval) break;
4278 if ((x = cmfld("e-mail address","",&s,xxstring)) < 0) {
4279 if (x == -3) {
4280 printf("?address required\n");
4281 x = -9;
4282 }
4283 goto xsendx;
4284 }
4285 s = brstrip(s);
4286 if (pv[n].sval) free(pv[n].sval);
4287 pv[n].sval = malloc((int)strlen(s)+1);
4288 if (pv[n].sval)
4289 strcpy(pv[n].sval,s); /* safe */
4290 break;
4291
4292 case SND_PRI: /* Send to be printed (REMOTE PRINT) */
4293 #ifdef IKSD
4294 if (inserver && !ENABLED(en_mai)) {
4295 printf("?Sorry, sending files for printing is disabled\n");
4296 return(-9);
4297 }
4298 #endif /* IKSD */
4299 pv[n].ival = 1;
4300 if (!getval) break;
4301 if ((x = cmfld("Print options","",&s,xxstring)) < 0)
4302 if (x != -3) goto xsendx;
4303 s = brstrip(s);
4304 if (pv[n].sval) free(pv[n].sval);
4305 pv[n].sval = malloc((int)strlen(s)+1);
4306 if (pv[n].sval)
4307 strcpy(pv[n].sval,s); /* safe */
4308 break;
4309
4310 case SND_ASN: /* As-name */
4311 debug(F101,"xsend /as-name getval","",getval);
4312 if (!getval) break;
4313 if ((x = cmfld("Name to send under","",&s,NULL)) < 0) {
4314 if (x == -3) {
4315 printf("?name required\n");
4316 x = -9;
4317 }
4318 goto xsendx;
4319 }
4320 s = brstrip(s);
4321 if ((y = strlen(s)) > 0) {
4322 if (pv[n].sval) free(pv[n].sval);
4323 pv[n].sval = malloc(y+1);
4324 if (pv[n].sval) {
4325 strcpy(pv[n].sval,s); /* safe */
4326 pv[n].ival = 1;
4327 }
4328 }
4329 break;
4330
4331 case SND_STA: { /* Starting position (= PSEND) */
4332 CK_OFF_T w;
4333 if (!getval) break;
4334 if ((x = cmnumw("0-based position","0",10,&w,xxstring)) < 0)
4335 goto xsendx;
4336 pv[n].wval = w;
4337 break;
4338 }
4339 case SND_PRO: /* Protocol to use */
4340 if (!getval) break;
4341 if ((x = cmkey(protos,nprotos,"File-transfer protocol","",
4342 xxstring)) < 0) {
4343 if (x == -3) {
4344 printf("?name of protocol required\n");
4345 x = -9;
4346 }
4347 goto xsendx;
4348 }
4349 pv[n].ival = x;
4350 break;
4351
4352 #ifdef PIPESEND
4353 case SND_FLT: /* Filter */
4354 debug(F101,"xsend /filter getval","",getval);
4355 if (!getval) break;
4356 if ((x = cmfld("Filter program to send through","",&s,NULL)) < 0) {
4357 if (x == -3)
4358 s = "";
4359 else
4360 goto xsendx;
4361 }
4362 if (*s) s = brstrip(s);
4363 y = strlen(s);
4364 for (x = 0; x < y; x++) { /* Make sure they included "\v(...)" */
4365 if (s[x] != '\\') continue;
4366 if (s[x+1] == 'v') break;
4367 }
4368 if (x == y) {
4369 printf(
4370 "?Filter must contain a replacement variable for filename.\n"
4371 );
4372 x = -9;
4373 goto xsendx;
4374 }
4375 pv[n].ival = 1;
4376 if (pv[n].sval) {
4377 free(pv[n].sval);
4378 pv[n].sval = NULL;
4379 }
4380 if ((y = strlen(s)) > 0) {
4381 if ((pv[n].sval = malloc(y+1)))
4382 strcpy(pv[n].sval,s); /* safe */
4383 }
4384 break;
4385 #endif /* PIPESEND */
4386
4387 case SND_PTH: /* Pathnames */
4388 if (!getval) {
4389 pv[n].ival = PATH_REL;
4390 break;
4391 }
4392 if ((x = cmkey(pathtab,npathtab,"","absolute",xxstring)) < 0)
4393 goto xsendx;
4394 pv[n].ival = x;
4395 break;
4396
4397 case SND_NAM: /* Filenames */
4398 if (!getval) break;
4399 if ((x = cmkey(fntab,nfntab,"","converted",xxstring)) < 0)
4400 goto xsendx;
4401 debug(F101,"xsend /filenames","",x);
4402 pv[n].ival = x;
4403 break;
4404
4405 #ifdef CALIBRATE
4406 case SND_CAL: { /* /CALIBRATE */
4407 CK_OFF_T w;
4408 if (getval) {
4409 if ((x = cmnumw("number of Kbytes to send",
4410 "1024",10,&w,xxstring)) < 0)
4411 goto xsendx;
4412 } else
4413 w = (CK_OFF_T)1024;
4414 pv[n].wval = w;
4415 pv[SND_ARR].ival = 0;
4416 break;
4417 }
4418 #endif /* CALIBRATE */
4419
4420 case SND_FIL: /* Name of file containing filnames */
4421 if (!getval) break;
4422 if ((x = cmifi("Name of file containing list of filenames",
4423 "",&s,&y,xxstring)) < 0) {
4424 if (x == -3) {
4425 printf("?Filename required\n");
4426 x = -9;
4427 }
4428 goto xsendx;
4429 } else if (y) {
4430 printf("?Wildcards not allowed\n");
4431 x = -9;
4432 goto xsendx;
4433 }
4434 if (pv[n].sval)
4435 free(pv[n].sval);
4436 if (s) if (*s) {
4437 if ((pv[n].sval = malloc((int)strlen(s)+1))) {
4438 strcpy(pv[n].sval,s);
4439 pv[n].ival = 1;
4440 pv[SND_ARR].ival = 0;
4441 }
4442 }
4443 break;
4444
4445 #ifndef NOSPL
4446 case SND_ARR: /* SEND /ARRAY: */
4447 if (!getval) break;
4448 ap = NULL;
4449 if ((x = cmfld("Array name (a single letter will do)",
4450 "",
4451 &s,
4452 NULL
4453 )) < 0) {
4454 if (x == -3)
4455 break;
4456 else
4457 return(x);
4458 }
4459 if ((x = arraybounds(s,&(range[0]),&(range[1]))) < 0) {
4460 printf("?Bad array: %s\n",s);
4461 return(-9);
4462 }
4463 if (!(ap = a_ptr[x])) {
4464 printf("?No such array: %s\n",s);
4465 return(-9);
4466 }
4467 pv[n].ival = 1;
4468 pv[SND_CMD].ival = 0; /* Undo any conflicting ones... */
4469 pv[SND_RES].ival = 0;
4470 pv[SND_CAL].ival = 0;
4471 pv[SND_FIL].ival = 0;
4472 arrayx = x;
4473 break;
4474 #endif /* NOSPL */
4475
4476 case SND_XPA: /* /TRANSPARENT */
4477 pv[n].ival = 1;
4478 break;
4479
4480 case SND_TYP: /* Only files of given type */
4481 if (!getval) break;
4482 if ((x = cmkey(txtbin,3,"","all",xxstring)) < 0)
4483 goto xsendx;
4484 pv[n].ival = (x == 2) ? -1 : x;
4485 break;
4486
4487 default:
4488 printf("?Unexpected switch value - %d\n",cmresult.nresult);
4489 x = -9;
4490 goto xsendx;
4491 }
4492 }
4493 debug(F101,"xsend cmresult fcode","",cmresult.fcode);
4494
4495 #ifdef COMMENT
4496 /* List switch parsing results in debug log */
4497 for (i = 0; i <= SND_MAX; i++) {
4498 ckmakmsg(line,LINBUFSIZ,"xsend switch ",ckitoa(i),NULL,NULL);
4499 debug(F111,line, pv[i].sval, pv[i].ival);
4500 }
4501 #endif /* COMMENT */
4502
4503 /* Now we have all switches, plus maybe a filename or command, or nothing */
4504
4505 #ifdef PIPESEND
4506 if (protocol != PROTO_K && pv[SND_CMD].ival > 0) {
4507 printf("?Sorry, %s works only with Kermit protocol\n",
4508 (cx == XXCSEN) ? "CSEND" : "SEND /COMMAND");
4509 x = -9;
4510 goto xsendx;
4511 }
4512 if (pv[SND_RES].ival > 0 || /* /RECOVER */
4513 pv[SND_STA].wval > 0) { /* or /STARTING */
4514 if (sndfilter || pv[SND_FLT].ival > 0) {
4515 printf("?Sorry, no /RECOVER or /START if SEND FILTER selected\n");
4516 x = -9;
4517 goto xsendx;
4518 }
4519 }
4520 #endif /* PIPESEND */
4521
4522 cmarg = "";
4523 cmarg2 = "";
4524 line[0] = NUL;
4525 s = line;
4526 wild = 0;
4527
4528 switch (cmresult.fcode) { /* How did we get out of switch loop */
4529 case _CMIFI: /* Input filename */
4530 ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Name */
4531 if (pv[SND_ARR].ival > 0)
4532 cmarg2 = line;
4533 else
4534 wild = cmresult.nresult; /* Wild flag */
4535 if (!recursive && !wild)
4536 nolinks = 0;
4537 break;
4538 case _CMFLD: /* Field */
4539 /* Only allowed with /COMMAND and /ARRAY */
4540 if (pv[SND_CMD].ival < 1 && pv[SND_ARR].ival < 1) {
4541 #ifdef CKROOT
4542 if (ckrooterr)
4543 printf("?Off limits: %s\n",cmresult.sresult);
4544 else
4545 #endif /* CKROOT */
4546 printf("?%s - \"%s\"\n",
4547 iswild(cmresult.sresult) ?
4548 "No files match" : "File not found",
4549 cmresult.sresult
4550 );
4551 x = -9;
4552 goto xsendx;
4553 }
4554 ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
4555 if (pv[SND_ARR].ival > 0)
4556 cmarg2 = line;
4557 break;
4558 case _CMCFM: /* Confirmation */
4559 /* s = ""; */
4560 confirmed = 1;
4561 break;
4562 default:
4563 printf("?Unexpected function code: %d\n",cmresult.fcode);
4564 x = -9;
4565 goto xsendx;
4566 }
4567 debug(F110,"xsend string",s,0);
4568 debug(F101,"xsend confirmed","",confirmed);
4569
4570 /* Save and change protocol and transfer mode */
4571 /* Global values are restored in main parse loop */
4572
4573 g_proto = protocol; /* Save current global protocol */
4574 g_urpsiz = urpsiz;
4575 g_spsizf = spsizf;
4576 g_spsiz = spsiz;
4577 g_spsizr = spsizr;
4578 g_spmax = spmax;
4579 g_wslotr = wslotr;
4580 g_prefixing = prefixing;
4581 g_fncact = fncact;
4582 g_fncnv = fncnv;
4583 g_fnspath = fnspath;
4584 g_fnrpath = fnrpath;
4585 g_xfrxla = xfrxla;
4586
4587 if (pv[SND_PRO].ival > -1) { /* Change according to switch */
4588 protocol = pv[SND_PRO].ival;
4589 if (ptab[protocol].rpktlen > -1) /* copied from initproto() */
4590 urpsiz = ptab[protocol].rpktlen;
4591 if (ptab[protocol].spktflg > -1)
4592 spsizf = ptab[protocol].spktflg;
4593 if (ptab[protocol].spktlen > -1) {
4594 spsiz = ptab[protocol].spktlen;
4595 if (spsizf)
4596 spsizr = spmax = spsiz;
4597 }
4598 if (ptab[protocol].winsize > -1)
4599 wslotr = ptab[protocol].winsize;
4600 if (ptab[protocol].prefix > -1)
4601 prefixing = ptab[protocol].prefix;
4602 if (ptab[protocol].fnca > -1)
4603 fncact = ptab[protocol].fnca;
4604 if (ptab[protocol].fncn > -1)
4605 fncnv = ptab[protocol].fncn;
4606 if (ptab[protocol].fnsp > -1)
4607 fnspath = ptab[protocol].fnsp;
4608 if (ptab[protocol].fnrp > -1)
4609 fnrpath = ptab[protocol].fnrp;
4610 }
4611 debug(F101,"xsend protocol","",protocol);
4612
4613 if (pv[SND_NOB].ival > -1) { /* /NOBACKUP (skip backup file) */
4614 g_skipbup = skipbup;
4615 skipbup = 1;
4616 }
4617 if (pv[SND_REC].ival > 0) /* /RECURSIVE */
4618 recursive = 2;
4619
4620 if (pv[SND_TYP].ival > -1) { /* /TYPE */
4621 xfiletype = pv[SND_TYP].ival;
4622 if (xfiletype == 2)
4623 xfiletype = -1;
4624 }
4625 g_binary = binary; /* Save global transfer mode */
4626 #ifdef PATTERNS
4627 g_patterns = patterns; /* Save FILE PATTERNS setting */
4628 #endif /* PATTERNS */
4629 if (pv[SND_BIN].ival > 0) { /* Change according to switch */
4630 /* If they said /BINARY they mean /BINARY */
4631 patterns = 0; /* So no pattern-based switching */
4632 g_xfermode = xfermode; /* or automatic transfer mode */
4633 xfermode = XMODE_M;
4634 binary = XYFT_B;
4635 debug(F101,"doxsend /BINARY xfermode","",xfermode);
4636 } else if (pv[SND_TXT].ival > 0) { /* Ditto for /TEXT */
4637 patterns = 0;
4638 g_xfermode = xfermode;
4639 xfermode = XMODE_M;
4640 binary = XYFT_T;
4641 debug(F101,"doxsend /TEXT xfermode","",xfermode);
4642 } else if (pv[SND_IMG].ival > 0) {
4643 #ifdef VMS
4644 binary = XYFT_I;
4645 #else
4646 binary = XYFT_B;
4647 #endif /* VMS */
4648 }
4649 #ifdef CK_LABELED
4650 else if (pv[SND_LBL].ival > 0) {
4651 binary = XYFT_L;
4652 }
4653 #endif /* CK_LABELED */
4654 debug(F101,"xsend binary","",binary);
4655
4656 if (pv[SND_XPA].ival > 0) /* /TRANSPARENT */
4657 xfrxla = 0; /* Don't translate character sets */
4658
4659 /* Check for legal combinations of switches, filenames, etc */
4660
4661 #ifdef PIPESEND
4662 if (pv[SND_CMD].ival > 0) { /* COMMAND - strip any braces */
4663 debug(F110,"SEND /COMMAND before stripping",s,0);
4664 s = brstrip(s);
4665 debug(F110,"SEND /COMMAND after stripping",s,0);
4666 if (!*s) {
4667 printf("?Sorry, a command to send from is required\n");
4668 x = -9;
4669 goto xsendx;
4670 }
4671 cmarg = s;
4672 }
4673 #endif /* PIPESEND */
4674
4675 /* Set up /MOVE and /RENAME */
4676
4677 if (pv[SND_DEL].ival > 0 &&
4678 (pv[SND_MOV].ival > 0 || pv[SND_REN].ival > 0)) {
4679 printf("?Sorry, /DELETE conflicts with /MOVE or /RENAME\n");
4680 x = -9;
4681 goto xsendx;
4682 }
4683 #ifdef CK_TMPDIR
4684 if (pv[SND_MOV].ival > 0) {
4685 int len;
4686 char * p = pv[SND_MOV].sval;
4687 #ifdef CK_LOGIN
4688 if (isguest) {
4689 printf("?Sorry, /MOVE-TO not available to guests\n");
4690 x = -9;
4691 goto xsendx;
4692 }
4693 #endif /* CK_LOGIN */
4694 len = strlen(p);
4695 if (!isdir(p)) { /* Check directory */
4696 #ifdef CK_MKDIR
4697 char * s = NULL;
4698 s = (char *)malloc(len + 4);
4699 if (s) {
4700 strcpy(s,p); /* safe */
4701 #ifdef datageneral
4702 if (s[len-1] != ':') { s[len++] = ':'; s[len] = NUL; }
4703 #else
4704 if (s[len-1] != '/') { s[len++] = '/'; s[len] = NUL; }
4705 #endif /* datageneral */
4706 s[len++] = 'X';
4707 s[len] = NUL;
4708 x = zmkdir(s);
4709 free(s);
4710 if (x < 0) {
4711 printf("?Can't create \"%s\"\n",p);
4712 x = -9;
4713 goto xsendx;
4714 }
4715 }
4716 #else
4717 printf("?Directory \"%s\" not found\n",p);
4718 x = -9;
4719 goto xsendx;
4720 #endif /* CK_MKDIR */
4721 }
4722 zfnqfp(p,LINBUFSIZ,tmpbuf);
4723 makestr(&snd_move,tmpbuf);
4724 }
4725 #endif /* CK_TMPDIR */
4726
4727 if (pv[SND_REN].ival > 0) { /* /RENAME */
4728 char * p = pv[SND_REN].sval;
4729 #ifdef CK_LOGIN
4730 if (isguest) {
4731 printf("?Sorry, /RENAME-TO not available to guests\n");
4732 x = -9;
4733 goto xsendx;
4734 }
4735 #endif /* CK_LOGIN */
4736 if (!p) p = "";
4737 if (!*p) {
4738 printf("?New name required for /RENAME\n");
4739 x = -9;
4740 goto xsendx;
4741 }
4742 p = brstrip(p);
4743 #ifndef NOSPL
4744 /* If name given is wild, rename string must contain variables */
4745 if (wild) {
4746 char * s = tmpbuf;
4747 x = TMPBUFSIZ;
4748 zzstring(p,&s,&x);
4749 if (!strcmp(tmpbuf,p)) {
4750 printf(
4751 "?/RENAME for file group must contain variables such as \\v(filename)\n"
4752 );
4753 x = -9;
4754 goto xsendx;
4755 }
4756 }
4757 #endif /* NOSPL */
4758 makestr(&snd_rename,p);
4759 }
4760
4761 /* Handle /RECOVER and /START */
4762
4763 #ifdef CK_RESEND
4764 if (pv[SND_RES].ival > 0 && binary != XYFT_B && !filepeek
4765 #ifdef PATTERNS
4766 && !patterns
4767 #else
4768 #ifdef VMS
4769 /* VMS sets text/binary automatically later when it opens the file */
4770 && 0
4771 #endif /* VMS */
4772 #endif /* PATTERNS */
4773 ) {
4774 printf("?Sorry, /BINARY required\n");
4775 x = -9;
4776 goto xsendx;
4777 }
4778 if (pv[SND_STA].wval > 0) { /* /START */
4779 if (wild) {
4780 printf("?Sorry, wildcards not permitted with /START\n");
4781 x = -9;
4782 goto xsendx;
4783 }
4784 if (sizeof(int) < 4) {
4785 printf("?Sorry, this command needs at least 32-bit integers\n");
4786 x = -9;
4787 goto xsendx;
4788 }
4789 #ifdef CK_XYZ
4790 if (protocol != PROTO_K) {
4791 printf("?Sorry, SEND /START works only with Kermit protocol\n");
4792 x = -9;
4793 goto xsendx;
4794 }
4795 #endif /* CK_XYZ */
4796 }
4797 #ifdef CK_XYZ
4798 if (pv[SND_RES].ival > 0) {
4799 if (protocol != PROTO_K && protocol != PROTO_Z) {
4800 printf(
4801 "Sorry, /RECOVER is possible only with Kermit or ZMODEM protocol\n"
4802 );
4803 x = -9;
4804 goto xsendx;
4805 }
4806 }
4807 #endif /* CK_XYZ */
4808 #endif /* CK_RESEND */
4809
4810 if (protocol == PROTO_K) {
4811 if ((pv[SND_MAI].ival > 0 || /* MAIL */
4812 pv[SND_PRI].ival > 0 || /* PRINT */
4813 pv[SND_RES].ival > 0 /* RESEND */
4814 ) &&
4815 (!atdiso || !atcapr)) { /* Disposition attribute off? */
4816 printf("?Sorry, ATTRIBUTE DISPOSITION must be ON\n");
4817 x = -9;
4818 goto xsendx;
4819 }
4820 }
4821
4822 #ifdef CK_XYZ
4823 if (wild && (protocol == PROTO_X || protocol == PROTO_XC)) {
4824 printf(
4825 "Sorry, you can only send one file at a time with XMODEM protocol\n"
4826 );
4827 x = -9;
4828 goto xsendx;
4829 }
4830 #endif /* CK_XYZ */
4831
4832 if (!confirmed) { /* CR not typed yet, get more fields */
4833 char *m;
4834 if (mlist) { /* MSEND or MMOVE */
4835 nfils = 0; /* We already have the first one */
4836 #ifndef NOMSEND
4837 msfiles[nfils++] = line; /* Store pointer */
4838 lp = line + (int)strlen(line) + 1; /* Point past it */
4839 debug(F111,"xsend msend",msfiles[nfils-1],nfils-1);
4840 while (1) { /* Get more filenames */
4841 char *p;
4842 if ((x = cmifi("Names of files to send, separated by spaces",
4843 "", &s,&y,xxstring)) < 0) {
4844 if (x != -3)
4845 goto xsendx;
4846 if ((x = cmcfm()) < 0)
4847 goto xsendx;
4848 break;
4849 }
4850 msfiles[nfils++] = lp; /* Got one, count it, point to it, */
4851 p = lp; /* remember pointer, */
4852 while ((*lp++ = *s++)) /* and copy it into buffer */
4853 if (lp > (line + LINBUFSIZ)) { /* Avoid memory leak */
4854 printf("?MSEND list too long\n");
4855 line[0] = NUL;
4856 x = -9;
4857 goto xsendx;
4858 }
4859 debug(F111,"xsend msend",msfiles[nfils-1],nfils-1);
4860 if (nfils == 1) fspec[0] = NUL; /* Take care of \v(filespec) */
4861 #ifdef ZFNQFP
4862 zfnqfp(p,TMPBUFSIZ,tmpbuf);
4863 p = tmpbuf;
4864 #endif /* ZFNQFP */
4865 if (((int)strlen(fspec) + (int)strlen(p) + 1) < fspeclen) {
4866 strcat(fspec,p); /* safe */
4867 strcat(fspec," "); /* safe */
4868 } else
4869 #ifdef COMMENT
4870 printf("WARNING - \\v(filespec) buffer overflow\n");
4871 #else
4872 debug(F101,"doxsend filespec buffer overflow","",0);
4873 #endif /* COMMENT */
4874 }
4875 #endif /* NOMSEND */
4876 } else { /* Regular SEND */
4877 char *p; int y;
4878 nfils = -1;
4879 if (pv[SND_MAI].ival > 0)
4880 m = (pv[SND_MAI].sval) ?
4881 "e-mail address (optional)" :
4882 "e-mail address (required)";
4883 else if (pv[SND_PRI].ival > 0)
4884 m = "printer options (optional)";
4885 else if (wild)
4886 m =
4887 "\nOptional as-name template containing replacement variables \
4888 like \\v(filename)";
4889 else
4890 m = "Optional name to send it with";
4891 if ((x = cmtxt(m,"",&p,NULL)) < 0)
4892 goto xsendx;
4893 if (!p) p = "";
4894 if (*p) { /* If some text was given... */
4895 p = brstrip(p); /* Replace /AS-NAME: value if any */
4896 if ((y = strlen(p)) > 0) {
4897 if (pv[SND_MAI].ival > 0) {
4898 makestr(&pv[SND_MAI].sval, p);
4899 } else {
4900 if (pv[SND_ASN].sval) free(pv[SND_ASN].sval);
4901 pv[SND_ASN].sval = malloc(y+1);
4902 if (pv[SND_ASN].sval) {
4903 strcpy(pv[SND_ASN].sval,p); /* safe */
4904 pv[SND_ASN].ival = 1;
4905 }
4906 }
4907 }
4908 }
4909 }
4910 }
4911 /* Set cmarg2 from as-name, however we got it. */
4912
4913 if (pv[SND_ASN].ival > 0 && pv[SND_ASN].sval && !*cmarg2) {
4914 int x;
4915 x = strlen(line);
4916 ckstrncpy(line+x+2,pv[SND_ASN].sval,LINBUFSIZ-x-1);
4917 cmarg2 = line+x+2;
4918 debug(F110,"doxsend cmarg2",cmarg2,0);
4919 }
4920
4921 #ifndef NOFRILLS
4922 if ((pv[SND_MAI].ival > 0) && (pv[SND_PRI].ival > 0)) {
4923 printf("Sorry, /MAIL and /PRINT are conflicting options\n");
4924 x = -9;
4925 goto xsendx;
4926 }
4927 n = 0; /* /MAIL or /PRINT? */
4928 if (pv[SND_MAI].ival > 0)
4929 n = SND_MAI;
4930 else if (pv[SND_PRI].ival > 0)
4931 n = SND_PRI;
4932 if (n) { /* Yes... */
4933 #ifdef DEBUG
4934 char * p;
4935 if (n == SND_MAI)
4936 p = "/MAIL";
4937 else
4938 p = "/PRINT";
4939 debug(F111,"xsend",p,n);
4940 #endif /* DEBUG */
4941 #ifdef CK_XYZ
4942 if (protocol != PROTO_K) {
4943 printf("Sorry, %s available only with Kermit protocol\n",
4944 (n == SND_MAI) ? "/MAIL" : "/PRINT"
4945 );
4946 x = -9;
4947 goto xsendx;
4948 }
4949 #endif /* CK_XYZ */
4950 debug(F101,"xsend print/mail wild","",wild);
4951 *optbuf = NUL; /* Wipe out any old options */
4952 s = pv[n].sval; /* mail address or print switch val */
4953 if (!s) s = "";
4954 debug(F110,"doxsend mail address or printer options",s,0);
4955 if (n == SND_MAI && !*s) {
4956 printf("?E-mail address required\n");
4957 x = -9;
4958 goto xsendx;
4959 } else if ((int)strlen(s) > 94) { /* Ensure legal size */
4960 printf("?%s too long\n",
4961 (n == SND_MAI) ?
4962 "E-mail address" :
4963 "Print option string"
4964 );
4965 x = -9;
4966 goto xsendx;
4967 }
4968 ckstrncpy(optbuf,s,OPTBUFLEN); /* OK, copy to option buffer */
4969 cmarg = line; /* File to send */
4970 if (n == SND_MAI) {
4971 debug(F110,"xsend mailing",cmarg,0);
4972 debug(F110,"xsend address:",optbuf,0);
4973 rmailf = 1;
4974 } else {
4975 debug(F110,"xsend printing",cmarg,0);
4976 debug(F110,"xsend options",optbuf,0);
4977 rprintf = 1;
4978 }
4979 }
4980 #endif /* NOFRILLS */
4981
4982 #ifdef CALIBRATE
4983 if (pv[SND_CAL].wval > 0) { /* Handle /CALIBRATE */
4984 if (confirmed) {
4985 calibrate = pv[SND_CAL].wval * (CK_OFF_T)1024;
4986 sndsrc = -9;
4987 nfils = 1;
4988 wild = 0;
4989 #ifndef NOMSEND
4990 addlist = 0;
4991 #endif /* NOMSEND */
4992 ckstrncpy(line,"CALIBRATION",LINBUFSIZ);
4993 s = cmarg = line;
4994 if (!cmarg2) cmarg2 = "";
4995 debug(F110,"doxsend cmarg2 calibrate",cmarg2,0);
4996 } else if (line[0]) {
4997 calibrate = 0;
4998 pv[SND_CAL].ival = 0;
4999 pv[SND_CAL].wval = 0;
5000 }
5001 }
5002 #endif /* CALIBRATE */
5003
5004 if (pv[SND_FIL].ival > 0) {
5005 if (confirmed && !calibrate) {
5006 if (zopeni(ZMFILE,pv[SND_FIL].sval) < 1) {
5007 debug(F110,"xsend can't open",pv[SND_FIL].sval,0);
5008 printf("?Failure to open %s\n",filefile);
5009 x = -9;
5010 goto xsendx;
5011 }
5012 makestr(&filefile,pv[SND_FIL].sval); /* Open, remember name */
5013 debug(F110,"xsend opened",filefile,0);
5014 wild = 1;
5015 }
5016 }
5017
5018 /* SEND alone... */
5019
5020 #ifndef NOSPL
5021 if (confirmed && pv[SND_ARR].ival > 0) {
5022 if (!*cmarg2) {
5023 sndxnam[7] = (char)((arrayx == 1) ? 64 : arrayx + ARRAYBASE);
5024 cmarg2 = sndxnam;
5025 }
5026 cmarg = "";
5027 goto sendend;
5028 }
5029 #endif /* NOSPL */
5030
5031 if (confirmed && !line[0] && !filefile && !calibrate) {
5032 #ifndef NOMSEND
5033 if (filehead) { /* OK if we have a SEND-LIST */
5034 nfils = filesinlist;
5035 sndsrc = nfils; /* Like MSEND */
5036 addlist = 1; /* But using a different list... */
5037 filenext = filehead;
5038 goto sendend;
5039 }
5040 #endif /* NOMSEND */
5041 printf("?Filename required but not given\n");
5042 x = -9;
5043 goto xsendx;
5044 }
5045
5046 /* Not send-list or array */
5047
5048 #ifndef NOMSEND
5049 addlist = 0; /* Don't use SEND-LIST. */
5050 filenext = NULL;
5051 #endif /* NOMSEND */
5052
5053 if (mlist) { /* MSEND or MMOVE */
5054 #ifndef NOMSEND
5055 cmlist = msfiles; /* List of files to send */
5056 sndsrc = nfils;
5057 cmarg2 = "";
5058 sendstart = (CK_OFF_T)0;
5059 #endif /* NOMSEND */
5060 #ifdef PIPESEND
5061 pipesend = 0;
5062 #endif /* PIPESEND */
5063 } else if (filefile) { /* File contains list of filenames */
5064 s = "";
5065 cmarg = "";
5066 cmarg2 = "";
5067 line[0] = NUL;
5068 nfils = 1;
5069 sndsrc = 1;
5070
5071 } else if (!calibrate && pv[SND_ARR].ival < 1 && pv[SND_CMD].ival < 1) {
5072
5073 nfils = sndsrc = -1; /* Not MSEND, MMOVE, /LIST, or /ARRAY */
5074 if ( /* or /COMMAND */
5075
5076 #ifndef NOFRILLS
5077 !rmailf && !rprintf /* Not MAIL or PRINT */
5078 #else
5079 1
5080 #endif /* NOFRILLS */
5081 ) {
5082 CK_OFF_T y = (CK_OFF_T)1;
5083 if (!wild)
5084 y = zchki(s);
5085 if (y < (CK_OFF_T)0) {
5086 printf("?Read access denied - \"%s\"\n", s);
5087 x = -9;
5088 goto xsendx;
5089 }
5090 if (s != line) /* We might already have done this. */
5091 ckstrncpy(line,s,LINBUFSIZ); /* Copy of string just parsed. */
5092 else
5093 debug(F110,"doxsend line=s",line,0);
5094 cmarg = line; /* File to send */
5095 }
5096 zfnqfp(cmarg,fspeclen,fspec);
5097 }
5098 if (!mlist) { /* For all but MSEND... */
5099 #ifdef PIPESEND
5100 if (pv[SND_CMD].ival > 0) /* /COMMAND sets pipesend flag */
5101 pipesend = 1;
5102 debug(F101,"xsend /COMMAND pipesend","",pipesend);
5103 if (pipesend && filefile) {
5104 printf("?Invalid switch combination\n");
5105 x = -9;
5106 goto xsendx;
5107 }
5108 #endif /* PIPESEND */
5109
5110 #ifndef NOSPL
5111 /* If as-name given and filespec is wild, as-name must contain variables */
5112 debug(F111,"doxsend cmarg2 wild",cmarg2,wild);
5113 if (wild && *cmarg2) {
5114 char * s = tmpbuf;
5115 x = TMPBUFSIZ;
5116 zzstring(cmarg2,&s,&x);
5117 if (!strcmp(tmpbuf,cmarg2)) {
5118 printf(
5119 "?As-name for file group must contain variables such as \\v(filename)\n"
5120 );
5121 x = -9;
5122 goto xsendx;
5123 }
5124 }
5125 #endif /* NOSPL */
5126
5127 /* Strip braces from as-name */
5128 debug(F110,"xsend cmarg2 before stripping",cmarg2,0);
5129 cmarg2 = brstrip(cmarg2);
5130 debug(F110,"xsend filename",cmarg,0);
5131 debug(F110,"xsend as-name",cmarg2,0);
5132
5133 /* Copy as-name to a safe place */
5134
5135 if (asnbuf) {
5136 free(asnbuf);
5137 asnbuf = NULL;
5138 }
5139 if ((y = strlen(cmarg2)) > 0) {
5140 asnbuf = (char *) malloc(y + 1);
5141 if (asnbuf) {
5142 strcpy(asnbuf,cmarg2); /* safe */
5143 cmarg2 = asnbuf;
5144 } else cmarg2 = "";
5145 }
5146
5147 #ifdef CK_RESEND
5148 debug(F111,"xsend pv[SND_STA].ival","",pv[SND_STA].ival);
5149 if (pv[SND_STA].wval > (CK_OFF_T)-1) { /* /START position */
5150 if (wild) {
5151 printf("?/STARTING-AT may not be used with multiple files.\n");
5152 x = -9;
5153 goto xsendx;
5154 } else
5155 sendstart = pv[SND_STA].wval;
5156 } else
5157 sendstart = (CK_OFF_T)0;
5158 debug(F101,"xsend /STARTING","",sendstart);
5159 #endif /* CK_RESEND */
5160 }
5161
5162 sendend: /* Common successful exit */
5163 moving = 0;
5164 if (pv[SND_SHH].ival > 0) { /* SEND /QUIET... */
5165 g_displa = fdispla;
5166 fdispla = 0;
5167 debug(F101,"xsend display","",fdispla);
5168 }
5169
5170 #ifndef NOSPL /* SEND /ARRAY... */
5171 if (pv[SND_ARR].ival > 0) {
5172 if (!ap) { x = -2; goto xsendx; } /* (shouldn't happen) */
5173 if (range[0] == -1) /* If low end of range not specified */
5174 range[0] = 1; /* default to 1 */
5175 if (range[1] == -1) /* If high not specified */
5176 range[1] = a_dim[arrayx]; /* default to size of array */
5177 if ((range[0] < 0) || /* Check range */
5178 (range[0] > a_dim[arrayx]) ||
5179 (range[1] < range[0]) ||
5180 (range[1] > a_dim[arrayx])) {
5181 printf("?Bad array range - [%d:%d]\n",range[0],range[1]);
5182 x = -9;
5183 goto xsendx;
5184 }
5185 sndarray = ap; /* Array pointer */
5186 sndxin = arrayx; /* Array index */
5187 sndxlo = range[0]; /* Array range */
5188 sndxhi = range[1];
5189 sndxnam[7] = (char)((sndxin == 1) ? 64 : sndxin + ARRAYBASE);
5190
5191 #ifdef COMMENT
5192 printf("SENDING FROM ARRAY: &%c[]...\n", /* debugging */
5193 (sndxin == 1) ? 64 : sndxin + ARRAYBASE);
5194 printf("Lo=%d\nHi=%d\n", sndxlo, sndxhi);
5195 printf("cmarg=[%s]\ncmarg2=[%s]\n", cmarg, cmarg2);
5196 while ((x = agnbyte()) > -1) {
5197 putchar((char)x);
5198 }
5199 return(1);
5200 #endif /* COMMENT */
5201 }
5202 #endif /* NOSPL */
5203
5204 if (pv[SND_ARR].ival < 1) { /* File selection & disposition... */
5205
5206 if (pv[SND_DEL].ival > 0) /* /DELETE was specified */
5207 moving = 1;
5208 debug(F101,"xsend /DELETE","",moving);
5209 if (pv[SND_AFT].ival > 0) /* Copy SEND criteria */
5210 ckstrncpy(sndafter,pv[SND_AFT].sval,19);
5211 if (pv[SND_BEF].ival > 0)
5212 ckstrncpy(sndbefore,pv[SND_BEF].sval,19);
5213 if (pv[SND_NAF].ival > 0)
5214 ckstrncpy(sndnafter,pv[SND_NAF].sval,19);
5215 if (pv[SND_NBE].ival > 0)
5216 ckstrncpy(sndnbefore,pv[SND_NBE].sval,19);
5217 if (pv[SND_EXC].ival > 0)
5218 makelist(pv[SND_EXC].sval,sndexcept,NSNDEXCEPT);
5219 if (pv[SND_SMA].wval > (CK_OFF_T)-1)
5220 sndsmaller = pv[SND_SMA].wval;
5221 if (pv[SND_LAR].wval > (CK_OFF_T)-1)
5222 sndlarger = pv[SND_LAR].wval;
5223 if (pv[SND_NAM].ival > -1) {
5224 g_fncnv = fncnv; /* Save global value */
5225 fncnv = pv[SND_NAM].ival;
5226 debug(F101,"xsend fncnv","",fncnv);
5227 }
5228 if (pv[SND_PTH].ival > -1) {
5229 g_spath = fnspath; /* Save global values */
5230 fnspath = pv[SND_PTH].ival;
5231 #ifndef NZLTOR
5232 if (fnspath != PATH_OFF) {
5233 g_fncnv = fncnv; /* Bad bad... */
5234 fncnv = XYFN_C;
5235 }
5236 #endif /* NZLTOR */
5237 debug(F101,"xsend fnspath","",fnspath);
5238 debug(F101,"xsend fncnv","",fncnv);
5239 }
5240 }
5241
5242 #ifdef PIPESEND
5243 if (pv[SND_FLT].ival > 0) {
5244 makestr(&sndfilter,pv[SND_FLT].sval);
5245 debug(F110,"xsend /FILTER", sndfilter, 0);
5246 }
5247 #endif /* PIPESEND */
5248
5249 #ifdef CK_APC
5250 /* MOVE not allowed in APCs */
5251 if (moving &&
5252 (apcactive == APC_LOCAL || apcactive == APC_REMOTE)
5253 && !(apcstatus & APC_UNCH))
5254 return(success = 0);
5255 #endif /* CK_APC */
5256 #ifdef IKS_OPTION
5257 if (
5258 #ifdef CK_XYZ
5259 protocol == PROTO_K &&
5260 #endif /* CK_XYZ */
5261 !iks_wait(KERMIT_REQ_START,1)) {
5262 printf("?A Kermit Server is not available to process this command.\n");
5263 printf("?Start a RECEIVE command to complement this command.\n");
5264 }
5265 #endif /* IKS_OPTION */
5266
5267 #ifdef IKSD
5268 #ifdef CK_LOGIN
5269 if (moving && inserver && isguest) {
5270 printf("?File deletion not allowed for guests.\n");
5271 return(-9);
5272 }
5273 #endif /* CK_LOGIN */
5274 #endif /* IKSD */
5275
5276 sstate = 's'; /* Set start state to SEND */
5277 sndcmd = 1;
5278 #ifdef CK_RESEND
5279 if (pv[SND_RES].ival > 0) /* Send sendmode appropriately */
5280 sendmode = SM_RESEND;
5281 else if (pv[SND_STA].ival > 0)
5282 sendmode = SM_PSEND;
5283 else
5284 #endif /* CK_RESEND */
5285 if (mlist)
5286 sendmode = SM_MSEND;
5287 else
5288 sendmode = SM_SEND;
5289 #ifdef MAC
5290 what = W_SEND;
5291 scrcreate();
5292 #endif /* MAC */
5293 if (local && pv[SND_SHH].ival != 0) { /* If in local mode, */
5294 displa = 1; /* turn on file transfer display */
5295 }
5296 x = 0;
5297
5298 xsendx: /* Common exit, including failure */
5299 debug(F101,"doxsend sndsrc","",sndsrc);
5300 for (i = 0; i <= SND_MAX; i++) { /* Free malloc'd memory */
5301 if (pv[i].sval)
5302 free(pv[i].sval);
5303 }
5304 return(x);
5305 }
5306 #endif /* NOXFER */
5307
5308 #ifndef NOLOCAL
5309 /* D O X C O N N -- CONNECT command parsing with switches */
5310
5311 #ifdef XLIMITS
5312 #define XLIMORTRIGGER
5313 #else
5314 #ifdef CK_TRIGGER
5315 #define XLIMORTRIGGER
5316 #endif /* CK_TRIGGER */
5317 #endif /* XLIMITS */
5318
5319 #ifdef CKTIDLE
5320 int tt_idlelimit = 0; /* Terminal idle limit */
5321 int tt_idleact = IDLE_RET; /* Terminal idle action */
5322 #endif /* CKTIDLE */
5323
5324 #ifdef OS2 /* K95 only: */
5325 extern int
5326 tt_idlesnd_tmo; /* Idle interval */
5327 int tt_timelimit = 0; /* Time limit, 0 = none */
5328 extern char * /* Parse results - strings: */
5329 tt_idlesnd_str; /* Idle string */
5330 #endif /* OS2 */
5331
5332 #ifdef CK_TRIGGER
5333 extern char *tt_trigger[];
5334 extern CHAR *tt_trmatch[];
5335 extern char *triggerval;
5336 static char *g_tt_trigger[TRIGGERS];
5337 #endif /* CK_TRIGGER */
5338
5339 #ifdef OS2
5340 static int g_tt_idlesnd_tmo, g_tt_timelimit; /* For saving and restoring */
5341 static int g_tt_idlelimit, g_tt_saved = 0;
5342 static char * g_tt_idlesnd_str; /* global settings */
5343 #endif /* OS2 */
5344
5345 static struct stringint pv[CONN_MAX+1];
5346
5347 VOID
resconn()5348 resconn() {
5349 int i;
5350
5351 #ifdef OS2
5352 if ( g_tt_saved ) {
5353 tt_idlelimit = g_tt_idlelimit;
5354 tt_idlesnd_tmo = g_tt_idlesnd_tmo;
5355 tt_timelimit = g_tt_timelimit;
5356 tt_idlesnd_str = g_tt_idlesnd_str;
5357 g_tt_saved = 0;
5358 }
5359 #endif /* OS2 */
5360
5361 #ifdef CK_TRIGGER
5362 for (i = 0; i < TRIGGERS; i++)
5363 tt_trigger[i] = g_tt_trigger[i];
5364 #endif /* CK_TRIGGER */
5365
5366 for (i = 0; i <= CONN_MAX; i++) { /* Free malloc'd memory */
5367 if (pv[i].sval)
5368 free(pv[i].sval);
5369 pv[i].sval = NULL;
5370 }
5371 }
5372
5373 int
doxconn(cx)5374 doxconn(cx) int cx; {
5375 int c, i, n; /* Workers */
5376 int x, y;
5377 int getval = 0; /* Whether to get switch value */
5378 int async = 0; /* Make an async connect */
5379 struct FDB sw, cm; /* FDBs for each parse function */
5380 extern FILE * tfile[];
5381 extern char * macp[];
5382
5383 #ifdef OS2
5384 g_tt_idlesnd_tmo = tt_idlesnd_tmo; /* Save global settings */
5385 g_tt_timelimit = tt_timelimit;
5386 g_tt_idlelimit = tt_idlelimit;
5387 g_tt_idlesnd_str = tt_idlesnd_str;
5388 g_tt_saved = 1;
5389 #endif /* OS2 */
5390
5391 #ifdef CK_TRIGGER
5392 if (!tt_trigger[0]) { /* First initialization */
5393 for (i = 1; i < TRIGGERS; i++)
5394 tt_trigger[i] = NULL;
5395 }
5396 for (i = 0; i < TRIGGERS; i++)
5397 g_tt_trigger[i] = tt_trigger[i];
5398 if (triggerval) {
5399 free(triggerval);
5400 triggerval = NULL;
5401 }
5402 #endif /* CK_TRIGGER */
5403
5404 for (i = 0; i <= CONN_MAX; i++) { /* Initialize switch values */
5405 pv[i].sval = NULL; /* to null pointers */
5406 pv[i].ival = -1; /* and -1 int values */
5407 pv[i].wval = (CK_OFF_T)-1;
5408 }
5409 if (cx == XXCQ) /* CQ == CONNECT /QUIETLY */
5410 pv[CONN_NV].ival = 1;
5411
5412 /* Set up chained parse functions... */
5413
5414 cmfdbi(&sw, /* First FDB - command switches */
5415 _CMKEY, /* fcode */
5416 "Switch", /* hlpmsg */
5417 "", /* default */
5418 "", /* addtl string data */
5419 nconntab, /* addtl numeric data 1: tbl size */
5420 4, /* addtl numeric data 2: 4 = cmswi */
5421 xxstring, /* Processing function */
5422 conntab, /* Keyword table */
5423 &cm /* Pointer to next FDB */
5424 );
5425 cmfdbi(&cm, /* 2nd FDB - Confirmation */
5426 _CMCFM, /* fcode */
5427 "", /* hlpmsg */
5428 "", /* default */
5429 "", /* addtl string data */
5430 0, /* addtl numeric data 1 */
5431 0, /* addtl numeric data 2 */
5432 NULL,
5433 NULL,
5434 NULL
5435 );
5436
5437 while (1) { /* Parse 0 or more switches */
5438 x = cmfdb(&sw); /* Parse switch or confirmation */
5439 debug(F101,"doxconn cmfdb","",x);
5440 if (x < 0) { /* Error */
5441 if (x == -9 || x == -2)
5442 printf("?No switches match - \"%s\"\n",atmbuf);
5443 goto xconnx; /* or reparse needed */
5444 }
5445 if (cmresult.fcode != _CMKEY) /* Break out if not a switch */
5446 break;
5447 c = cmgbrk(); /* Get break character */
5448 getval = (c == ':' || c == '='); /* to see how they ended the switch */
5449 if (getval && !(cmresult.kflags & CM_ARG)) {
5450 printf("?This switch does not take arguments\n");
5451 x = -9;
5452 goto xconnx;
5453 }
5454 if (!getval && (cmgkwflgs() & CM_ARG)) {
5455 printf("?This switch requires an argument\n");
5456 return(-9);
5457 }
5458 n = cmresult.nresult; /* Numeric result = switch value */
5459 debug(F101,"doxconn switch","",n);
5460
5461 switch (n) { /* Process the switch */
5462 #ifdef OS2
5463 case CONN_AS: /* Asynchronous */
5464 pv[CONN_AS].ival = 1;
5465 pv[CONN_SY].ival = 0;
5466 break;
5467 case CONN_SY: /* Synchronous */
5468 pv[CONN_SY].ival = 1;
5469 pv[CONN_AS].ival = 0;
5470 break;
5471 #endif /* OS2 */
5472 case CONN_NV: /* Non-verbal */
5473 pv[n].ival = 1;
5474 break;
5475 #ifdef XLIMITS
5476 case CONN_II: /* Idle-interval */
5477 case CONN_IL: /* Idle-limit */
5478 case CONN_TL: /* Time-limit */
5479 if (!getval) break;
5480 if ((x = cmnum("Seconds","0",10,&y,xxstring)) < 0)
5481 goto xconnx;
5482 pv[n].ival = y;
5483 break;
5484 case CONN_IS: /* Idle-string */
5485 #endif /* XLIMITS */
5486 #ifdef CK_TRIGGER
5487 case CONN_TS: /* Trigger-string */
5488 #endif /* CK_TRIGGER */
5489 #ifdef XLIMORTRIGGER
5490 if (!getval) break;
5491 if ((x = cmfld("String (enclose in braces if it contains spaces)",
5492 "",&s,xxstring)) < 0) {
5493 if (x == -3) {
5494 printf("?String required\n");
5495 x = -9;
5496 }
5497 goto xconnx;
5498 }
5499 if (n != CONN_TS)
5500 s = brstrip(s);
5501 if ((y = strlen(s)) > 0) {
5502 if (pv[n].sval) free(pv[n].sval);
5503 pv[n].sval = malloc(y+1);
5504 if (pv[n].sval) {
5505 strcpy(pv[n].sval,s); /* safe */
5506 pv[n].ival = 1;
5507 }
5508 }
5509 break;
5510 #endif /* XLIMORTRIGGER */
5511 default:
5512 printf("?Unexpected switch value - %d\n",cmresult.nresult);
5513 x = -9;
5514 goto xconnx;
5515 }
5516 }
5517 debug(F101,"doxconn cmresult.fcode","",cmresult.fcode);
5518 if (cmresult.fcode != _CMCFM) {
5519 printf("?Unexpected function code: %d\n",cmresult.fcode);
5520 x = -9;
5521 goto xconnx;
5522 }
5523
5524 /* Command was confirmed so we can pre-pop command level. */
5525 /* This is so CONNECT module won't think we're executing a script */
5526 /* if CONNECT was the final command in the script. */
5527
5528 if (cmdlvl > 0)
5529 prepop();
5530
5531 #ifdef OS2 /* Make results available globally */
5532 if (pv[CONN_IL].ival > -1) /* Idle limit */
5533 tt_idlelimit = pv[CONN_IL].ival;
5534 if (pv[CONN_II].ival > -1) /* Idle limit */
5535 tt_idlesnd_tmo = pv[CONN_II].ival;
5536 if (pv[CONN_IS].sval) /* Idle string */
5537 if (tt_idlesnd_str = (char *)malloc((int)strlen(pv[CONN_IS].sval)+1))
5538 strcpy(tt_idlesnd_str,pv[CONN_IS].sval); /* safe */
5539 if (pv[CONN_TL].ival > -1) /* Session limit */
5540 tt_timelimit = pv[CONN_TL].ival;
5541 async = (pv[CONN_AS].ival > 0 ||
5542 pv[CONN_SY].ival <= 0 && cmdlvl == 0) ? 1 : 0;
5543 #endif /* OS2 */
5544
5545 #ifdef CK_TRIGGER
5546 if (pv[CONN_TS].sval) /* Trigger strings */
5547 makelist(pv[CONN_TS].sval,tt_trigger,TRIGGERS);
5548 for (i = 0; i < TRIGGERS; i++) /* Trigger match pointers */
5549 tt_trmatch[i] = NULL;
5550 if (triggerval) { /* Reset trigger value */
5551 free(triggerval);
5552 triggerval = NULL;
5553 }
5554 #endif /* CK_TRIGGER */
5555
5556 #ifdef SSHCMD
5557 /*
5558 2010/03/01...
5559 The previous connection was through the external ssh client and now, with
5560 that connection closed, the user says "connect" and expects a new connection
5561 to be made to the same host, because that's how all the other connection
5562 methods work, so (and this is quite a hack)...
5563 */
5564 if (!ckstrcmp("ssh ",ttname,4,0)) { /* Previous "host" was "ssh blah" */
5565 _PROTOTYP (int redossh, ( void ) );
5566 extern int ttyfd;
5567 if (ttyfd < 0) { /* And connection is no longer open */
5568 int xx;
5569 xx = redossh(); /* So redo the SSH connection */
5570 if (xx < 0) return(xx);
5571 goto xconnx;
5572 }
5573 }
5574 #endif /* SSHCMD */
5575 x = doconect((pv[CONN_NV].ival > 0) ? 1 : 0, async);
5576 {
5577 int xx;
5578 debug(F101,"doxconn doconect returns","",x);
5579 if ((xx = ttchk()) < 0) dologend();
5580 debug(F101,"doxconn ttchk returns","",xx);
5581 }
5582
5583 #ifdef CK_TRIGGER
5584 debug(F111,"doxconn doconect triggerval",triggerval,x);
5585 #endif /* CK_TRIGGER */
5586
5587 xconnx:
5588 /* Back from CONNECT -- Restore global settings */
5589
5590 if (!async)
5591 resconn();
5592
5593 success = (x > 0) ? 1 : 0;
5594 return(x);
5595 }
5596 #endif /* NOLOCAL */
5597
5598 #ifdef ADDCMD
5599 /* cx == XXADD or XXREMV */
5600 /* fc == ADD_BIN or ADD_TXT */
5601 static int
doadd(cx,fc)5602 doadd(cx,fc) int cx, fc; {
5603 #ifdef PATTERNS
5604 char * tmp[FTPATTERNS];
5605 char **p = NULL;
5606 int i, j, k, n = 0, x = 0, last;
5607
5608 #endif /* PATTERNS */
5609 if (cx != XXADD && cx != XXREMV) {
5610 printf("?Unexpected function code: %d\n",cx);
5611 return(-9);
5612 }
5613 #ifdef PATTERNS
5614 while (n < FTPATTERNS) { /* Collect new patterns */
5615 tmp[n] = NULL;
5616 if ((x = cmfld("Pattern","",&s,xxstring)) < 0)
5617 break;
5618 ckstrncpy(line,s,LINBUFSIZ);
5619 s = brstrip(line);
5620 makestr(&(tmp[n++]),s);
5621 }
5622 if (x == -3)
5623 x = cmcfm();
5624 if (x < 0)
5625 goto xdoadd;
5626 p = (fc == ADD_BIN) ? binpatterns : txtpatterns; /* Which list */
5627 last = 0;
5628 for (i = 0; i < FTPATTERNS; i++) { /* Find last one in list */
5629 if (!p[i]) {
5630 last = i;
5631 break;
5632 }
5633 }
5634 if (cx == XXADD) { /* Adding */
5635 if (last + n > FTPATTERNS) { /* Check if too many */
5636 printf("?Too many patterns - %d is the maximum\n", FTPATTERNS);
5637 goto xdoadd;
5638 }
5639 for (i = 0; i < n; i++) { /* Copy in the new ones. */
5640 for (j = 0, x = 0; x == 0 && j < last ; j++ )
5641 x = !ckstrcmp(tmp[i],p[j],-1,filecase); /* match */
5642 if (x == 0)
5643 makestr(&(p[last++]),tmp[i]);
5644 }
5645 makestr(&(p[last]),NULL); /* Null-terminate the list */
5646 x = 1;
5647 goto xdoadd; /* Done */
5648 } else if (cx == XXREMV) { /* Remove something(s) */
5649 int j, k;
5650 if (last == 0) /* List is empty */
5651 goto xdoadd; /* Nothing to remove */
5652 for (i = 0; i < n; i++) { /* i = Patterns they typed */
5653 for (j = 0; j < last; j++) { /* j = Patterns in list */
5654 /* Change this to ckstrcmp()... */
5655 if (filecase)
5656 x = !ckstrcmp(tmp[i],p[j],-1,filecase); /* match */
5657 else
5658 x = ckstrcmp(tmp[i],p[j],-1,0); /* Case-independent match */
5659 if (x) { /* This one matches */
5660 makestr(&(p[j]),NULL); /* Free it */
5661 for (k = j; k < last; k++) /* Move the rest up */
5662 p[k] = p[k+1];
5663 p[k] = NULL; /* Erase last one */
5664 if (!p[k])
5665 break;
5666 }
5667 }
5668 }
5669 }
5670 xdoadd: /* Common exit */
5671 for (i = 0; i < n; i++)
5672 if (tmp[i])
5673 free(tmp[i]);
5674 return(x);
5675 #endif /* PATTERNS */
5676 }
5677
5678 /* ADD SEND-LIST */
5679
5680 static int
addsend(cx)5681 addsend(cx) int cx; {
5682 #ifndef NOMSEND
5683 extern struct keytab fttab[];
5684 extern int nfttyp;
5685 struct filelist * flp;
5686 char * fmode = "";
5687 int xmode = 0;
5688 int xbinary = 0;
5689 #endif /* NOMSEND */
5690
5691 #ifdef NOMSEND
5692 printf("?Sorry, ADD/REMOVE SEND-LIST not available.\n");
5693 return(-9);
5694 #endif /* NOMSEND */
5695 if (cx == XXREMV) {
5696 printf("?Sorry, REMOVE SEND-LIST not implemented yet.\n");
5697 return(-9);
5698 }
5699 #ifndef NOMSEND
5700 #ifndef XYZ_INTERNAL
5701 if (protocol != PROTO_K) {
5702 printf("?Sorry, ADD SEND-LIST does not work with external protocols\n");
5703 return(-9);
5704 }
5705 #endif /* XYZ_INTERNAL */
5706
5707 x = cmifi("File specification to add","", &s,&y,xxstring);
5708 if (x < 0) {
5709 if (x == -3) {
5710 printf("?A file specification is required\n");
5711 return(-9);
5712 } else
5713 return(x);
5714 }
5715 ckstrncpy(tmpbuf,s,TMPBUFSIZ);
5716 s = tmpbuf;
5717 if (filesinlist == 0) /* Take care of \v(filespec) */
5718 fspec[0] = NUL;
5719 zfnqfp(s,LINBUFSIZ,line);
5720 s = line;
5721 if (((int)strlen(fspec) + (int)strlen(s) + 1) < fspeclen) {
5722 strcat(fspec,s); /* safe */
5723 strcat(fspec," "); /* safe */
5724 } else
5725 printf("WARNING - \\v(filespec) buffer overflow\n");
5726
5727
5728 xbinary = binary;
5729 if ((patterns || filepeek) /* FILE PATTERNS or SCAN is ON */
5730 #ifdef CK_LABELED
5731 && binary != XYFT_L /* And not if FILE TYPE LABELED */
5732 #endif /* CK_LABELED */
5733 #ifdef VMS
5734 && binary != XYFT_I /* or FILE TYPE IMAGE */
5735 #endif /* VMS */
5736 ) {
5737 int k, x;
5738 x = -1;
5739 k = scanfile(line,&x,nscanfile);
5740 if (k > 0) xbinary = (k == FT_BIN) ? XYFT_B : XYFT_T;
5741 }
5742 fmode = gfmode(xbinary,0);
5743 if ((x = cmkey(fttab,nfttyp,
5744 "type of file transfer", fmode, xxstring)) < 0)
5745 return(x);
5746 xmode = x;
5747
5748 cmarg2 = "";
5749 if ((x = cmfld(y ?
5750 "\nAs-name template containing replacement variables such as \\v(filename)" :
5751 "Name to send it with", "",&s,NULL)) < 0)
5752 if (x != -3)
5753 return(x);
5754 #ifndef NOSPL
5755 if (y && *s) {
5756 char * p = tmpbuf;
5757 x = TMPBUFSIZ;
5758 zzstring(s,&p,&x);
5759 if (!strcmp(tmpbuf,s)) {
5760 printf(
5761 "?As-name for file group must contain variables such as \\v(filename)\n"
5762 );
5763 return(-9);
5764 }
5765 }
5766 #endif /* NOSPL */
5767 ckstrncpy(tmpbuf,s,TMPBUFSIZ);
5768 cmarg2 = tmpbuf;
5769
5770 if ((x = cmcfm()) < 0)
5771 return(x);
5772 flp = (struct filelist *) malloc(sizeof(struct filelist));
5773 if (flp) {
5774 if (filetail)
5775 filetail->fl_next = flp;
5776 filetail = flp;
5777 if (!filehead)
5778 filehead = flp;
5779 x = (int) strlen(line); /* Length of filename */
5780 s = (char *) malloc(x + 1);
5781 if (s) {
5782 strcpy(s,line); /* safe */
5783 flp->fl_name = s;
5784 flp->fl_mode = xmode;
5785 x = (int) strlen(cmarg2); /* Length of as-name */
5786 if (x < 1) {
5787 flp->fl_alias = NULL;
5788 } else {
5789 s = (char *) malloc(x + 1);
5790 if (s) {
5791 strcpy(s,cmarg2); /* safe */
5792 flp->fl_alias = s;
5793 } else {
5794 printf("Sorry, can't allocate space for as-name");
5795 return(-9);
5796 }
5797 }
5798 flp->fl_next = NULL;
5799 filesinlist++; /* Count this node */
5800 return(success = 1); /* Finished adding this node */
5801 } else {
5802 printf("Sorry, can't allocate space for name");
5803 return(-9);
5804 }
5805 } else {
5806 printf("Sorry, can't allocate file list node");
5807 return(-9);
5808 }
5809 #endif /* NOMSEND */
5810 }
5811 #endif /* ADDCMD */
5812
5813 #ifndef NOHTTP /* HTTP ops... */
5814 #ifdef TCPSOCKET
5815 #define HTTP_GET 0 /* GET */
5816 #define HTTP_PUT 1 /* PUT */
5817 #define HTTP_POS 2 /* POST */
5818 #define HTTP_IDX 3 /* INDEX */
5819 #define HTTP_HED 4 /* HEAD */
5820 #define HTTP_DEL 5 /* DELETE */
5821 #define HTTP_CON 6 /* CONNECT */
5822 #define HTTP_OPN 7 /* OPEN */
5823 #define HTTP_CLS 8 /* CLOSE */
5824
5825 static struct keytab httptab[] = {
5826 { "close", HTTP_CLS, 0 },
5827 { "connect", HTTP_CON, 0 },
5828 { "delete", HTTP_DEL, 0 },
5829 { "get", HTTP_GET, 0 },
5830 { "head", HTTP_HED, 0 },
5831 { "index", HTTP_IDX, 0 },
5832 { "open", HTTP_OPN, 0 },
5833 { "put", HTTP_PUT, 0 },
5834 { "post", HTTP_POS, 0 }
5835 };
5836 static int nhttptab = sizeof(httptab)/sizeof(struct keytab);
5837
5838 /* HTTP switches */
5839 #define HT_SW_AG 0 /* /AGENT */
5840 #define HT_SW_HD 1 /* /HEADER */
5841 #define HT_SW_US 2 /* /USER */
5842 #define HT_SW_PW 3 /* /PASSWORD */
5843 #define HT_SW_AR 4 /* /ARRAY */
5844 #define HT_SW_TP 5 /* /TOSCREEN */
5845
5846 static struct keytab httpswtab[] = {
5847 { "/agent", HT_SW_AG, CM_ARG },
5848 #ifndef NOSPL
5849 { "/array", HT_SW_AR, CM_ARG },
5850 #endif /* NOSPL */
5851 { "/header", HT_SW_HD, CM_ARG },
5852 { "/password", HT_SW_PW, CM_ARG },
5853 { "/toscreen", HT_SW_TP, 0 },
5854 { "/user", HT_SW_US, CM_ARG },
5855 { "", 0, 0 }
5856 };
5857 static int nhttpswtab = sizeof(httpswtab)/sizeof(struct keytab) - 1;
5858
5859 /* HTTP PUT/POST switches */
5860 #define HT_PP_MT 0 /* /MIME-TYPE */
5861
5862 static struct keytab httpptab[] = {
5863 { "/mime-type", HT_PP_MT, CM_ARG },
5864 { "", 0, 0 }
5865 };
5866 static int nhttpptab = sizeof(httpptab)/sizeof(struct keytab) - 1;
5867
5868 #define HTTP_MAXHDR 8
5869
5870 static int
xdohttp(action,lfile,rf,dfile,agent,hdr,user,pass,mime,array,type)5871 xdohttp(action, lfile, rf, dfile, agent, hdr, user, pass, mime, array, type)
5872 int action;
5873 char *lfile, *rf, *dfile, *agent, *hdr, *user, *pass, *mime, array;
5874 int type;
5875 /* xdohttp */ {
5876 int i, rc = 0;
5877 char * hdrlist[HTTP_MAXHDR];
5878 char rfile[CKMAXPATH+1];
5879 extern int httpfd;
5880
5881 /* Check for a valid state to execute the command */
5882 if (inserver) {
5883 printf("?The HTTP command may not be used from the IKS\r\n");
5884 } else if (httpfd == -1) {
5885 if (http_reopen() < 0)
5886 printf("?No connection\n");
5887 else
5888 rc = 1;
5889 } else {
5890 rc = 1;
5891 }
5892
5893 /* If the command is not valid, exit with failure */
5894 if (rc == 0)
5895 return(success = 0);
5896
5897 if (action != HTTP_CON && rf[0] != '/') {
5898 rfile[0] = '/';
5899 ckstrncpy(&rfile[1],rf,CKMAXPATH);
5900 } else {
5901 ckstrncpy(rfile,rf,CKMAXPATH);
5902 }
5903 for (i = 0; i < HTTP_MAXHDR; i++) /* Initialize header list */
5904 hdrlist[i] = NULL;
5905 makelist(hdr,hdrlist,HTTP_MAXHDR); /* Make header list */
5906
5907 #ifdef BETADEBUG
5908 for (i = 0; i < nhttptab; i++) /* Find action keyword */
5909 if (httptab[i].kwval == action)
5910 break;
5911 if (i == nhttptab) { /* Shouldn't happen... */
5912 printf("?Invalid action - %d\n",action);
5913 return(0); /* Failure */
5914 }
5915
5916 printf("HTTP action: %s\n",httptab[i].kwd);
5917 printf(" Agent: %s\n",agent ? agent : "(null)");
5918
5919 if (hdrlist[1]) {
5920 printf(" Header list: 1. %s\n",hdrlist[0]);
5921 for (i = 1; i < HTTP_MAXHDR && hdrlist[i]; i++)
5922 printf("%15d. %s\n",i+1,hdrlist[i]);
5923 } else
5924 printf(" Header: %s\n",hdrlist[0] ? hdrlist[0] : "(null)");
5925
5926 printf(" User: %s\n",user ? user : "(null)");
5927 #ifdef COMMENT
5928 printf(" Password: %s\n",pass ? pass : "(null)");
5929 #endif /* COMMENT */
5930
5931 #ifndef NOSPL
5932 if (array)
5933 printf(" Array: \\%%%c[]\n", array);
5934 else
5935 printf(" Array: (none)\n");
5936 #endif /* NOSPL */
5937
5938 if (action == HTTP_PUT || action == HTTP_POS)
5939 printf(" Mime-type: %s\n",mime ? mime : "(null)");
5940
5941 printf(" Local file: %s\n",lfile ? lfile : "(null)");
5942 printf(" Remote file: %s\n",rfile ? rfile : "(null)");
5943 printf(" Destination file: %s\n",dfile ? dfile : "(null)");
5944 #endif /* BETADEBUG */
5945
5946 /* The http_xxxx() functions return 0 on success, -1 on failure */
5947 switch (action) {
5948 case HTTP_CON: {
5949 extern int ttyfd;
5950 rc = http_connect(httpfd,agent,hdrlist,user,pass,array,rfile);
5951 break;
5952 }
5953 case HTTP_DEL:
5954 rc = http_delete(agent,hdrlist,user,pass,array,rfile);
5955 break;
5956 case HTTP_GET:
5957 rc = http_get(agent,hdrlist,user,pass,array,lfile,rfile,type);
5958 break;
5959 case HTTP_HED:
5960 rc = http_head(agent,hdrlist,user,pass,array,lfile,rfile,type);
5961 break;
5962 case HTTP_PUT:
5963 rc = http_put(agent,hdrlist,mime,user,pass,array,lfile,rfile,dfile,
5964 type);
5965 break;
5966 case HTTP_POS:
5967 rc = http_post(agent,hdrlist,mime,user,pass,array,lfile,rfile,dfile,
5968 type);
5969 break;
5970 case HTTP_IDX:
5971 rc = http_index(agent,hdrlist,user,pass,array,lfile,rfile,type);
5972 break;
5973 default:
5974 rc = -1;
5975 }
5976 return(rc == 0 ? 1 : 0); /* Success is set by caller */
5977 }
5978 #endif /* TCPSOCKET */
5979 #endif /* NOHTTP */
5980
5981 #ifndef NOSPL /* ARRAY ops... */
5982 static struct keytab arraytab[] = {
5983 { "clear", ARR_CLR, 0 },
5984 { "copy", ARR_CPY, 0 },
5985 { "dcl", ARR_DCL, CM_INV },
5986 { "declare", ARR_DCL, 0 },
5987 { "destroy", ARR_DST, CM_INV },
5988 { "equate", ARR_EQU, CM_INV },
5989 { "link", ARR_EQU, 0 },
5990 { "resize", ARR_RSZ, 0 },
5991 { "set", ARR_SET, 0 },
5992 #ifndef NOSHOW
5993 { "show", ARR_SHO, 0 },
5994 #endif /* NOSHOW */
5995 { "sort", ARR_SRT, 0 },
5996 { "undeclare", ARR_DST, 0 },
5997 { "", 0, 0 }
5998 };
5999 static int narraytab = sizeof(arraytab)/sizeof(struct keytab) - 1;
6000
6001 #ifdef CKLEARN
6002 static struct keytab learnswi[] = {
6003 { "/close", 2, 0 },
6004 { "/off", 0, 0 },
6005 { "/on", 1, 0 }
6006 };
6007 #endif /* CKLEARN */
6008
6009 int
arrayitoa(x)6010 arrayitoa(x) int x; { /* Array index to array letter */
6011 if (x == 1)
6012 return(64);
6013 else if (x < 0 || x > (122 - ARRAYBASE))
6014 return(-1);
6015 else
6016 return(x + ARRAYBASE);
6017 }
6018
6019 int
arrayatoi(c)6020 arrayatoi(c) int c; { /* Array letter to array index */
6021 if (c == 64)
6022 c = 96;
6023 if (c > 63 && c < 91)
6024 c += 32;
6025 if (c < ARRAYBASE || c > 122)
6026 return(-1);
6027 return(c - ARRAYBASE);
6028 }
6029
6030 static int /* Declare an array */
dodcl(cx)6031 dodcl(cx) int cx; {
6032 int i, n, v, lo, hi, rc = 0;
6033 int isdynamic = 0;
6034 char tmpbuf[64];
6035 char ** p = NULL;
6036 char tmp[64]; /* Local temporary string buffer */
6037 if ((y = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */
6038 if (y == -3) {
6039 printf("?Array name required\n");
6040 return(-9);
6041 } else return(y);
6042 }
6043 ckstrncpy(line,s,LINBUFSIZ);
6044 s = line;
6045 x = arraybounds(s,&lo,&hi); /* Check syntax and get bounds */
6046 debug(F111,"dodcl arraybounds",s,x);
6047 if (x < 0) { /* Error - Maybe it's a variable */
6048 char * p; /* whose value is an array name */
6049 int n;
6050 p = tmpbuf;
6051 n = 63;
6052 p[0] = NUL;
6053 if (s[0] == CMDQ && s[1] == '&')
6054 s++;
6055 if (zzstring(s,&p,&n) > -1) {
6056 s = tmpbuf;
6057 x = arraybounds(s,&lo,&hi);
6058 debug(F111,"dodcl arraybounds 2",s,x);
6059 }
6060 if (x < 0) {
6061 printf("?Bad array name - \"%s\"\n",s);
6062 return(-9);
6063 }
6064 }
6065 debug(F101,"dodcl hi","",hi);
6066 debug(F101,"dodcl lo","",lo);
6067 debug(F101,"dodcl lo+1","",lo+1);
6068
6069 if (lo == -1 && hi == -1) { /* Have good array name and bounds */
6070 isdynamic = 1;
6071 n = CMDBL / 5;
6072 } else if (hi > -1) {
6073 printf("?Segment notation not allowed in array declarations\n");
6074 return(-9);
6075 } else if ((lo+1) < 0) {
6076 debug(F101,"dodcl underflow","",lo+1);
6077 printf("?Dimension underflow\n");
6078 return(-9);
6079 } else
6080 n = lo;
6081 x = arrayitoa(x);
6082 if (cx == XXUNDCL) {
6083 n = 0;
6084 v = 0;
6085 if ((y = cmcfm()) < 0)
6086 return(y);
6087 } else {
6088 p = (char **)malloc(sizeof(char **)*(n+1));
6089 if (!p) {
6090 printf("?Memory allocation error\n");
6091 return(-9);
6092 }
6093 v = 0; /* Highest initialized member */
6094 p[0] = NULL; /* Element 0 */
6095 keepallchars = 1;
6096 while (n > 0 && v < n) { /* Parse initializers */
6097 p[v+1] = NULL;
6098 ckmakxmsg(tmp,
6099 64,
6100 "Initial value for \\&",
6101 ckctoa((char)x),
6102 "[",
6103 ckitoa(v+1),
6104 "]",
6105 NULL,NULL,NULL,NULL,NULL,NULL,NULL
6106 );
6107
6108 rc = cmfld((char *)tmp,"",&s,xxstring); /* Get field */
6109 if (rc < 0) { /* Error... */
6110 if (rc == -3) { /* Empty element */
6111 if (cmflgs == 1) /* because end of line? */
6112 break; /* Yes, done initializing */
6113 else /* No, it's just empty */
6114 continue; /* Go on to next one. */
6115 } else { /* Other parse error */
6116 goto dclx; /* Go free temp pointers */
6117 }
6118 }
6119 rc = 1;
6120 if (v == 0 && !strcmp(s,"=")) /* Skip the = sign. */
6121 continue;
6122 s = brstrip(s); /* Strip any braces */
6123 makestr(&(p[++v]),s);
6124 }
6125 keepallchars = 0;
6126 if ((y = cmtxt("Carriage return to confirm","",&s,NULL)) < 0)
6127 return(y);
6128 if (isdynamic)
6129 n = v;
6130 }
6131 if (dclarray((char)x,n) < 0) { /* Declare the array */
6132 printf("?Declare failed\n");
6133 goto dclx;
6134 }
6135 for (i = 1; i <= v; i++) { /* Add any initial values */
6136 tmp[0] = '&';
6137 ckmakmsg(&tmp[1],63,ckctoa((char)x),"[",ckitoa(i),"]");
6138 if (addmac(tmp,p[i]) < 0) {
6139 printf("Array initialization error: %s %s\n",tmp,p[i]);
6140 rc = -9;
6141 goto dclx;
6142 }
6143 }
6144 dclx:
6145 if (p) {
6146 for (i = 1; i <= v; i++)
6147 if (p[i]) free(p[i]);
6148 free((char *)p);
6149 }
6150 debug(F101,"DCL rc","",rc);
6151 return(success = rc);
6152 }
6153
6154 static int
rszarray()6155 rszarray() {
6156 int i, x, y, n, lo, hi, islink = -1;
6157 char c, * s, ** ap = NULL;
6158 if ((x = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */
6159 if (x == -3) {
6160 printf("?Array name required\n");
6161 return(-9);
6162 } else return(x);
6163 }
6164 ckstrncpy(line,s,LINBUFSIZ); /* Make safe copy of name */
6165 s = line;
6166 x = arraybounds(s,&lo,&hi);
6167 if (x < 0) { /* Parse the name, get index */
6168 printf("?Bad array reference - \"%s\"\n", s);
6169 return(-9);
6170 }
6171 if (lo < 0 && hi < 0) {
6172 y = cmnum("New size","",10,&lo,xxstring);
6173 if (y < 0) {
6174 if (y == -3)
6175 printf("?New size required\n");
6176 return(y);
6177 }
6178 }
6179 if ((y = cmcfm()) < 0)
6180 return(y);
6181 if (a_link[x] > -1) { /* Link? */
6182 islink = x; /* Yes follow it */
6183 x = a_link[x]; /* and remember */
6184 }
6185 if (!a_ptr[x]) {
6186 printf("?Array not declared - \"%s\"\n", s);
6187 return(-9);
6188 }
6189 if (lo < 0) {
6190 printf("?New size required\n");
6191 return(-9);
6192 }
6193 if (hi > -1) {
6194 printf("?Array segments not allowed for this operation\n");
6195 return(-9);
6196 }
6197 c = arrayitoa(x); /* Get array letter */
6198 if (c == '@') { /* Argument vector array off limits */
6199 printf("?Sorry, \\&@[] is read-only\n");
6200 return(-9);
6201 }
6202 if (lo == 0) { /* If new size is 0... */
6203 dclarray(c,0); /* Undeclare the array */
6204 return(success = 1);
6205 }
6206 n = a_dim[x]; /* Current size */
6207 ap = (char **) malloc((lo+1) * sizeof(char *)); /* New array */
6208 y = (n < lo) ? n : lo;
6209 for (i = 0; i <= y; i++) /* Copy the part that fits */
6210 ap[i] = a_ptr[x][i];
6211 if (n < lo) { /* If original array smaller */
6212 for (; i <= lo; i++) /* initialize extra elements in */
6213 ap[i] = NULL; /* new array to NULL. */
6214 } else if (n > lo) { /* If new array smaller */
6215 for (; i <= lo; i++) /* deallocate leftover elements */
6216 makestr(&(a_ptr[x][i]),NULL); /* from original array. */
6217 }
6218 free((char *)a_ptr[x]); /* Free original array list */
6219 a_ptr[x] = ap; /* Replace with new one */
6220 a_dim[x] = lo; /* Record the new dimension */
6221 if (islink > -1) { /* Was this a link? */
6222 a_ptr[islink] = ap; /* If so point to the resized array */
6223 a_dim[islink] = lo;
6224 } else { /* If not are there links to here? */
6225 for (i = 0; i < (int) 'z' - ARRAYBASE; i++) { /* Any linked arrays? */
6226 if (i != x && a_link[i] == x) { /* Find and update them */
6227 a_ptr[i] = ap;
6228 a_dim[i] = lo;
6229 }
6230 }
6231 }
6232 return(success = 1);
6233 }
6234
6235 static int
copyarray()6236 copyarray() {
6237 int i, j, x1, lo1, hi1, x2, lo2, hi2, whole = 0;
6238 char c1, c2, * a1, * a2;
6239 if ((y = cmfld("Name of source array","",&s,NULL)) < 0)
6240 return(y);
6241 ckstrncpy(line,s,LINBUFSIZ);
6242 a1 = line;
6243 if ((x1 = arraybounds(a1,&lo1,&hi1)) < 0) {
6244 printf("?Bad array reference - \"%s\"\n", a1);
6245 return(-9);
6246 } else if (!a_ptr[x1]) {
6247 printf("?Array not declared - \"%s\"\n", a1);
6248 return(-9);
6249 }
6250 c1 = arrayitoa(x1);
6251
6252 if ((y = cmfld("Name of destination array","",&s,NULL)) < 0)
6253 return(y);
6254 ckstrncpy(tmpbuf,s,TMPBUFSIZ);
6255 a2 = tmpbuf;
6256 if ((x2 = arraybounds(a2,&lo2,&hi2)) < 0) {
6257 printf("?Bad array reference - \"%s\"\n", a2);
6258 return(-9);
6259 }
6260 c2 = arrayitoa(x2);
6261
6262 if ((x = cmcfm()) < 0)
6263 return(x);
6264
6265 if (c2 == '@') { /* Argument vector array off limits */
6266 printf("?Sorry, \\&@[] is read-only\n");
6267 return(-9);
6268 }
6269 if (lo1 < 0 && lo2 < 0 && hi1 < 0 && hi2 < 0) /* Special case for */
6270 whole = 1; /* whole array... */
6271
6272 if (lo1 < 0) lo1 = whole ? 0 : 1; /* Supply lower bound of source */
6273 if (hi1 < 0) hi1 = a_dim[x1]; /* Supply upper bound of source */
6274 if (lo2 < 0) lo2 = whole ? 0 : 1; /* Lower bound of target */
6275 if (hi2 < 0) hi2 = lo2 + hi1 - lo1; /* Upper bound of target */
6276 if (a_ptr[x2]) { /* Target array is already declared? */
6277 if (hi2 > a_dim[x2]) /* If upper bound out of range */
6278 hi2 = a_dim[x2]; /* shrink to fit */
6279 } else { /* Otherwise... */
6280 x2 = dclarray(c2, hi2); /* declare the target array */
6281 }
6282 for (i = lo1, j = lo2; i <= hi1 && j <= hi2; i++,j++) { /* Copy */
6283 makestr(&(a_ptr[x2][j]),a_ptr[x1][i]);
6284 }
6285 return(success = 1);
6286 }
6287
6288 static int /* Undeclare an array */
unarray()6289 unarray() {
6290 int x, y, n, rc = 0;
6291 char c, * s;
6292
6293 if ((y = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */
6294 if (y == -3) {
6295 printf("?Array name required\n");
6296 return(-9);
6297 } else return(y);
6298 }
6299 ckstrncpy(line,s,LINBUFSIZ); /* Make safe copy of name */
6300 s = line;
6301 if ((y = cmcfm()) < 0)
6302 return(y);
6303 if ((x = arraybounds(s,&y,&n)) < 0) { /* Parse the name, get index */
6304 printf("?Bad array reference - \"%s\"\n", s);
6305 return(-9);
6306 }
6307 if (y > 0 || n > 0) {
6308 printf("?Partial arrays can not be destroyed\n");
6309 return(-9);
6310 }
6311 c = arrayitoa(x); /* Get array letter */
6312 if (a_ptr[x]) { /* If array is declared */
6313 if (c == '@') { /* Argument vector array off limits */
6314 printf("?Sorry, \\&@[] is read-only\n");
6315 return(-9);
6316 }
6317 rc = dclarray(c,-1); /* Undeclare the array */
6318 } else /* It wasn't declared */
6319 rc = 1;
6320 if (rc > -1) { /* Set return code and success */
6321 success = 1;
6322 rc = 1;
6323 } else {
6324 success = 0;
6325 printf("?Failed - destroy \"\\&%c[]\"\n", c);
6326 rc = -9;
6327 }
6328 return(rc);
6329 }
6330
6331 static int
clrarray(cx)6332 clrarray(cx) int cx; {
6333 int i, x, lo, hi;
6334 char c, * s, * val = NULL;
6335
6336 if ((x = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */
6337 if (x == -3) {
6338 printf("?Array name required\n");
6339 return(-9);
6340 } else return(x);
6341 }
6342 ckstrncpy(line,s,LINBUFSIZ); /* Make safe copy of name */
6343 s = line;
6344 if (cx == ARR_SET) { /* SET */
6345 if ((x = cmtxt("Value","",&val,xxstring)) < 0)
6346 return(x);
6347 ckstrncpy(tmpbuf,val,TMPBUFSIZ); /* Value to set */
6348 val = tmpbuf;
6349 if (!*val) val = NULL;
6350 } else if ((x = cmcfm()) < 0) /* CLEAR */
6351 return(x);
6352
6353 if ((x = arraybounds(s,&lo,&hi)) < 0) { /* Parse the name */
6354 printf("?Bad array reference - \"%s\"\n", s);
6355 return(-9);
6356 }
6357 c = arrayitoa(x); /* Get array letter */
6358 if (!a_ptr[x]) { /* If array is declared */
6359 printf("?Array %s is not declared\n", s);
6360 return(-9);
6361 } else if (c == '@') { /* Argument vector array off limits */
6362 printf("?Sorry, \\&@[] is read-only\n");
6363 return(-9);
6364 }
6365 if (lo < 0) lo = 0;
6366 if (hi < 0) hi = a_dim[x];
6367 for (i = lo; i <= hi; i++) /* Clear/Set selected range */
6368 makestr(&(a_ptr[x][i]),val);
6369
6370 return(success = 1);
6371 }
6372
6373 extern char **aa_ptr[CMDSTKL][28];
6374 extern int aa_dim[CMDSTKL][28];
6375
6376 static int /* Create symbolic link to an array */
linkarray()6377 linkarray() {
6378 int i = 0, x, y, lo, hi, flag = 0;
6379 char c, * s, * p;
6380
6381 if ((x = cmfld("Array name not currently in use","",&s,NULL)) < 0) {
6382 if (x == -3) {
6383 printf("?Array name required\n");
6384 return(-9);
6385 } else return(x);
6386 }
6387 ckstrncpy(line,s,LINBUFSIZ); /* Make safe copy of link name */
6388 s = line;
6389 if ((x = cmfld("Name of existing array","",&p,xxstring)) < 0) {
6390 if (x == -3) {
6391 printf("?Array name required\n");
6392 return(-9);
6393 } else return(x);
6394 }
6395 ckstrncpy(tmpbuf,p,TMPBUFSIZ); /* Make safe copy of array name */
6396 p = tmpbuf;
6397 if ((x = cmcfm()) < 0)
6398 return(x);
6399
6400 if ((x = arraybounds(s,&lo,&hi)) < 0) { /* Parse the link name */
6401 printf("?Bad array reference - \"%s\"\n", s);
6402 return(-9);
6403 }
6404 if (a_ptr[x]) { /* Must not already exist */
6405 c = arrayitoa(x);
6406 printf("?Array already exists: \\&%c[]\n", c);
6407 return(-9);
6408 }
6409 if (lo > -1 || hi > -1) {
6410 printf("?Sorry, whole arrays only: %s\n",s);
6411 return(-9);
6412 }
6413 if ((y = arraybounds(p,&lo,&hi)) < 0) { /* Parse the array name */
6414 printf("?Bad array reference - \"%s\"\n", s);
6415 return(-9);
6416 }
6417 if (lo > -1 || hi > -1) {
6418 printf("?Sorry, whole arrays only: %s\n",p);
6419 return(-9);
6420 }
6421 if (x == y) {
6422 for (i = cmdlvl; i >= 0; i--)
6423 if (aa_ptr[i][x]) {
6424 flag++;
6425 break;
6426 }
6427 }
6428 if (flag) {
6429 a_ptr[x] = aa_ptr[i][y]; /* Link to saved copy */
6430 a_dim[x] = aa_dim[i][y];
6431 } else { /* Otherwise... */
6432 c = arrayitoa(y); /* Check if it's declared */
6433 if (!a_ptr[y]) {
6434 printf("?Array is not declared: \\&%c[]\n", c);
6435 return(-9);
6436 }
6437 if (a_link[y] > -1) { /* And if it's a link itself */
6438 printf("?Links to links not allowed: \\&%c[]\n", c);
6439 return(-9);
6440 }
6441 a_ptr[x] = a_ptr[y]; /* All OK, make the link */
6442 a_dim[x] = a_dim[y];
6443 }
6444 a_link[x] = y;
6445 return(success = 1);
6446 }
6447 #endif /* NOSPL */
6448
6449 #ifndef NOCSETS
6450 static char * dcsetname = NULL;
6451
6452 /* Get Display Character-Set Name */
6453
6454 char *
getdcset()6455 getdcset() {
6456 char * s;
6457 int y;
6458 #ifdef PCFONTS
6459 extern int tt_font, ntermfont;
6460 extern struct keytab term_font[];
6461 #endif /* PCFONTS */
6462
6463 s = "";
6464 #ifdef OS2
6465 y = os2getcp(); /* Default is current code page */
6466 switch (y) {
6467 case 437: s = "cp437"; break;
6468 case 850: s = "cp850"; break;
6469 case 852: s = "cp852"; break;
6470 case 857: s = "cp857"; break;
6471 case 858: s = "cp858"; break;
6472 case 862: s = "cp862"; break;
6473 case 866: s = "cp866"; break;
6474 case 869: s = "cp869"; break;
6475 case 1250: s = "cp1250"; break;
6476 case 1251: s = "cp1251"; break;
6477 case 1252: s = "cp1252"; break;
6478 case 1253: s = "cp1253"; break;
6479 case 1254: s = "cp1254"; break;
6480 case 1255: s = "cp1255"; break;
6481 case 1256: s = "cp1256"; break;
6482 case 1257: s = "cp1257"; break;
6483 case 1258: s = "cp1258"; break;
6484 }
6485 #ifdef PCFONTS
6486 /*
6487 If the user has loaded a font with SET TERMINAL FONT then we want
6488 to change the default code page to the font that was loaded.
6489 */
6490 if (tt_font != TTF_ROM) {
6491 for (y = 0; y < ntermfont; y++ ) {
6492 if (term_font[y].kwval == tt_font) {
6493 s = term_font[y].kwd;
6494 break;
6495 }
6496 }
6497 }
6498 #endif /* PCFONTS */
6499 #else /* OS2 */
6500 #ifdef COMMENT
6501 /* Hack not needed as of C-Kermit 7.1 */
6502 if (fcharset == FC_1LATIN) {
6503 s = "latin1-iso"; /* Hack to avoid reporting "cp1252" */
6504 } else { /* Report current file character set */
6505 #endif /* COMMENT */
6506 for (y = 0; y <= nfilc; y++)
6507 if (fcstab[y].kwval == fcharset) {
6508 s = fcstab[y].kwd;
6509 break;
6510 }
6511 #ifdef COMMENT
6512 }
6513 #endif /* COMMENT */
6514 #endif /* OS2 */
6515 makestr(&dcsetname,s); /* Return stable pointer */
6516 return((char *)dcsetname);
6517 }
6518 #endif /* NOCSETS */
6519
6520 #ifndef NOFRILLS
6521 static int
doclear()6522 doclear() {
6523 if ((x = cmkey(clrtab,nclear,"item to clear",
6524 #ifdef NOSPL
6525 "device-buffer"
6526 #else
6527 "device-and-input"
6528 #endif /* NOSPL */
6529 ,xxstring)) < 0) return(x);
6530 #ifndef NOSPL
6531 #ifdef OS2
6532 if (x == CLR_CMD || x == CLR_TRM) {
6533 if ((z = cmkey(clrcmdtab,nclrcmd,"how much screen to clear\n",
6534 "all",xxstring)) < 0)
6535 return(z);
6536 }
6537 #endif /* OS2 */
6538 #endif /* NOSPL */
6539 if ((y = cmcfm()) < 0)
6540 return(y);
6541
6542 /* Clear device input buffer if requested */
6543 y = (x & CLR_DEV) ? ttflui() : 0;
6544
6545 if (x & CLR_SCR) /* CLEAR SCREEN */
6546 y = ck_cls(); /* (= SCREEN CLEAR = CLS) */
6547
6548 if (x & CLR_KBD) { /* CLEAR KEYBOARD */
6549 int n;
6550 n = conchk();
6551 y = 0;
6552 while (n-- > 0 && (y = coninc(0) > -1))
6553 ;
6554 y = (y > -1) ? 0 : -1;
6555 }
6556
6557 #ifndef NOSPL
6558 /* Clear INPUT command buffer if requested */
6559 if (x & CLR_INP) {
6560 for (z = 0; z < inbufsize; z++)
6561 inpbuf[z] = NUL;
6562 inpbp = inpbuf;
6563 y = 0;
6564 }
6565 #ifdef CK_APC
6566 if (x & CLR_APC) {
6567 debug(F101,"Executing CLEAR APC","",apcactive);
6568 apcactive = 0;
6569 y = 0;
6570 }
6571 #endif /* CK_APC */
6572 if (x & CLR_ALR) {
6573 setalarm(0L);
6574 y = 0;
6575 }
6576 #endif /* NOSPL */
6577
6578 #ifdef PATTERNS
6579 if (x & (CLR_TXT|CLR_BIN)) {
6580 int i;
6581 for (i = 0; i < FTPATTERNS; i++) {
6582 if (x & CLR_TXT)
6583 makestr(&txtpatterns[i],NULL);
6584 if (x & CLR_BIN)
6585 makestr(&binpatterns[i],NULL);
6586 }
6587 y = 0;
6588 }
6589 #endif /* PATTERNS */
6590
6591 #ifndef NODIAL
6592 if (x & CLR_DIA) {
6593 dialsta = DIA_UNK;
6594 y = 0;
6595 }
6596 #endif /* NODIAL */
6597
6598 #ifndef NOMSEND
6599 if (x & CLR_SFL) { /* CLEAR SEND-LIST */
6600 if (filehead) {
6601 struct filelist * flp, * next;
6602 flp = filehead;
6603 while (flp) {
6604 if (flp->fl_name)
6605 free(flp->fl_name);
6606 if (flp->fl_alias)
6607 free(flp->fl_alias);
6608 next = flp->fl_next;
6609 free((char *)flp);
6610 flp = next;
6611 }
6612 }
6613 filesinlist = 0;
6614 filehead = NULL;
6615 filetail = NULL;
6616 addlist = 0;
6617 y = 0;
6618 }
6619 #endif /* NOMSEND */
6620
6621 #ifdef OS2
6622 #ifndef NOLOCAL
6623 switch (x) {
6624 case CLR_SCL:
6625 clearscrollback(VTERM);
6626 break;
6627 case CLR_CMD:
6628 switch ( z ) {
6629 case CLR_C_ALL:
6630 clear();
6631 break;
6632 case CLR_C_BOS:
6633 clrboscr_escape(VCMD,SP);
6634 break;
6635 case CLR_C_BOL:
6636 clrbol_escape(VCMD,SP);
6637 break;
6638 case CLR_C_EOL:
6639 clrtoeoln(VCMD,SP);
6640 break;
6641 case CLR_C_EOS:
6642 clreoscr_escape(VCMD,SP);
6643 break;
6644 case CLR_C_LIN:
6645 clrline_escape(VCMD,SP);
6646 break;
6647 case CLR_C_SCR:
6648 clearscrollback(VCMD);
6649 break;
6650 default:
6651 printf("Not implemented yet, sorry.\n");
6652 break;
6653 }
6654 break;
6655
6656 #ifndef NOTERM
6657 case CLR_TRM:
6658 switch ( z ) {
6659 case CLR_C_ALL:
6660 if (VscrnGetBufferSize(VTERM) > 0 ) {
6661 VscrnScroll(VTERM, UPWARD, 0,
6662 VscrnGetHeight(VTERM)-(tt_status[VTERM]?2:1),
6663 VscrnGetHeight(VTERM) -
6664 (tt_status[VTERM]?1:0), TRUE, SP
6665 );
6666 cleartermscreen(VTERM);
6667 }
6668 break;
6669 case CLR_C_BOS:
6670 clrboscr_escape(VTERM,SP);
6671 break;
6672 case CLR_C_BOL:
6673 clrbol_escape(VTERM,SP);
6674 break;
6675 case CLR_C_EOL:
6676 clrtoeoln(VTERM,SP);
6677 break;
6678 case CLR_C_EOS:
6679 clreoscr_escape(VTERM,SP);
6680 break;
6681 case CLR_C_LIN:
6682 clrline_escape(VTERM,SP);
6683 break;
6684 case CLR_C_SCR:
6685 clearscrollback(VTERM);
6686 break;
6687 default:
6688 printf("Not implemented yet, sorry.\n");
6689 break;
6690 }
6691 break;
6692 #endif /* NOTERM */
6693 }
6694 y = 0;
6695 #endif /* NOLOCAL */
6696 #endif /* OS2 */
6697 return(success = (y == 0));
6698 }
6699 #endif /* NOFRILLS */
6700
6701 #ifndef NOSPL
6702 static int
doeval(cx)6703 doeval(cx) int cx; {
6704 char *p;
6705 char vnambuf[VNAML], * vnp = NULL; /* These must be on the stack */
6706 if (!oldeval) {
6707 if ((y = cmfld("Variable name","",&s,
6708 ((cx == XX_EVAL) ? xxstring : NULL))) < 0) {
6709 if (y == -3) {
6710 printf("?Variable name required\n");
6711 return(-9);
6712 } else return(y);
6713 }
6714 ckstrncpy(vnambuf,s,VNAML); /* Make a copy. */
6715 vnp = vnambuf;
6716 if (vnambuf[0] == CMDQ &&
6717 (vnambuf[1] == '%' || vnambuf[1] == '&'))
6718 vnp++;
6719 y = 0;
6720 if (*vnp == '%' || *vnp == '&') {
6721 if ((y = parsevar(vnp,&x,&z)) < 0)
6722 return(y);
6723 }
6724 }
6725 if ((x = cmtxt("Integer arithmetic expression","",&s,xxstring)) < 0)
6726 return(x);
6727 p = evala(s);
6728 if (!p) p = "";
6729 if (oldeval && *p)
6730 printf("%s\n", p);
6731 ckstrncpy(evalbuf,p,32);
6732 if (!oldeval)
6733 return(success = addmac(vnambuf,p));
6734 else
6735 return(success = *p ? 1 : 0);
6736 }
6737 #endif /* NOSPL */
6738
6739 #ifdef TNCODE
6740 static int
dotelopt()6741 dotelopt() {
6742 if ((x = cmkey(telcmd, ntelcmd, "TELNET command", "", xxstring)) < 0 )
6743 return(x);
6744 switch (x) {
6745 case WILL:
6746 case WONT:
6747 case DO:
6748 case DONT:
6749 if ((y = cmkey(tnopts,ntnopts,"TELNET option","",xxstring)) < 0)
6750 return(y);
6751 if ((z = cmcfm()) < 0) return(z);
6752
6753 switch (x) {
6754 case WILL:
6755 if (TELOPT_UNANSWERED_WILL(y))
6756 return(success = 0);
6757 break;
6758 case WONT:
6759 if (TELOPT_UNANSWERED_WONT(y))
6760 return(success = 0);
6761 break;
6762 case DO:
6763 if (TELOPT_UNANSWERED_DO(y))
6764 return(success = 0);
6765 break;
6766 case DONT:
6767 if (TELOPT_UNANSWERED_DONT(y))
6768 return(success = 0);
6769 break;
6770 }
6771 if (local) {
6772 success = ((tn_sopt(x,y) > -1) ? 1 : 0);
6773 } else {
6774 printf("ff%02x%02x\n",x,y);
6775 success = 1;
6776 }
6777 if (success) {
6778 switch (x) {
6779 case WILL:
6780 TELOPT_UNANSWERED_WILL(y) = 1;
6781 break;
6782 case WONT:
6783 if ( TELOPT_ME(y) )
6784 TELOPT_UNANSWERED_WONT(y) = 1;
6785 break;
6786 case DO:
6787 TELOPT_UNANSWERED_DO(y) = 1;
6788 break;
6789 case DONT:
6790 if ( TELOPT_ME(y) )
6791 TELOPT_UNANSWERED_DONT(y) = 1;
6792 break;
6793 }
6794 if (tn_wait("XXTELOP") < 0) {
6795 tn_push();
6796 success = 0;
6797 }
6798 }
6799 return(success);
6800 case SB:
6801 if ((y=cmkey(tnsbopts,ntnsbopts,"TELNET option","",xxstring)) < 0)
6802 return(y);
6803 switch (y) {
6804 case TELOPT_NAWS:
6805 /* Some compilers require switch() to have at least 1 case */
6806 #ifdef CK_NAWS
6807 TELOPT_SB(TELOPT_NAWS).naws.x = 0;
6808 TELOPT_SB(TELOPT_NAWS).naws.y = 0;
6809 if (local)
6810 return(success = ((tn_snaws() > -1) ? 1 : 0));
6811 else
6812 return(success = 0);
6813 #else
6814 return(success = 0);
6815 #endif /* CK_NAWS */
6816 }
6817 return(success = 0);
6818
6819 #ifdef CK_KERBEROS
6820 #ifdef KRB5
6821 case TN_FWD:
6822 success = (kerberos5_forward() == AUTH_SUCCESS);
6823 return(success);
6824 #endif /* KRB5 */
6825 #endif /* CK_KERBEROS */
6826
6827 default:
6828 if ((z = cmcfm()) < 0) return(z);
6829 #ifndef NOLOCAL
6830 if (local) {
6831 CHAR temp[3];
6832 if (network && IS_TELNET()) { /* TELNET */
6833 temp[0] = (CHAR) IAC;
6834 temp[1] = x;
6835 temp[2] = NUL;
6836 success = (ttol((CHAR *)temp,2) > -1 ? 1 : 0);
6837 if (tn_deb || debses || deblog) {
6838 /* TN_MSG_LEN is in ckctel.h */
6839 ckmakmsg(tn_msg,256,"TELNET SENT ",TELCMD(x),NULL,NULL);
6840 debug(F101,tn_msg,"",x);
6841 if (debses || tn_deb) tn_debug(tn_msg);
6842 }
6843 return(success);
6844 }
6845 return(success = 0);
6846 } else {
6847 #endif /* NOLOCAL */
6848 printf("ff%02x\n",x);
6849 return(success = 1);
6850 #ifndef NOLOCAL
6851 }
6852 #endif /* NOLOCAL */
6853 }
6854 }
6855 #endif /* TNCODE */
6856
6857
6858 #ifndef NOPUSH
6859 #ifndef NOFRILLS
6860 static int
doedit()6861 doedit() {
6862 #ifdef OS2
6863 char * p = NULL;
6864 #endif /* OS2 */
6865 if (!editor[0]) {
6866 s = getenv("EDITOR");
6867 if (s) ckstrncpy(editor,s,CKMAXPATH);
6868 editor[CKMAXPATH] = NUL;
6869 if (!editor[0]) {
6870 printf("?Editor not defined - use SET EDITOR to define\n");
6871 return(-9);
6872 }
6873 }
6874 ckstrncpy(tmpbuf,editfile,TMPBUFSIZ);
6875 /*
6876 cmiofi() lets us parse the name of an existing file, or the name of
6877 a nonexistent file to be created.
6878 */
6879 x = cmiofi("File to edit", (char *)tmpbuf, &s, &y, xxstring);
6880 debug(F111,"edit",s,x);
6881 if (x < 0 && x != -3)
6882 return(x);
6883 if (x == -3) {
6884 tmpbuf[0] = NUL;
6885 } else {
6886 ckstrncpy(tmpbuf,s,TMPBUFSIZ);
6887 }
6888 if ((z = cmcfm()) < 0) return(z);
6889 if (y) {
6890 printf("?A single file please\n");
6891 return(-9);
6892 }
6893 if (nopush) {
6894 printf("?Sorry, editing not allowed\n");
6895 return(success = 0);
6896 }
6897 if (tmpbuf[0]) {
6898 /* Get full path in case we change directories between EDIT commands */
6899 zfnqfp(tmpbuf, CKMAXPATH, editfile);
6900 editfile[CKMAXPATH] = NUL;
6901 #ifdef OS2
6902 p = editfile; /* Flip the stupid slashes */
6903 while (*p) {
6904 if (*p == '/') *p = '\\';
6905 p++;
6906 }
6907 #endif /* OS2 */
6908 } else
6909 editfile[0] = NUL;
6910 if (editfile[0]) {
6911 if (zchki(editfile) < (CK_OFF_T)0 && zchko(editfile) < 0) {
6912 printf("?Access denied: %s\n",editfile);
6913 return(-9);
6914 }
6915 }
6916 x = 0;
6917 if (editopts[0]) {
6918 #ifdef OS2
6919 x = ckindex("%1",(char *)editopts,0,0,1);
6920 if (x > 0)
6921 editopts[x] = 's';
6922 else
6923 #endif /* OS2 */
6924 x = ckindex("%s",(char *)editopts,0,0,1);
6925 }
6926 if (((int)strlen(editopts) + (int)strlen(editfile) + 1) < TMPBUFSIZ) {
6927 if (x)
6928 sprintf(tmpbuf,editopts,editfile);
6929 else
6930 sprintf(tmpbuf,"%s %s",editopts,editfile);
6931 }
6932 s = line;
6933 ckmakmsg(s,LINBUFSIZ,editor," ",tmpbuf,NULL);
6934 #ifdef OS2
6935 p = s + strlen(editor); /* And again with the slashes */
6936 while (p != s) {
6937 if (*p == '/') *p = '\\';
6938 p--;
6939 }
6940 #endif /* OS2 */
6941 conres();
6942 x = zshcmd(s);
6943 concb((char)escape);
6944 return(x);
6945 }
6946 #endif /* NOFRILLS */
6947 #endif /* NOPUSH */
6948
6949 #ifdef BROWSER
6950 static int
dobrowse()6951 dobrowse() {
6952 #ifdef OS2
6953 char * p = NULL;
6954 #endif /* OS2 */
6955 if (nopush) {
6956 printf("?Sorry, browsing not allowed\n");
6957 return(success = 0);
6958 }
6959 #ifndef NT
6960 /* Windows lets the Shell Execute the URL if no Browser is defined */
6961 if (!browser[0]) {
6962 s = getenv("BROWSER");
6963 if (s) ckstrncpy(browser,s,CKMAXPATH);
6964 browser[CKMAXPATH] = NUL;
6965 if (!browser[0]) {
6966 printf("?Browser not defined - use SET BROWSER to define\n");
6967 return(-9);
6968 }
6969 }
6970 #endif /* NT */
6971 ckstrncpy(tmpbuf,browsurl,TMPBUFSIZ);
6972 if ((x = cmtxt("URL",(char *)browsurl,&s,xxstring)) < 0)
6973 return(x);
6974 ckstrncpy(browsurl,s,4096);
6975 x = 0;
6976 if (browsopts[0]) {
6977 #ifdef OS2
6978 x = ckindex("%1",(char *)browsopts,0,0,1);
6979 if (x > 0)
6980 browsopts[x] = 's';
6981 else
6982 #endif /* OS2 */
6983 x = ckindex("%s",(char *)browsopts,0,0,1);
6984 }
6985 if (((int)strlen(browsopts) + (int)strlen(browsurl) + 1) < TMPBUFSIZ) {
6986 if (x)
6987 sprintf(tmpbuf,browsopts,browsurl);
6988 else
6989 sprintf(tmpbuf,"%s %s",browsopts,browsurl);
6990 }
6991 #ifdef NT
6992 if (!browser[0])
6993 return(success = Win32ShellExecute(browsurl));
6994 #endif /* NT */
6995 s = line;
6996 ckmakmsg(s,LINBUFSIZ,browser," ",tmpbuf,NULL);
6997 #ifdef OS2
6998 p = line + strlen(browser); /* Flip slashes */
6999 while (p != line) {
7000 if (*p == '/') *p = '\\';
7001 p--;
7002 }
7003 #endif /* OS2 */
7004 conres();
7005 x = zshcmd(s);
7006 concb((char)escape);
7007 return(x);
7008 }
7009 #endif /* BROWSER */
7010
7011 #ifdef CK_RECALL
7012 static int
doredo()7013 doredo() { /* Find a previous cmd and redo it */
7014 extern int on_recall, in_recall;
7015 int x;
7016 char * p;
7017
7018 if ((x = cmtxt(
7019 "pattern, or first few characters of a previous command",
7020 "*",&s,xxstring)) < 0)
7021 return(x);
7022 ckstrncpy(line,s,LINBUFSIZ);
7023 x = strlen(s);
7024 s = line;
7025 if (*s == '{') { /* Braces disable adding * to end */
7026 if (s[x-1] == '}') {
7027 s[x-1] = NUL;
7028 s++;
7029 x--;
7030 }
7031 } else { /* No braces, add * to end. */
7032 s[x] = '*';
7033 s[x+1] = NUL;
7034 }
7035
7036 while (x > 0 && s[x] == '*' && s[x-1] == '*') s[x--] = NUL;
7037
7038 if (!on_recall || !in_recall) {
7039 printf("?Sorry, command recall can't be used now.\n");
7040 return(-9);
7041 }
7042 if ((p = cmgetcmd(s))) { /* Look for it history buffer */
7043 ckmakmsg(cmdbuf,CMDBL,p,"\r",NULL,NULL); /* Copy to command buffer */
7044 if (!quiet) /* Echo it */
7045 printf("%s\n",cmdbuf);
7046 cmaddnext(); /* Force re-add to history buffer */
7047 return(cmflgs = -1); /* Force reparse */
7048 } else {
7049 printf("?Sorry - \"%s\" not found\n", s);
7050 return(-9);
7051 }
7052 }
7053 #endif /* CK_RECALL */
7054
7055 #ifndef NOXFER
7056 #ifndef NOCSETS
7057 static int
doassoc()7058 doassoc() { /* ASSOCIATE */
7059 extern struct keytab tcstab[];
7060 extern int ntcs;
7061 if ((x = cmkey(assoctab, nassoc, "", "", xxstring)) < 0 )
7062 return(x);
7063
7064 switch (x) { /* Associate what? */
7065
7066 case ASSOC_TC: /* Transfer character-set... */
7067 if ((x = cmkey(tcstab, ntcs,
7068 "transfer character-set name","",xxstring)) < 0)
7069 return(x);
7070 if ((y = cmkey(fcstab, nfilc,
7071 "with file character-set","", xxstring)) < 0)
7072 if (y != -3)
7073 return(y);
7074 if ((z = cmcfm()) < 0)
7075 return(z);
7076 axcset[x] = y;
7077 return(success = 1);
7078
7079 case ASSOC_FC: /* File character-set... */
7080 if ((x = cmkey(fcstab, nfilc,
7081 "file character-set name","",xxstring)) < 0)
7082 return(x);
7083 if ((y = cmkey(tcstab, ntcs,
7084 "with transfer character-set","", xxstring)) < 0)
7085 if (y != -3)
7086 return(y);
7087 if ((z = cmcfm()) < 0)
7088 return(z);
7089 afcset[x] = y;
7090 return(success = 1);
7091
7092 default:
7093 return(-2);
7094 }
7095 }
7096 #endif /* NOCSETS */
7097 #endif /* NOXFER */
7098
7099 #ifndef NOHELP
7100 static int
domanual()7101 domanual() {
7102 #ifdef OS2
7103 if ((x = cmcfm()) < 0)
7104 return(x);
7105 if (nopush) {
7106 printf("?Sorry, access to system commands is disabled.\n");
7107 return(-9);
7108 }
7109 y = mxlook(mactab,"manual",nmac);
7110 if (y > -1) {
7111 z = maclvl; /* Save the current maclvl */
7112 dodo(y,NULL,cmdstk[cmdlvl].ccflgs); /* Run the macro */
7113 while (maclvl > z) {
7114 debug(F101,"XXMAN loop maclvl 1","",maclvl);
7115 sstate = (CHAR) parser(1);
7116 debug(F101,"XXMAN loop maclvl 2","",maclvl);
7117 if (sstate) proto();
7118 }
7119 debug(F101,"XXMAN loop exit maclvl","",maclvl);
7120 return(success);
7121 }
7122 return(success = 0);
7123 #else
7124 if ((x = cmtxt(
7125 #ifdef UNIX
7126 "Carriage return to confirm the command, or manual topic",
7127 #else
7128 "Carriage return to confirm the command, or help topic",
7129 #endif /* UNIX */
7130 "kermit",
7131 &s,
7132 xxstring
7133 )
7134 ) < 0)
7135 return(x);
7136 #endif /* OS2 */
7137
7138 #ifdef UNIX
7139 ckmakmsg(tmpbuf,TMPBUFSIZ,"man ",s,NULL,NULL);
7140 #else
7141 ckmakmsg(tmpbuf,TMPBUFSIZ,"help ",s,NULL,NULL);
7142 #endif /* UNIX */
7143 debug(F110,"MANUAL",tmpbuf,0);
7144 if (nopush) {
7145 printf("?Sorry, access to system commands is disabled.\n");
7146 return(-9);
7147 } else {
7148 conres(); /* Restore the console */
7149 success = zshcmd(tmpbuf);
7150 concb((char)escape); /* Restore CBREAK mode */
7151 return(success);
7152 }
7153 }
7154 #endif /* NOHELP */
7155
7156 #ifndef NOHTTP
7157 #ifdef TCPSOCKET
7158 static struct keytab sslswtab[] = {
7159 { "/ssl", 1, 0 },
7160 { "/tls", 1, 0 }
7161 };
7162
7163 #ifndef NOURL
7164 struct urldata http_url = {NULL,NULL,NULL,NULL,NULL,NULL,NULL};
7165 #endif /* NOURL */
7166
7167 static int
dohttp()7168 dohttp() { /* HTTP */
7169 struct FDB sw, kw, fi;
7170 int n, getval, allinone = 0;
7171 char c, * p;
7172 char rdns[128];
7173
7174 char * http_agent = NULL; /* Parse results */
7175 char * http_hdr = NULL;
7176 char * http_user = NULL;
7177 char * http_pass = NULL;
7178 char * http_mime = NULL;
7179 char * http_lfile = NULL;
7180 char * http_rfile = NULL;
7181 char * http_dfile = NULL;
7182 char http_array = NUL;
7183 int http_action = -1;
7184
7185 char * http_host = NULL;
7186 char * http_srv = NULL;
7187 int http_ssl = 0;
7188
7189 static char * http_d_agent = NULL;
7190 static char * http_d_user = NULL;
7191 static char * http_d_pass = NULL;
7192
7193 static int http_d_type = 0;
7194 int http_type = http_d_type;
7195
7196 #ifdef OS2
7197 p = "Kermit 95"; /* Default user agent */
7198 #else
7199 p = "C-Kermit";
7200 #endif /* OS2 */
7201 makestr(&http_agent,p);
7202 makestr(&http_mime,"text/HTML"); /* MIME type default */
7203 rdns[0] = '\0';
7204
7205 cmfdbi(&sw, /* 1st FDB - general switches */
7206 _CMKEY, /* fcode */
7207 "OPEN, CLOSE, GET, HEAD, PUT, INDEX, or POST,\n or switch", /* hlpmsg */
7208 "", /* default */
7209 "", /* addtl string data */
7210 nhttpswtab, /* addtl numeric data 1: tbl size */
7211 4, /* addtl numeric data 2: 4 = cmswi */
7212 xxstring, /* Processing function */
7213 httpswtab, /* Keyword table */
7214 &kw /* Pointer to next FDB */
7215 );
7216 cmfdbi(&kw, /* 2nd FDB - commands */
7217 _CMKEY, /* fcode */
7218 "Command", /* hlpmsg */
7219 "", /* default */
7220 "", /* addtl string data */
7221 nhttptab, /* addtl numeric data 1: tbl size */
7222 0, /* addtl numeric data 2: 0 = keyword */
7223 xxstring, /* Processing function */
7224 httptab, /* Keyword table */
7225 NULL /* Pointer to next FDB */
7226 );
7227
7228 while (1) {
7229 x = cmfdb(&sw); /* Parse something */
7230 if (x < 0) /* Error */
7231 goto xhttp;
7232 n = cmresult.nresult;
7233 if (cmresult.fdbaddr == &kw) /* Command - exit this loop */
7234 break;
7235 c = cmgbrk(); /* Switch... */
7236 getval = (c == ':' || c == '=');
7237 x = -9;
7238 if (getval && !(cmgkwflgs() & CM_ARG)) {
7239 printf("?This switch does not take an argument\n");
7240 goto xhttp;
7241 }
7242 switch (cmresult.nresult) { /* Handle each switch */
7243 case HT_SW_TP: /* /TOSCREEN */
7244 http_type = 1;
7245 break;
7246 case HT_SW_AG: /* /AGENT */
7247 if (getval) {
7248 if ((x = cmfld("User agent",p,&s,xxstring)) < 0)
7249 goto xhttp;
7250 } else {
7251 s = p;
7252 }
7253 makestr(&http_agent,s);
7254 break;
7255 case HT_SW_HD: /* /HEADER */
7256 s = NULL;
7257 if (getval) {
7258 if ((x = cmfld("Header line","",&s,xxstring)) < 0) {
7259 if (x == -3)
7260 s = NULL;
7261 else
7262 goto xhttp;
7263 }
7264 }
7265 makestr(&http_hdr,s);
7266 break;
7267 case HT_SW_US: /* /USER */
7268 s = NULL;
7269 if (getval) {
7270 if ((x = cmfld("User ID","",&s,xxstring)) < 0) {
7271 if (x == -3)
7272 s = "";
7273 else
7274 goto xhttp;
7275 }
7276 }
7277 makestr(&http_user,s);
7278 break;
7279 case HT_SW_PW: /* /PASSWORD */
7280 debok = 0;
7281 s = NULL;
7282 if (getval) {
7283 if ((x = cmfld("Password","",&s,xxstring)) < 0)
7284 goto xhttp;
7285 }
7286 makestr(&http_pass,s);
7287 break;
7288 #ifndef NOSPL
7289 case HT_SW_AR: { /* /ARRAY: */
7290 char * s2, array = NUL;
7291 if (!getval) {
7292 printf("?This switch requires an argument\n");
7293 x = -9;
7294 goto xhttp;
7295 }
7296 if ((x = cmfld("Array name (a single letter will do)",
7297 "",
7298 &s,
7299 NULL
7300 )) < 0) {
7301 if (x == -3) {
7302 printf("?Array name required\n");
7303 x = -9;
7304 goto xhttp;
7305 } else
7306 goto xhttp;
7307 }
7308 if (!*s) {
7309 printf("?Array name required\n");
7310 x = -9;
7311 goto xhttp;
7312 }
7313 s2 = s;
7314 if (*s == CMDQ) s++;
7315 if (*s == '&') s++;
7316 if (!isalpha(*s)) {
7317 printf("?Bad array name - \"%s\"\n",s2);
7318 x = -9;
7319 goto xhttp;
7320 }
7321 array = *s++;
7322 if (isupper(array))
7323 array = tolower(array);
7324 if (*s && (*s != '[' || *(s+1) != ']')) {
7325 printf("?Bad array name - \"%s\"\n",s2);
7326 http_array = NUL;
7327 x = -9;
7328 goto xhttp;
7329 }
7330 http_array = array;
7331 break;
7332 }
7333 #endif /* NOSPL */
7334 default:
7335 x = -2;
7336 goto xhttp;
7337 }
7338 }
7339 http_action = n; /* Save the action */
7340 if (http_action == HTTP_PUT || http_action == HTTP_POS) {
7341 cmfdbi(&sw, /* 1st FDB - switch */
7342 _CMKEY, /* fcode */
7343 "Local filename\n Or switch", /* help */
7344 "", /* default */
7345 "", /* addtl string data */
7346 nhttpptab, /* keyword table size */
7347 4, /* addtl numeric data 2: 4 = cmswi */
7348 xxstring, /* Processing function */
7349 httpptab, /* Keyword table */
7350 &fi /* Pointer to next FDB */
7351 );
7352 cmfdbi(&fi, /* 2nd FDB - filename */
7353 _CMIFI, /* fcode */
7354 "Local filename", /* hlpmsg */
7355 "", /* default */
7356 "", /* addtl string data */
7357 0, /* addtl numeric data 1 */
7358 0, /* addtl numeric data 2 */
7359 xxstring,
7360 NULL,
7361 NULL
7362 );
7363 while (1) {
7364 x = cmfdb(&sw);
7365 if (x < 0)
7366 goto xhttp; /* Free any malloc'd temp strings */
7367 n = cmresult.nresult;
7368 if (cmresult.fcode != _CMKEY)
7369 break;
7370 c = cmgbrk(); /* Switch... */
7371 getval = (c == ':' || c == '=');
7372 if (getval && !(cmgkwflgs() & CM_ARG)) {
7373 printf("?This switch does not take an argument\n");
7374 x = -9;
7375 goto xhttp;
7376 }
7377 switch (n) {
7378 case HT_PP_MT:
7379 s = "text/HTML";
7380 if (getval) {
7381 if ((x = cmfld("MIME type",
7382 "text/HTML",&s,xxstring)) < 0)
7383 goto xhttp;
7384 }
7385 makestr(&http_mime,s);
7386 break;
7387 default:
7388 x = -2;
7389 goto xhttp;
7390 }
7391 }
7392 makestr(&http_lfile,cmresult.sresult);
7393 n = ckindex("/",http_lfile,-1,1,0);
7394 if (n)
7395 p = &http_lfile[n];
7396 else
7397 p = http_lfile;
7398 if ((x = cmfld("URL or remote filename",p,&s,xxstring)) < 0) {
7399 if (x == -3) {
7400 printf("?%s what?\n",(http_action == HTTP_PUT) ? "Put" : "Post");
7401 x = -9;
7402 }
7403 goto xhttp;
7404 }
7405 if (!*s) s = NULL;
7406 makestr(&http_rfile,s);
7407
7408 if ((x = cmtxt("Response filename","",&s,xxstring)) < 0) {
7409 if (x != -3)
7410 goto xhttp;
7411 }
7412 if (*s)
7413 makestr(&http_dfile,s);
7414 }
7415 switch (http_action) {
7416 case HTTP_DEL: /* DELETE */
7417 if ((x = cmfld("URL or remote source file","",&s,xxstring)) < 0) {
7418 if (x == -3) {
7419 printf("?Delete what?\n");
7420 x = -9;
7421 }
7422 goto xhttp;
7423 }
7424 makestr(&http_rfile,s);
7425 break;
7426 case HTTP_CON: /* CONNECT */
7427 if ((x = cmfld("Remote host[:port]","",&s,xxstring)) < 0) {
7428 if (x == -3) {
7429 printf("?Remote host[:port] is required\n");
7430 x = -9;
7431 }
7432 goto xhttp;
7433 }
7434 makestr(&http_rfile,s);
7435 break;
7436 case HTTP_HED: { /* HEAD */
7437 char buf[CKMAXPATH+1];
7438 if ((x = cmfld("URL or remote source file","",&s,xxstring)) < 0) {
7439 if (x == -3) {
7440 printf("?Head of what?\n");
7441 x = -9;
7442 }
7443 goto xhttp;
7444 }
7445 makestr(&http_rfile,s);
7446
7447 if (http_array || http_type) { /* Default result filename */
7448 p = ""; /* None if /ARRAY or /TOSCREEN */
7449 } else {
7450 n = ckindex("/",http_rfile,-1,1,0); /* Otherwise strip path */
7451 if (n) /* and add ".head" */
7452 p = &http_rfile[n];
7453 else
7454 p = http_rfile;
7455 ckmakmsg(buf,CKMAXPATH,p,".head",NULL,NULL);
7456 p = buf;
7457 }
7458 if ((x = cmofi("Local filename",p,&s,xxstring)) < 0) {
7459 if (x != -3)
7460 goto xhttp;
7461 }
7462 makestr(&http_lfile,s);
7463 break;
7464 }
7465 case HTTP_GET: /* GET */
7466 case HTTP_IDX: { /* INDEX */
7467 extern int wildena;
7468 int tmp;
7469 char * lfile = "";
7470 if ((x = cmfld("URL or remote source file","",&s,xxstring)) < 0) {
7471 if (x == -3) {
7472 printf("?Get what?\n");
7473 x = -9;
7474 }
7475 goto xhttp;
7476 }
7477 makestr(&http_rfile,s);
7478 if (http_action == HTTP_GET && !http_type)
7479 zstrip(http_rfile,&lfile);
7480 /* URLs often contain question marks or other metacharacters */
7481 /* cmofi() doesn't like them */
7482 tmp = wildena;
7483 wildena = 0;
7484 if ((x = cmofi("Local filename",lfile,&s,xxstring)) < 0) {
7485 wildena = tmp;
7486 if (x != -3)
7487 goto xhttp;
7488 }
7489 wildena = tmp;
7490 makestr(&http_lfile,s);
7491 break;
7492 }
7493 case HTTP_OPN: {
7494 int sslswitch = 0;
7495 #ifdef CK_SSL
7496 struct FDB sw, fl;
7497 cmfdbi(&sw,
7498 _CMKEY, /* fcode */
7499 "IP host name or address, or switch", /* hlpmsg */
7500 "", /* default */
7501 "", /* addtl string data */
7502 2, /* addtl numeric data 1: tbl size */
7503 4, /* addtl numeric data 2: 4 = cmswi */
7504 xxstring, /* Processing function */
7505 sslswtab, /* Keyword table */
7506 &fl /* Pointer to next FDB */
7507 );
7508 cmfdbi(&fl, /* 2nd FDB - host */
7509 _CMFLD, /* fcode */
7510 "", /* hlpmsg */
7511 "", /* default */
7512 "", /* addtl string data */
7513 0, /* addtl numeric data 1 */
7514 0, /* addtl numeric data 2 */
7515 xxstring,
7516 NULL,
7517 NULL
7518 );
7519 x = cmfdb(&sw); /* Parse switch or host */
7520 if (x < 0) /* Error */
7521 goto xhttp;
7522 if (cmresult.fcode == _CMFLD) { /* Host */
7523 s = cmresult.sresult; /* Set up expected pointer */
7524 goto havehost; /* Go parse rest of command */
7525 }
7526 sslswitch = 1; /* /SSL or /TLS switch - set flag */
7527 #endif /* CK_SSL */
7528
7529 /* Parse host */
7530
7531 if ((x = cmfld("URL, hostname, or ip-address","",&s,xxstring)) < 0) {
7532 if (x == -3) {
7533 printf("?Open what?\n");
7534 x = -9;
7535 }
7536 goto xhttp;
7537 }
7538
7539 havehost: /* Come here with s -> host */
7540 #ifdef CK_URL
7541 x = urlparse(s,&http_url); /* Was a URL given? */
7542 if (x < 1) { /* Not a URL */
7543 #endif /* CK_URL */
7544 makestr(&http_host,s);
7545 if ((x =
7546 cmfld("Service name or port number",
7547 sslswitch ? "https" : "http",&s,xxstring)) < 0)
7548 goto xhttp;
7549 else
7550 makestr(&http_srv,s);
7551 #ifdef CK_URL
7552 } else if (ckstrcmp(http_url.svc,"http",-1,0) && /* Non-HTTP URL */
7553 ckstrcmp(http_url.svc,"https",-1,0)) {
7554 printf("?Non-HTTP URL\n");
7555 x = -9;
7556 goto xhttp;
7557 } else { /* Have HTTP URL */
7558 makestr(&http_srv, http_url.svc);
7559 makestr(&http_user,http_url.usr);
7560 makestr(&http_pass,http_url.psw);
7561 makestr(&http_host,http_url.hos);
7562 if (http_url.por)
7563 makestr(&http_srv,http_url.por);
7564 makestr(&http_rfile,http_url.pth);
7565 }
7566 if (http_rfile) { /* Open, GET, and Close */
7567 printf("?Directory/file path not allowed in HTTP OPEN URL\n");
7568 x = -9;
7569 goto xhttp;
7570 }
7571 if (!ckstrcmp("https",http_srv,-1,0) || sslswitch ||
7572 !ckstrcmp("443",http_srv,-1,0))
7573 http_ssl = 1;
7574 #endif /* CK_URL */
7575 break;
7576 }
7577 case HTTP_CLS:
7578 break;
7579 }
7580 if ((x = cmcfm()) < 0)
7581 goto xhttp;
7582
7583 if (http_action == HTTP_OPN) {
7584 x = (http_open(http_host,http_srv,http_ssl,rdns,128,http_agent) == 0);
7585 if (x) {
7586 if (!quiet) {
7587 if (rdns[0])
7588 printf("Connected to %s [%s]\r\n",http_host,rdns);
7589 else
7590 printf("Connected to %s\r\n",http_host);
7591 }
7592 if (http_agent) {
7593 if (http_d_agent)
7594 free(http_d_agent);
7595 http_d_agent = http_agent;
7596 http_agent = NULL;
7597 }
7598 if (http_user) {
7599 if (http_d_user)
7600 free(http_d_user);
7601 http_d_user = http_user;
7602 http_user = NULL;
7603 }
7604 if (http_pass) {
7605 if (http_d_pass) {
7606 memset(http_d_pass,0,strlen(http_d_pass));
7607 free(http_d_pass);
7608 }
7609 http_d_pass = http_pass;
7610 http_pass = NULL;
7611 }
7612 http_d_type = http_type;
7613 } else {
7614 if (!quiet)
7615 printf("?HTTP Connection failed.\r\n");
7616 }
7617 } else if (http_action == HTTP_CLS) {
7618 if (http_d_agent) {
7619 free(http_d_agent);
7620 http_d_agent = NULL;
7621 }
7622 if (http_d_user) {
7623 free(http_d_user);
7624 http_d_user = NULL;
7625 }
7626 if (http_d_pass) {
7627 memset(http_d_pass,0,strlen(http_d_pass));
7628 free(http_d_pass);
7629 http_d_pass = NULL;
7630 }
7631 http_d_type = 0;
7632 x = (http_close() == 0);
7633 }
7634 if ((http_action != HTTP_CLS) &&
7635 (http_action != HTTP_CON) && http_rfile) { /* Remote file is URL? */
7636
7637 /* All-in-one actions when a URL is given... */
7638
7639 #ifdef CK_URL
7640 if (urlparse(http_rfile,&http_url) > 0) { /* Have URL? */
7641 if (ckstrcmp(http_url.svc,"http",-1,0) && /* It's an HTTP URL? */
7642 ckstrcmp(http_url.svc,"https",-1,0)) {
7643 printf("?Non-HTTP URL\n");
7644 x = -9;
7645 goto xhttp;
7646 } else { /* Yes, collect the pieces */
7647 makestr(&http_srv, http_url.svc);
7648 makestr(&http_user,http_url.usr);
7649 makestr(&http_pass,http_url.psw);
7650 makestr(&http_host,http_url.hos);
7651 if (http_url.por)
7652 makestr(&http_srv,http_url.por);
7653 makestr(&http_rfile,http_url.pth);
7654 }
7655 if (!http_rfile) { /* Still have a path? */
7656 makestr(&http_rfile,"/");
7657 }
7658 if (!ckstrcmp("https",http_srv,-1,0) || /* Check for SSL/TLS */
7659 !ckstrcmp("443",http_srv,-1,0))
7660 http_ssl = 1;
7661 if (http_isconnected()) /* Close any open HTTP connection */
7662 http_close();
7663 if (http_pass == NULL && http_d_pass != NULL)
7664 makestr(&http_pass,http_d_pass);
7665 x = (http_open(http_host,
7666 http_srv,http_ssl,rdns,128,http_d_agent) == 0);
7667 if (x < 0) {
7668 x = 0;
7669 goto xhttp;
7670 }
7671 allinone = 1;
7672 }
7673 #endif /* CK_URL */
7674 if (http_pass == NULL && http_d_pass != NULL)
7675 makestr(&http_pass,http_d_pass);
7676
7677 if (http_action == HTTP_OPN && allinone) {
7678 http_action = HTTP_GET;
7679 }
7680 x = xdohttp(http_action,
7681 http_lfile,
7682 http_rfile,
7683 http_dfile,
7684 http_agent ? http_agent : http_d_agent,
7685 http_hdr,
7686 http_user ? http_user : http_d_user,
7687 http_pass ? http_pass : http_d_pass,
7688 http_mime,
7689 http_array,
7690 http_type
7691 );
7692 if (allinone)
7693 x = (http_close() == 0);
7694 }
7695
7696 xhttp:
7697 if (http_agent) free(http_agent);
7698 if (http_hdr) free(http_hdr);
7699 if (http_user) free(http_user);
7700 if (http_pass) {
7701 memset(http_pass,0,strlen(http_pass));
7702 free(http_pass);
7703 }
7704 if (http_mime) free(http_mime);
7705 if (http_lfile) free(http_lfile);
7706 if (http_rfile) free(http_rfile);
7707 if (http_dfile) free(http_dfile);
7708 if (http_host) free(http_host);
7709 if (http_srv) free(http_srv);
7710
7711 if (x > -1)
7712 success = x;
7713 return(x);
7714 }
7715 #endif /* TCPSOCKET */
7716 #endif /* NOHTTP */
7717
7718
7719 #ifndef NOSPL
7720 static int
dotrace()7721 dotrace() {
7722 int on = 1;
7723 struct FDB sw, kw;
7724 cmfdbi(&sw, /* 1st FDB - switch */
7725 _CMKEY, /* fcode */
7726 "Trace object;\n Or switch", /* help */
7727 "", /* default */
7728 "", /* addtl string data */
7729 2, /* keyword table size */
7730 4, /* addtl numeric data 2: 4 = cmswi */
7731 xxstring, /* Processing function */
7732 onoffsw, /* Keyword table */
7733 &kw /* Pointer to next FDB */
7734 );
7735 cmfdbi(&kw, /* 2nd FDB - Trace object */
7736 _CMKEY, /* fcode */
7737 "Trace object", /* help */
7738 "all", /* default */
7739 "", /* addtl string data */
7740 ntracetab, /* keyword table size */
7741 0, /* addtl numeric data 2: 0 = keyword */
7742 xxstring, /* Processing function */
7743 tracetab, /* Keyword table */
7744 NULL /* Pointer to next FDB */
7745 );
7746 if ((x = cmfdb(&sw)) < 0)
7747 return(x);
7748 if (cmresult.fdbaddr == &sw) {
7749 on = cmresult.nresult;
7750 if ((x = cmkey(tracetab, ntracetab,"","all",xxstring)) < 0)
7751 return(x);
7752 } else {
7753 x = cmresult.nresult;
7754 }
7755 if ((y = cmcfm()) < 0)
7756 return(y);
7757
7758 switch (x) {
7759 case TRA_ASG:
7760 tra_asg = on;
7761 break;
7762 case TRA_CMD:
7763 tra_cmd = on;
7764 break;
7765 case TRA_ALL:
7766 tra_asg = on;
7767 tra_cmd = on;
7768 break;
7769 default:
7770 return(-2);
7771 }
7772 printf("TRACE %s\n", on ? "ON" : "OFF");
7773 return(success = 1);
7774 }
7775 #endif /* NOSPL */
7776
7777
7778 static int
doprompt()7779 doprompt() {
7780 extern int xcmdsrc;
7781 if ((x = cmtxt("Optional message","",&s,xxstring)) < 0)
7782 return(x);
7783 #ifdef NOSPL
7784 printf("?Sorry, PROMPT requires script programming language\n");
7785 return(-9);
7786 #else
7787 debug(F101,"Prompt cmdlvl","",cmdlvl);
7788 cmdlvl++;
7789 if (cmdlvl > CMDSTKL) {
7790 printf("?Command stack overflow: %d\n",cmdlvl);
7791 cmdlvl--;
7792 return(-9);
7793 }
7794 xcmdsrc = CMD_KB;
7795 cmdstk[cmdlvl].src = CMD_KB; /* Say we're at the prompt */
7796 cmdstk[cmdlvl].lvl = 0;
7797 cmdstk[cmdlvl].ccflgs = cmdstk[cmdlvl-1].ccflgs;
7798 if (tra_cmd)
7799 printf("[%d] +P: \"(prompt)\"\n",cmdlvl);
7800 concb((char)escape);
7801 if (!quiet)
7802 printf(
7803 "(Recursive command prompt: Resume script with CONTINUE, STOP to stop...)\n"
7804 );
7805 if (*s) { /* If prompt given */
7806 makestr(&(prstring[cmdlvl-1]),cmgetp()); /* Save current prompt */
7807 cmsetp(s); /* Set new one */
7808 }
7809 return(success = 1);
7810 #endif /* NOSPL */
7811 }
7812
7813 #ifdef CKLEARN
7814 VOID
learncmd(s)7815 learncmd(s) char *s; { /* Record commands in learned script */
7816 char buf[64];
7817 int i, k;
7818 if (learnfp && learning) { /* Only if open and on */
7819 k = ckstrncpy(buf,s,64);
7820 for (i = 0; i < k; i++) { /* Get top-level command keyword */
7821 if (buf[i] <= SP) {
7822 buf[i] = NUL;
7823 break;
7824 }
7825 }
7826 k = lookup(cmdtab,buf,ncmd,NULL); /* Look it up */
7827 if (k == XXCON || k == XXLEARN) /* Don't record CONNECT or LEARN */
7828 return;
7829 if (k == XXTEL) {
7830 fputs("SET HOST /NETWORK:TCP",learnfp);
7831 fputs(&s[i],learnfp);
7832 fputs(" TELNET /TELNET",learnfp);
7833 fputs("\nIF FAIL STOP 1 Connection failed\n",learnfp);
7834 } else {
7835 fputs(s,learnfp);
7836 fputs("\n",learnfp);
7837 }
7838 }
7839 }
7840 #endif /* CKLEARN */
7841
7842
7843 #ifdef SSHCMD
7844 /*
7845 2010/03/01...
7846 Reopen a connection that was made with an external ssh client
7847 after it has been closed.
7848 */
7849 int
redossh()7850 redossh() {
7851 int x, netsave;
7852 x = nettype;
7853 debug(F111,"redossh nettype",ttname,nettype);
7854 if ((y = setlin(XXSSH,0,1)) < 0) {
7855 if (errno)
7856 printf("?%s\n",ck_errstr());
7857 else
7858 return(y);
7859 nettype = x; /* Failed, restore net type. */
7860 success = 0;
7861 return(y);
7862 }
7863 netsave = x;
7864 return(y);
7865 }
7866 #endif /* SSHCMD */
7867
7868 /*
7869 Like hmsga() in ckuus2.c but takes a single substitution parameter, s2,
7870 which replaces every occurrence of "%s" in the first argument.
7871 Added to print text containing the copyright year, so the year doesn't
7872 have to be hardwired into lots of scattered text strings.
7873 */
7874 int /* Print an array of lines, */
7875 #ifdef CK_ANSIC
hmsgaa(char * s[],char * s2)7876 hmsgaa(char *s[], char *s2) /* pausing at end of each screen. */
7877 #else
7878 hmsgaa(s,s2) char *s[]; char *s2;
7879 #endif /* CK_ANSIC */
7880 {
7881 extern int hmtopline;
7882 #ifdef OS2
7883 extern int tt_rows[], tt_cols[];
7884 #else /* OS2 */
7885 extern int tt_rows, tt_cols;
7886 #endif /* OS2 */
7887 int x, y, i, j, k, n;
7888 if ((x = cmcfm()) < 0) return(x);
7889
7890 #ifdef CK_TTGWSIZ
7891 #ifdef OS2
7892 ttgcwsz();
7893 #else /* OS2 */
7894 /* Check whether window size changed */
7895 if (ttgwsiz() > 0) {
7896 if (tt_rows > 0 && tt_cols > 0) {
7897 cmd_rows = tt_rows;
7898 cmd_cols = tt_cols;
7899 }
7900 }
7901 #endif /* OS2 */
7902 #endif /* CK_TTGWSIZ */
7903
7904 printf("\n"); /* Start off with a blank line */
7905 n = (hmtopline > 0) ? hmtopline : 1; /* Line counter */
7906 for (i = 0; *s[i]; i++) {
7907 printf((char *)s[i],s2); /* Print a line. */
7908 printf("\n");
7909 y = (int)strlen(s[i]);
7910 k = 1;
7911 for (j = 0; j < y; j++) /* See how many newlines were */
7912 if (s[i][j] == '\n') k++; /* in the string... */
7913 n += k;
7914 if (n > (cmd_rows - 3) && *s[i+1]) /* After a screenful, give them */
7915 if (!askmore()) return(0); /* a "more?" prompt. */
7916 else n = 0;
7917 }
7918 printf("\n");
7919 return(0);
7920 }
7921
7922 /* I S I N T E R N A L M A C R O -- April 2017 */
7923
7924 int
isinternalmacro(x)7925 isinternalmacro(x) int x; { /* Test if macro is internally defined */
7926 char * m;
7927 char * tags[] = { "_whi", "_for", "_sw_", "_if_" };
7928 int i, internal = 0;
7929
7930 m = mactab[x].kwd;
7931
7932 #ifdef COMMENT
7933 /* Good idea but this flag is not set for _whi2, etc */
7934 internal = ((cmdstk[cmdlvl].ccflgs & CF_IMAC) ? 1 : 0);
7935 debug(F111,"isinternalmacro",m,internal);
7936 return(internal);
7937 #endif /* COMMENT */
7938
7939 debug(F101,"isinternalmacro x","",x);
7940 if (*m != '_') {
7941 debug(F110," not internal",m,0);
7942 return(0);
7943 }
7944 if (!m) m = "";
7945 if (*m) {
7946 debug(F110," macro name",m,0);
7947 internal = ckindex(m,"|_while|_forx|_forz|_xif|_switx|",0,0,0);
7948 debug(F111," internal macro","A",internal);
7949 if (!internal) {
7950 int i, j, n, len = 0;
7951 n = -1;
7952 for (i = 0; i < sizeof(* tags); i++) {
7953 if (ckindex(tags[i],m,0,0,0)) {
7954 n = i;
7955 break;
7956 }
7957 }
7958 debug(F111," tags index",tags[n],n);
7959 if (n > -1) {
7960 char * tag = tags[i];
7961 len = (int)strlen(tag);
7962 debug(F111," tag len",tag,len);
7963 for (i = len; m[i]; i++) {
7964 debug(F101," loop i","",i);
7965 debug(F000," char","",m[i]);
7966 if (!isdigit(m[i])) {
7967 internal = 0;
7968 break;
7969 } else {
7970 internal = 1;
7971 }
7972 }
7973 }
7974 debug(F101," internal macro","B",internal);
7975 }
7976 }
7977 return(internal);
7978 }
7979
7980 /* N E W E R R M S G -- New error message routine, April 2017 */
7981
7982 #define ERRMSGBUFSIZ 320
7983 static char errmsgbuf[ERRMSGBUFSIZ] = { '\0' };
7984
newerrmsg(s)7985 VOID newerrmsg(s) char *s; {
7986 char * tmperrbuf[ERRMSGBUFSIZ];
7987
7988 extern char lasttakeline[];
7989 extern char *tfnam[];
7990 extern int tfblockstart[];
7991 extern int tlevel;
7992 int len1, len2, len3, len4, len5;
7993 char * buf = errmsgbuf;
7994 char * takefile = getbasename(tfnam[tlevel]);
7995 char nbuf[20];
7996 char * lineno = nbuf;
7997 int x;
7998
7999 debug(F110,"newerrmsg",s,0);
8000 ckstrncpy(nbuf,ckitoa(tfblockstart[tlevel]),20);
8001 lineno = (char *)nbuf;
8002
8003 if (!s) s = "";
8004 if (!*s) s = "Syntax error";
8005
8006 if (tlevel < 0) {
8007 printf("?%s\n",s);
8008 return;
8009 }
8010 len1 = (int)strlen(s);
8011 len2 = (int)strlen(takefile);
8012 len3 = (int)strlen(lineno);
8013 len4 = (int)strlen((char *)lasttakeline);
8014 len5 = len1 + len2 + len3 + 12;
8015
8016 x = 80 - len5; /* Free space for beginning of offending command */
8017 if (x > len4) { /* Free space is greater than command length */
8018 #ifdef HAVE_SNPRINTF
8019 snprintf((char *)tmperrbuf,ERRMSGBUFSIZ,"?%s[%s]: \"%s\": %s\n",
8020 takefile,
8021 lineno,
8022 (char *)lasttakeline,
8023 s
8024 );
8025 #else
8026 sprintf((char *)tmperrbuf,"?%s[%s]: \"%s\": %s\n",
8027 takefile,
8028 lineno,
8029 (char *)lasttakeline,
8030 s
8031 );
8032 #endif /* HAVE_SNPRINTF */
8033
8034 } else if (x > 40) {
8035 char c;
8036 c = lasttakeline[x];
8037 lasttakeline[x] = NUL;
8038 #ifdef HAVE_SNPRINTF
8039 snprintf((char *)tmperrbuf,ERRMSGBUFSIZ,"?%s[%s]: \"%s...\": %s\n",
8040 takefile, lineno, (char *)lasttakeline, s);
8041 #else
8042 sprintf((char *)tmperrbuf,"?%s[%s]: \"%s...\": %s\n",
8043 takefile, lineno, (char *)lasttakeline, s);
8044 #endif /* HAVE_SNPRINTF */
8045 lasttakeline[x] = c;
8046 } else {
8047 char c;
8048 if (len4 > 74) {
8049 x = 74 - (len2 + len3 + 8);
8050 c = lasttakeline[x];
8051 lasttakeline[x] = NUL;
8052 #ifdef HAVE_SNPRINTF
8053 snprintf((char *)tmperrbuf,ERRMSGBUFSIZ,
8054 "?%s[%s]: \"%s...\":\n Error: %s\n",
8055 takefile, lineno, (char *)lasttakeline, s);
8056 #else
8057 sprintf((char *)tmperrbuf,"?%s[%s]: \"%s...\":\n Error: %s\n",
8058 takefile, lineno, (char *)lasttakeline, s);
8059
8060 #endif /* HAVE_SNPRINTF */
8061 lasttakeline[x] = c;
8062 } else {
8063 #ifdef HAVE_SNPRINTF
8064 snprintf((char *)tmperrbuf,ERRMSGBUFSIZ,
8065 "?%s[%s]: \"%s\":\n %s\n",
8066 takefile, lineno, (char *)lasttakeline, s);
8067 #else
8068 sprintf((char *)tmperrbuf,"?%s[%s]: \"%s\":\n %s\n",
8069 takefile, lineno, (char *)lasttakeline, s);
8070 #endif /* HAVE_SNPRINTF */
8071 }
8072 }
8073 xnewerrmsg:
8074 /* Print the message only if it's not the same as the last one */
8075 if (ckstrcmp((char *)errmsgbuf,(char *)tmperrbuf,ERRMSGBUFSIZ,1)) {
8076 ckstrncpy((char *)errmsgbuf,(char *)tmperrbuf,ERRMSGBUFSIZ);
8077 printf("%s",(char *)errmsgbuf);
8078 }
8079 return;
8080 }
8081
8082 /* D O C M D -- Do a command */
8083
8084 /*
8085 Returns:
8086 -2: user typed an illegal command
8087 -1: reparse needed
8088 0: parse was successful (even tho command may have failed).
8089 */
8090 #ifdef DEBUG
8091 int cmdstats[256] = { -1, -1 };
8092 #endif /* DEBUG */
8093
8094 int
docmd(cx)8095 docmd(cx) int cx; {
8096 extern int nolocal, cmkwflgs;
8097
8098 debug(F101,"docmd entry, cx","",cx);
8099 activecmd = cx;
8100 doconx = ((activecmd == XXCON) || (activecmd == XXTEL) ||
8101 (activecmd == XXRLOG) || (activecmd == XXPIPE) ||
8102 (activecmd == XXIKSD) || (activecmd == XXPTY));
8103 /*
8104 Originally all commands were handled with a big switch() statement,
8105 but eventually this started blowing up compilers. Now we have a series
8106 of separate if statements and small switches, with the commands that are
8107 most commonly executed in scripts and loops coming first, to speed up
8108 compute-bound scripts.
8109 */
8110
8111 #ifdef DEBUG
8112 if (cmdstats[0] == -1) { /* Count commands */
8113 int i; /* for tuning... */
8114 for (i = 0; i < 256; i++)
8115 cmdstats[i] = 0;
8116 }
8117 #endif /* DEBUG */
8118
8119 switch (cx) {
8120 case -4: /* EOF */
8121 #ifdef OSK
8122 if (msgflg) printf("\n");
8123 #else
8124 if (msgflg) printf("\r\n");
8125 #endif /* OSK */
8126 doexit(GOOD_EXIT,xitsta);
8127 case -3: /* Null command */
8128 return(0);
8129 case -9: /* Like -2, but errmsg already done */
8130 case -1: /* Reparse needed */
8131 return(cx);
8132 case -6: /* Special */
8133 case -2: /* Error, maybe */
8134
8135 #ifndef NOSPL
8136 /*
8137 Maybe they typed a macro name. Let's look it up and see.
8138 */
8139 if (cx == -6) /* If they typed CR */
8140 ckstrncat(cmdbuf,"\015",CMDBL); /* add it back to command buffer. */
8141 if (ifcmd[cmdlvl] == 2) /* Watch out for IF commands. */
8142 ifcmd[cmdlvl]--;
8143 repars = 1; /* Force reparse */
8144 cmres();
8145 cx = XXDO; /* Try DO command */
8146 #else
8147 return(cx);
8148 #endif /* NOSPL */
8149 default:
8150 if (cx < 0)
8151 return(cx);
8152 break;
8153 }
8154 #ifdef DEBUG
8155 if (cx < 256)
8156 cmdstats[cx]++;
8157 #endif /* DEBUG */
8158
8159 if ((cmkwflgs & CM_PSH)
8160 #ifndef NOPUSH
8161 && nopush
8162 #endif /* NOPUSH */
8163 ) {
8164 printf("?Access to system disabled\n");
8165 return(-9);
8166 }
8167 if ((cmkwflgs & CM_LOC)
8168 #ifndef NOLOCAL
8169 && nolocal
8170 #endif /* NOLOCAL */
8171 ) {
8172 printf("?Connections disabled\n");
8173 return(-9);
8174 }
8175
8176 #ifndef NOSPL
8177 /* Used in FOR loops */
8178
8179 if (cx == XX_INCR || cx == XXINC || /* _INCREMENT, INCREMENT */
8180 cx == XX_DECR || cx == XXDEC) /* _DECREMENT, DECREMENT */
8181 return(doincr(cx));
8182
8183 /* Define (or change the definition of) a macro or variable */
8184
8185 if (cx == XXUNDEF || cx == XXUNDFX) {
8186 #ifdef IKSD
8187 if (inserver && !ENABLED(en_asg)) {
8188 printf("?Sorry, DEFINE/ASSIGN disabled\n");
8189 return(-9);
8190 }
8191 #endif /* IKSD */
8192 return(doundef(cx)); /* [_]UNDEFINE */
8193 }
8194 if (cx == XXDEF || cx == XXASS ||
8195 cx == XXDFX || cx == XXASX) {
8196 #ifdef IKSD
8197 if (inserver && !ENABLED(en_asg)) {
8198 printf("?Sorry, DEFINE/ASSIGN disabled\n");
8199 return(-9);
8200 }
8201 #endif /* IKSD */
8202 if (atmbuf[0] == '.' && !atmbuf[1]) /* "." entered as keyword */
8203 xxdot = 1; /* i.e. with space after it... */
8204 return(dodef(cx)); /* DEFINE, ASSIGN, etc... */
8205 }
8206
8207 /* IF, WHILE, and friends */
8208
8209 if (cx == XXIF || cx == XXIFX || cx == XXWHI || cx == XXASSER) {
8210 return(doif(cx));
8211 }
8212 if (cx == XXSWIT) { /* SWITCH */
8213 return(doswitch());
8214 }
8215
8216 /* GOTO, FORWARD, and _FORWARD (used internally by FOR, WHILE, etc) */
8217
8218 if (cx == XXGOTO || cx == XXFWD || cx == XXXFWD) { /* GOTO or FORWARD */
8219 /* Note, here we don't set SUCCESS/FAILURE flag */
8220 #ifdef COMMENT
8221 if ((y = cmfld("label","",&s,xxstring)) < 0) {
8222 if (y == -3) {
8223 if (cx != XXXFWD) {
8224 printf("?Label name required\n");
8225 return(-9);
8226 }
8227 } else
8228 return(y);
8229 }
8230 ckstrncpy(tmpbuf,s,TMPBUFSIZ);
8231 if ((x = cmcfm()) < 0) return(x);
8232 #else
8233 if ((y = cmtxt("label","",&s,xxstring)) < 0) {
8234 if (y == -3) {
8235 if (cx != XXXFWD) {
8236 printf("?GOTO: Label name required: \"%s\" \"%s\"\n",
8237 atmbuf,
8238 cmdbuf);
8239 return(-9);
8240 }
8241 } else
8242 return(y);
8243 }
8244 ckstrncpy(tmpbuf,brstrip(s),TMPBUFSIZ);
8245 #endif /* COMMENT */
8246 s = tmpbuf;
8247 debug(F111,"GOTO target",s,cx);
8248 return(dogoto(s,cx));
8249 }
8250 if (cx == XXDO || cx == XXMACRO) { /* DO (a macro) */
8251 char mnamebuf[16]; /* (buffer for controlled temp name) */
8252 struct FDB kw, fl;
8253 int mx; /* Macro index (on stack!) */
8254
8255 debug(F101,"XXMACRO 0",line,cx);
8256 if (cx == XXDO) {
8257 if (nmac == 0) {
8258 printf("\n?No macros defined\n");
8259 return(-9);
8260 }
8261 for (y = 0; y < nmac; y++) { /* copy the macro table into a */
8262 mackey[y].kwd = mactab[y].kwd; /* regular keyword table */
8263 mackey[y].kwval = y; /* with value = pointer to macro tbl */
8264 mackey[y].flgs = mactab[y].flgs;
8265 }
8266 cmfdbi(&kw, /* First FDB - macro name */
8267 _CMKEY, /* fcode */
8268 "Macro", /* hlpmsg */
8269 "", /* default */
8270 "", /* addtl string data */
8271 nmac, /* addtl numeric data 1: tbl size */
8272 0, /* addtl numeric data 2: 0 = cmkey */
8273 xxstring, /* Processing function */
8274 mackey, /* Keyword table */
8275 &fl /* Pointer to next FDB */
8276 );
8277 cmfdbi(&fl, /* 2nd FDB - for "{" */
8278 _CMFLD, /* fcode */
8279 "", /* hlpmsg */
8280 "",
8281 "", /* addtl string data */
8282 0, /* addtl numeric data 1 */
8283 0, /* addtl numeric data 2 */
8284 xxstring,
8285 NULL,
8286 NULL
8287 );
8288 x = cmfdb(&kw); /* Parse something */
8289 if (x < 0) { /* Error */
8290 if (x == -3) {
8291 printf("?Macro name required\n");
8292 return(-9);
8293 } else
8294 return(x);
8295 }
8296 if (cmresult.fcode == _CMKEY) {
8297 extern int mtchanged;
8298 char * macroname = NULL;
8299
8300 /* In case args include an \fexec() that changes the macro table */
8301
8302 mx = x; /* Save macro index on stack */
8303 mtchanged = 0; /* Mark state of macro table */
8304 makestr(¯oname,mactab[mx].kwd); /* Save name */
8305
8306 /*
8307 Prior to C-Kermit 9.0.304 Dev.22, April 23, 2017, cmtxt() was called in
8308 all cases with zzstring. But this fouled up the identification of macro
8309 arguments when their values contained grouping characters such as
8310 doublequotes and braces. Now we defer the evaluation of the macro
8311 arguments until after the arguments themselves have been correctly
8312 identified. An exception is made for the internal macros that implement
8313 the FOR, WHILE, IF, and SWITCH commands.
8314 */
8315 if (isinternalmacro(x)) {
8316 debug(F100,"DO parser internal macro","",0);
8317 if ((y = cmtxt("optional arguments","",&s,zzstring)) < 0)
8318 return(y); /* Get macro args */
8319 } else {
8320 debug(F100,"DO parser normal macro","",0);
8321 if ((y = cmtxt("optional arguments","",&s,NULL)) < 0)
8322 return(y); /* Get macro args */
8323 }
8324 if (mtchanged) { /* Macro table changed? */
8325 mx = mlook(mactab,macroname,nmac); /* Look up name again */
8326 }
8327 if (macroname)
8328 free(macroname);
8329
8330 return(dodo(mx,s,cmdstk[cmdlvl].ccflgs) < 1 ?
8331 (success = 0) : 1);
8332 }
8333 ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* _CMFLD */
8334 if (atmbuf[0] == '{') {
8335 if ((y = cmcfm()) < 0)
8336 return(y);
8337 }
8338 } else { /* XXMACRO ("immediate macro") */
8339 int k = 0;
8340 line[k++] = '{';
8341 line[k++] = SP;
8342 line[k] = NUL;
8343 debug(F111,"XXMACRO A",line,k);
8344 if ((y = cmtxt("Braced list of commands","",&s,xxstring)) < 0)
8345 return(y);
8346 k = ckstrncpy(line+k,s,LINBUFSIZ-k);
8347 debug(F111,"XXMACRO B",line,k);
8348 }
8349 x = strlen(line);
8350 if ((line[0] == '{' && line[x-1] != '}') || line[0] == '}')
8351 return(-2);
8352 if (line[0] != '{' && line[x-1] != '}') {
8353 /* Unknown command. If ON_UNKNOWN_COMMAND macro is defined, */
8354 /* parse args and then execute it, but only if it is not */
8355 /* already active. */
8356 int k = -1;
8357 if (!unkmacro) {
8358 k = mxlook(mactab,"on_unknown_command",nmac);
8359 }
8360 if (k > -1) {
8361 ckstrncpy(tmpbuf,atmbuf,TMPBUFSIZ);
8362 z = maclvl; /* Save the current maclvl */
8363 if ((y = cmtxt("text","",&s,xxstring)) < 0)
8364 return(y);
8365 ckstrncat(tmpbuf," ",TMPBUFSIZ);
8366 ckstrncat(tmpbuf,s,TMPBUFSIZ);
8367 unkmacro = 1;
8368 debug(F110,"ON_UNKNOWN_COMMAND",s,0);
8369 dodo(k,tmpbuf,cmdstk[cmdlvl].ccflgs); /* Run the macro */
8370 while (maclvl > z) {
8371 sstate = (CHAR) parser(1);
8372 if (sstate) proto();
8373 }
8374 debug(F101,"UNKMAC loop exit maclvl","",maclvl);
8375 unkmacro = 0;
8376 return(success);
8377 }
8378 if (x > 0)
8379 printf("?Not a command or macro name: \"%s\"\n",line);
8380 else
8381 printf("?Not a command or macro name.\n");
8382 return(-9);
8383 }
8384 s = brstrip(line);
8385 sprintf(mnamebuf," ..tmp:%03d",cmdlvl); /* safe (16) */
8386 x = addmac(mnamebuf,s);
8387 return(dodo(x,NULL,cmdstk[cmdlvl].ccflgs) < 1 ? (success = 0) : 1);
8388 }
8389
8390 if (cx == XXLBL) { /* LABEL */
8391 if ((x = cmfld("label","",&s,xxstring)) < 0) {
8392 if (x == -3) {
8393 #ifdef COMMENT
8394 printf("?LABEL: Label name required: \"%s\"\n", cmdbuf);
8395 return(-9);
8396 #else
8397 s = "";
8398 #endif /* COMMENT */
8399 } else return(x);
8400
8401 }
8402 debug(F111,"LABEL",s,x);
8403 if ((x = cmcfm()) < 0) return(x);
8404 return(0);
8405 }
8406
8407 if (cx == XXEVAL || cx == XX_EVAL) /* _EVALUATE, EVALUATE */
8408 return(doeval(cx));
8409
8410 #ifndef NOSEXP
8411 if (cx == XXSEXP) { /* Lisp-like S-Expression */
8412 struct stringarray * q;
8413 char /* *p, *r, */ *tmp, *m;
8414 int i, k, n, quote = 0, contd = 0, size = 0, len = 0;
8415 extern int sexprc, sexppv;
8416
8417 tmp = tmpbuf; /* Buffer to collect SEXP */
8418 tmpbuf[0] = NUL; /* Clear it */
8419 size = TMPBUFSIZ; /* Capacity of buffer */
8420 sexprc = -1; /* Assume bad input */
8421 n = 0; /* Paren balance counter */
8422
8423 while (1) { /* Allow SEXP on multiple lines */
8424 m = contd ?
8425 "Continuation of S-Expression" :
8426 "S-Expression (\"help sexp\" for details)";
8427 x = cmtxt(m,"",&s,xxstring);
8428 if (x < 0)
8429 return(x);
8430 if (!*s) /* Needed for (=) and (:) */
8431 s = cmdbuf+1; /* I can't explain why. */
8432 k = ckmakmsg(tmp, size, contd ? " " : "(", s, NULL, NULL);
8433 if (k < 1) {
8434 printf("?SEXP too long - %d max\n",TMPBUFSIZ);
8435 return(-9);
8436 }
8437 debug(F111,contd ? "sexp contd" : "sexp",s,k);
8438
8439 for (i = len; i < len+k; i++) { /* Check balance */
8440 if (!quote && tmpbuf[i] == CMDQ) {
8441 quote = 1;
8442 continue;
8443 }
8444 if (quote) {
8445 quote = 0;
8446 continue;
8447 }
8448 if (tmpbuf[i] == '(')
8449 n++;
8450 else if (tmpbuf[i] == ')')
8451 n--;
8452 }
8453 if (n == 0) { /* Break when balanced */
8454 break;
8455 }
8456 if (n < 0) { /* Too many right parens */
8457 printf("?Unbalanced S-Expression: \"%s\"\n",tmpbuf);
8458 return(-9);
8459 }
8460 contd++; /* Need more right parens */
8461 cmini(ckxech); /* so keep parsing */
8462 tmp += k; /* adjust buffer pointer */
8463 size -= k; /* and capacity */
8464 len += k; /* and length so far */
8465 }
8466 s = tmpbuf;
8467 makestr(&lastsexp,s);
8468 q = cksplit(1,SEXPMAX,s,NULL,NULL,8,0,0,0); /* Precheck for > 1 SEXP */
8469 debug(F101,"sexp split","",q->a_size);
8470
8471 if (q->a_size == 1) { /* We should get exactly one back */
8472 char * result, * dosexp();
8473 sexprc = 0; /* Reset out-of-band return code */
8474 result = dosexp(s); /* Get result */
8475 debug(F111,"sexp result",result,sexprc);
8476 if (sexprc == 0) { /* Success */
8477 /* Echo the result if desired */
8478 if ((!xcmdsrc && sexpecho != SET_OFF) || sexpecho == SET_ON)
8479 if (result) if (*result)
8480 printf(" %s\n",result);
8481 makestr(&sexpval,result);
8482 success = sexppv > -1 ? sexppv : 1;
8483 return(success);
8484 }
8485 }
8486 if (sexprc < 0)
8487 printf("?Invalid S-Expression: \"%s\"\n",lastsexp);
8488 return(-9);
8489 }
8490 #endif /* NOSEXP */
8491
8492 #endif /* NOSPL */
8493
8494 if (cx == XXECH || cx == XXXECH || cx == XXVOID
8495 #ifndef NOSPL
8496 || cx == XXAPC
8497 #endif /* NOSPL */
8498 ) { /* ECHO or APC */
8499 if ((x = cmtxt((cx == XXECH || cx == XXXECH) ?
8500 "Text to be echoed" :
8501 ((cx == XXVOID) ? "Text" :
8502 "Application Program Command text"),
8503 "",
8504 &s,
8505 xxstring
8506 )
8507 ) < 0)
8508 return(x);
8509 if (!s) s = "";
8510 #ifdef COMMENT
8511 /* This is to preserve the pre-8.0 behavior but it's too confusing */
8512 x = strlen(s);
8513 x = (x > 1) ? ((s[0] == '"' && s[x-1] == '"') ? 1 : 0) : 0;
8514 #endif /* COMMENT */
8515 s = brstrip(s); /* Strip braces and doublequotes */
8516 if (cx == XXECH) { /* ECHO */
8517 #ifndef NOSPL
8518 if (!fndiags || fnsuccess) {
8519 #endif /* NOSPL */
8520 #ifdef COMMENT
8521 /* The "if (x)" business preserves previous behavior */
8522 /* by putting back the doublequotes if they were included. */
8523 if (x)
8524 printf("\"%s\"\n",s);
8525 else
8526 #endif /* COMMENT */
8527 printf("%s\n",s);
8528 #ifndef NOSPL
8529 }
8530 #endif /* NOSPL */
8531 } else if (cx == XXXECH) { /* XECHO */
8532 if (x)
8533 printf("\"%s\"",s);
8534 else
8535 printf("%s",s);
8536 #ifdef UNIX
8537 fflush(stdout);
8538 #endif /* UNIX */
8539 } else if (cx == XXAPC) { /* APC */
8540 #ifdef CK_APC
8541 if (apcactive == APC_LOCAL ||
8542 (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH)))
8543 return(success = 0);
8544 #endif /* CK_APC */
8545 if (!local) {
8546 printf("%c_%s%c\\",ESC,s,ESC);
8547 #ifdef UNIX
8548 fflush(stdout);
8549 #endif /* UNIX */
8550
8551 } else { /* Local mode - have connection */
8552 #ifndef NOSPL
8553 if (ckmakxmsg(tmpbuf, /* Form APC string in buffer */
8554 TMPBUFSIZ,
8555 ckctoa((char)ESC),
8556 ckctoa('_'),
8557 s,
8558 ckctoa((char)ESC),
8559 ckctoa('\\'),
8560 NULL,NULL,NULL,NULL,NULL,NULL,NULL
8561 ) > 0)
8562 return(success = dooutput(tmpbuf, XXOUT));
8563 printf("?Too long\n");
8564 return(-9);
8565 #else
8566 printf("%c_%s%c\\",ESC,s,ESC);
8567 #endif /* NOSPL */
8568 }
8569 }
8570 return(success = 1);
8571 }
8572
8573 #ifndef NOSPL
8574 /* Copy macro args from/to two levels up, used internally by _floop et al. */
8575 if (cx == XXGTA || cx == XXPTA) { /* _GETARGS, _PUTARGS */
8576 int x;
8577 debug(F101,"docmd XXGTA","",XXGTA);
8578 debug(F101,"docmd cx","",cx);
8579 debug(F101,"docmd XXGTA maclvl","",maclvl);
8580 x = dogta(cx);
8581 debug(F101,"docmd dogta returns","",x);
8582 debug(F101,"docmd dogta maclvl","",maclvl);
8583 return(x);
8584 }
8585 #endif /* NOSPL */
8586
8587 #ifndef NOSPL
8588 #ifdef CKCHANNELIO
8589 if (cx == XXFILE)
8590 return(dofile(cx));
8591 else if (cx == XXF_RE || cx == XXF_WR || cx == XXF_OP ||
8592 cx == XXF_CL || cx == XXF_SE || cx == XXF_RW ||
8593 cx == XXF_FL || cx == XXF_LI || cx == XXF_ST || cx == XXF_CO)
8594 return(dofile(cx));
8595 #endif /* CKCHANNELIO */
8596
8597 /* ASK, ASKQ, READ */
8598 if (cx == XXASK || cx == XXASKQ || cx == XXREA ||
8599 cx == XXRDBL || cx == XXGETC || cx == XXGETK) {
8600 return(doask(cx));
8601 }
8602 #endif /* NOSPL */
8603
8604 #ifndef NOFRILLS
8605 #ifndef NOHELP
8606 if (cx == XXBUG) { /* BUG */
8607 if ((x = cmcfm()) < 0) return(x);
8608 return(dobug());
8609 }
8610 #endif /* NOHELP */
8611 #endif /* NOFRILLS */
8612
8613 #ifndef NOXFER
8614 if (cx == XXBYE) { /* BYE */
8615 extern int ftp_cmdlin;
8616 if ((x = cmcfm()) < 0) return(x);
8617
8618 #ifdef NEWFTP
8619 if ((ftpget == 1) || ((ftpget == 2) && ftpisopen())) {
8620 extern int stayflg, ftp_fai;
8621 success = ftpbye();
8622 if (ftp_cmdlin && !stayflg && !local)
8623 doexit(ftp_fai ? BAD_EXIT : GOOD_EXIT,-1);
8624 else
8625 return(success);
8626 }
8627 #endif /* NEWFTP */
8628
8629 if (!local) {
8630 printf("?No connection - use EXIT to quit.\n");
8631 return(-9);
8632 }
8633
8634 #ifdef CK_XYZ
8635 if (protocol != PROTO_K) {
8636 printf("?Sorry, BYE only works with Kermit protocol\n");
8637 return(-9);
8638 }
8639 #endif /* CK_XYZ */
8640
8641 #ifdef IKS_OPTION
8642 if (
8643 #ifdef CK_XYZ
8644 protocol == PROTO_K &&
8645 #endif /* CK_XYZ */
8646 !iks_wait(KERMIT_REQ_START,1)) {
8647 printf(
8648 "?A Kermit Server is not available to process this command\n");
8649 return(-9); /* Correct the return code */
8650 }
8651 #endif /* IKS_OPTION */
8652
8653 bye_active = 1;
8654 sstate = setgen('L',"","","");
8655 if (local) ttflui(); /* If local, flush tty input buffer */
8656 return(0);
8657 }
8658 #endif /* NOXFER */
8659
8660 if (cx == XXBEEP) { /* BEEP */
8661 int x;
8662 #ifdef OS2
8663 int y;
8664 if ((y = cmkey(beeptab, nbeeptab, "which kind of beep", "information",
8665 xxstring)) < 0 )
8666 return (y);
8667 if ((x = cmcfm()) < 0) return(x);
8668 bleep((short)y); /* y is one of the BP_ values */
8669 #else /* OS2 */
8670 if ((x = cmcfm()) < 0) return(x);
8671 #ifndef NOSPL
8672 bleep(BP_NOTE);
8673 #else
8674 putchar('\07');
8675 #endif /* NOSPL */
8676 #endif /* OS2 */
8677 return(0);
8678 }
8679
8680 #ifndef NOFRILLS
8681 if (cx == XXCLE) /* CLEAR */
8682 return(success = doclear());
8683 #endif /* NOFRILLS */
8684
8685 if (cx == XXCOM) { /* COMMENT */
8686 if ((x = cmtxt("Text of comment line","",&s,NULL)) < 0)
8687 return(x);
8688 /* Don't change SUCCESS flag for this one */
8689 return(0);
8690 }
8691
8692 #ifndef NOLOCAL
8693 if (cx == XXCON || cx == XXCQ) /* CONNECT or CONNECT /QUIETLY */
8694 return(doxconn(cx));
8695 #endif /* NOLOCAL */
8696
8697 #ifndef NOFRILLS
8698 #ifdef ZCOPY
8699 if (cx == XXCPY) { /* COPY a file */
8700 #ifdef IKSD
8701 if (inserver && !ENABLED(en_cpy)) {
8702 printf("?Sorry, COPY is disabled\n");
8703 return(-9);
8704 }
8705 #endif /* IKSD */
8706 #ifdef CK_APC
8707 if (apcactive == APC_LOCAL ||
8708 (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH))
8709 )
8710 return(success = 0);
8711 #endif /* CK_APC */
8712 return(docopy());
8713 }
8714 #endif /* ZCOPY */
8715 #ifdef NT
8716 if ( cx == XXLINK ) {
8717 #ifdef IKSD
8718 if (inserver && !ENABLED(en_cpy)) {
8719 printf("?Sorry, LINK (COPY) is disabled\n");
8720 return(-9);
8721 }
8722 #endif /* IKSD */
8723 #ifdef CK_APC
8724 if (apcactive == APC_LOCAL ||
8725 (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH))
8726 )
8727 return(success = 0);
8728 #endif /* CK_APC */
8729 return(dolink());
8730 }
8731 #endif /* NT */
8732 #endif /* NOFRILLS */
8733
8734 /* CD and friends */
8735 if (cx == XXCWD || cx == XXCDUP || cx == XXBACK ||
8736 cx == XXLCWD || cx == XXLCDU || cx == XXKCD) {
8737 #ifdef LOCUS
8738 if (!locus) {
8739 if (cx == XXCWD) {
8740 #ifdef NOXFER
8741 return(-2);
8742 #else
8743 return(dormt(XZCWD));
8744 #endif /* NOXFER */
8745 } else if (cx == XXCDUP) {
8746 #ifdef NOXFER
8747 return(-2);
8748 #else
8749 return(dormt(XZCDU));
8750 #endif /* NOXFER */
8751 }
8752 }
8753 #endif /* LOCUS */
8754 #ifdef IKSD
8755 if (inserver && !ENABLED(en_cwd)) {
8756 printf("?Sorry, changing directories is disabled\n");
8757 return(-9);
8758 }
8759 #endif /* IKSD */
8760 return(success = docd(cx));
8761 }
8762
8763 if (cx == XXCHK) /* CHECK */
8764 return(success = dochk());
8765
8766 if (cx == XXCLO) { /* CLOSE */
8767 x = cmkey(clstab,ncls,"\"CONNECTION\", or log or file to close",
8768 "connection",xxstring);
8769 if (x == -3) {
8770 printf("?You must say which file or log\n");
8771 return(-9);
8772 }
8773 if (x < 0) return(x);
8774 if ((y = cmcfm()) < 0) return(y);
8775 #ifndef NOLOCAL
8776 if (x == 9999) { /* CLOSE CONNECTION */
8777 x = clsconnx(0);
8778 switch (x) {
8779 case 0:
8780 if (msgflg) printf("?Connection was not open\n");
8781 case -1:
8782 return(0);
8783 case 1:
8784 whyclosed = WC_CLOS;
8785 return(1);
8786 }
8787 return(0);
8788 }
8789 #endif /* NOLOCAL */
8790 y = doclslog(x);
8791 success = (y == 1);
8792 return(success);
8793 }
8794
8795 #ifndef NOSPL
8796 if (cx == XXDCL || cx == XXUNDCL) { /* DECLARE an array */
8797 return(dodcl(cx));
8798 }
8799 #endif /* NOSPL */
8800
8801 #ifndef NODIAL
8802 if (cx == XXRED || cx == XXDIAL || cx == XXPDIA ||
8803 cx == XXANSW || cx == XXLOOK) { /* DIAL, REDIAL etc */
8804 #ifdef VMS
8805 extern int batch;
8806 #else
8807 #ifdef UNIXOROSK
8808 extern int backgrd;
8809 #endif /* UNIXOROSK */
8810 #endif /* VMS */
8811 x = dodial(cx);
8812 debug(F101,"dodial returns","",x);
8813 if ((cx == XXDIAL || cx == XXRED || cx == XXANSW) &&
8814 (x > 0) && /* If DIAL or REDIAL succeeded */
8815 (dialsta != DIA_PART) && /* and it wasn't partial */
8816 (dialcon > 0)) {
8817 if ((dialcon == 1 || /* And DIAL CONNECT is ON, */
8818 ((dialcon == 2) && /* or DIAL CONNECT is AUTO */
8819 !xcmdsrc /* and we're at top level... */
8820 #ifdef VMS
8821 && !batch /* Not if running from batch */
8822 #else
8823 #ifdef UNIXOROSK
8824 && !backgrd /* Not if running in background */
8825 #endif /* UNIXOROSK */
8826 #endif /* VMS */
8827 ))) /* Or AUTO */
8828 x = doconect(dialcq, /* Then also CONNECT */
8829 cmdlvl == 0 ? 1 : 0
8830 );
8831 if (ttchk() < 0)
8832 dologend();
8833 }
8834 return(success = x);
8835 }
8836 #endif /* NODIAL */
8837
8838 #ifndef NOPUSH
8839 #ifdef CK_REXX
8840 if (cx == XXREXX) { /* REXX */
8841 extern int nopush;
8842 if ( nopush )
8843 return(success=0);
8844 return(dorexx());
8845 }
8846 #endif /* CK_REXX */
8847 #endif /* NOPUSH */
8848
8849 #ifndef NOFRILLS
8850 if (cx == XXDEL || cx == XXLDEL) { /* DELETE */
8851 #ifdef LOCUS
8852 if (!locus && cx != XXLDEL) {
8853 #ifdef NOXFER
8854 return(-2);
8855 #else
8856 return(dormt(XZDEL));
8857 #endif /* NOXFER */
8858 }
8859 #endif /* LOCUS */
8860 #ifdef IKSD
8861 if (inserver && (!ENABLED(en_del)
8862 #ifdef CK_LOGIN
8863 || isguest
8864 #endif /* CK_LOGIN */
8865 )) {
8866 printf("?Sorry, DELETE is disabled\n");
8867 return(-9);
8868 }
8869 #endif /* IKSD */
8870 #ifdef CK_APC
8871 if ((apcactive == APC_LOCAL) ||
8872 ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
8873 return(success = 0);
8874 #endif /* CK_APC */
8875 return(dodel());
8876 }
8877 #endif /* NOFRILLS */
8878
8879 if (cx == XXTOUC) /* TOUCH */
8880 return(dodir(cx));
8881 if (cx == XXCHG) /* CHANGE */
8882 return(dodir(cx));
8883
8884 /* DIRECTORY commands */
8885
8886 if (cx == XXDIR || cx == XXLS || cx == XXLDIR ||
8887 cx == XXWDIR || cx == XXHDIR) {
8888 #ifdef LOCUS
8889 if (!locus && cx != XXLDIR) {
8890 #ifdef NOXFER
8891 return(-2);
8892 #else
8893 return(dormt(XZDIR));
8894 #endif /* NOXFER */
8895 }
8896 #endif /* LOCUS */
8897 #ifdef IKSD
8898 if (inserver && !ENABLED(en_dir)) {
8899 printf("?Sorry, DIRECTORY is disabled\n");
8900 return(-9);
8901 }
8902 #endif /* IKSD */
8903 return(dodir(cx));
8904 }
8905
8906 #ifndef NOSPL
8907 if (cx == XXELS) /* ELSE */
8908 return(doelse());
8909 #endif /* NOSPL */
8910
8911 #ifndef NOSERVER
8912 #ifndef NOFRILLS
8913 if (cx == XXENA || cx == XXDIS) { /* ENABLE, DISABLE */
8914 s = (cx == XXENA) ?
8915 "Server function to enable" :
8916 "Server function to disable";
8917
8918 if ((x = cmkey(enatab,nena,s,"",xxstring)) < 0) {
8919 if (x == -3) {
8920 printf("?Name of server function required\n");
8921 return(-9);
8922 } else return(x);
8923 }
8924 if ((y = cmkey(kmstab,3,"mode","both",xxstring)) < 0) {
8925 if (y == -3) {
8926 printf("?Please specify remote, local, or both\n");
8927 return(-9);
8928 } else return(y);
8929 }
8930 if (cx == XXDIS) /* Disabling, not enabling */
8931 y = 3 - y;
8932 if ((z = cmcfm()) < 0) return(z);
8933 #ifdef CK_APC
8934 if ((apcactive == APC_LOCAL) ||
8935 ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
8936 return(success = 0);
8937 #endif /* CK_APC */
8938 #ifdef IKSD
8939 /* This may seem like it duplicates the work in doenable() */
8940 /* but this code returns failure whereas doenable() returns */
8941 /* success. */
8942 if (inserver &&
8943 #ifdef IKSDCONF
8944 iksdcf &&
8945 #endif /* IKSDCONF */
8946 (x == EN_HOS || x == EN_PRI || x == EN_MAI || x == EN_WHO ||
8947 isguest))
8948 return(success = 0);
8949 #endif /* IKSD */
8950 return(doenable(y,x));
8951 }
8952 #endif /* NOFRILLS */
8953 #endif /* NOSERVER */
8954
8955 #ifndef NOSPL
8956 if (cx == XXRET) { /* RETURN */
8957 if ((x = cmtxt("Optional return value","",&s,NULL)) < 0)
8958 return(x);
8959 s = brstrip(s); /* Strip braces */
8960 if (cmdlvl == 0) /* At top level, nothing happens... */
8961 return(success = 1);
8962 switch (cmdstk[cmdlvl].src) { /* Action depends on command source */
8963 case CMD_TF: /* Command file */
8964 popclvl(); /* Pop command level */
8965 return(success = 1); /* always succeeds */
8966 case CMD_MD: /* Macro */
8967 case CMD_KB: /* Prompt */
8968 return(doreturn(s)); /* Trailing text is return value. */
8969 default: /* Shouldn't happen */
8970 return(-2);
8971 }
8972 }
8973 #endif /* NOSPL */
8974
8975 #ifndef NOSPL
8976 if (cx == XXOPE) /* OPEN */
8977 return(doopen());
8978 #endif /* NOSPL */
8979
8980 #ifndef NOSPL
8981 if (cx == XXOUT || cx == XXLNOUT) { /* OUTPUT or LINEOUT */
8982 if ((x = cmtxt("Text to be output","",&s,NULL)) < 0)
8983 return(x);
8984 #ifdef CK_APC
8985 if ((apcactive == APC_LOCAL) ||
8986 ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
8987 return(success = 0);
8988 #endif /* CK_APC */
8989 debug(F110,"OUTPUT 1",s,0);
8990 s = brstrip(s); /* Strip enclosing braces, */
8991 debug(F110,"OUTPUT 2",s,0);
8992 /*
8993 I don't think I could ever fully explain this in a million years...
8994 We have read the user's string without calling the variable-expander
8995 function. Now, before we call it, we have to double backslashes that
8996 appear before \N, \B, \L, and \ itself, so the expander function will
8997 reduce them back to single backslashes, so when we call dooutput()...
8998 But it's more complicated than that.
8999 */
9000 if (cmdgquo()) { /* Only if COMMAND QUOTING ON ... */
9001 for (x = 0, y = 0; s[x]; x++, y++) {
9002 if (s[x] == CMDQ) {
9003 char c = s[x+1];
9004 if (c == 'n' || c == 'N' ||
9005 c == 'b' || c == 'B' ||
9006 c == 'l' || c == 'L' ||
9007 c == CMDQ)
9008 line[y++] = CMDQ;
9009 }
9010 line[y] = s[x];
9011 }
9012 line[y++] = '\0'; /* Now expand variables, etc. */
9013 debug(F110,"OUTPUT 3",line,0);
9014 s = line+y+1;
9015 x = LINBUFSIZ - (int) strlen(line) - 1;
9016 debug(F101,"OUTPUT size","",x);
9017 if (zzstring(line,&s,&x) < 0)
9018 return(success = 0);
9019 s = line+y+1;
9020 debug(F110,"OUTPUT 4",s,0);
9021 }
9022 success = dooutput(s,cx);
9023 return(success);
9024 }
9025 #endif /* NOSPL */
9026
9027 #ifdef ANYX25
9028 #ifndef IBMX25
9029 if (cx == XXPAD) { /* PAD commands */
9030 x = cmkey(padtab,npadc,"PAD command","",xxstring);
9031 if (x == -3) {
9032 printf("?You must specify a PAD command to execute\n");
9033 return(-9);
9034 }
9035 if (x < 0) return(x);
9036
9037 switch (x) {
9038 case XYPADL:
9039 if (x25stat() < 0)
9040 printf("Sorry, you must 'set network' & 'set host' first\r\n");
9041 else {
9042 x25clear();
9043 initpad();
9044 }
9045 break;
9046 case XYPADS:
9047 if (x25stat() < 0)
9048 printf("Not connected\r\n");
9049 else {
9050 extern int linkid, lcn;
9051 conol("Connected thru ");
9052 conol(ttname);
9053 printf(", Link id %d, Logical channel number %d\r\n",
9054 linkid,lcn);
9055 }
9056 break;
9057 case XYPADR:
9058 if (x25stat() < 0)
9059 printf("Sorry, you must 'set network' & 'set host' first\r\n");
9060 else
9061 x25reset(0,0);
9062 break;
9063 case XYPADI:
9064 if (x25stat() < 0)
9065 printf("Sorry, you must 'set network' & 'set host' first\r\n");
9066 else
9067 x25intr(0);
9068 }
9069 return(0);
9070 }
9071 #endif /* IBMX25 */
9072 #endif /* ANYX25 */
9073
9074 #ifndef NOSPL
9075 if (cx == XXPAU || cx == XXWAI || cx == XXMSL) /* PAUSE, WAIT, etc */
9076 return(dopaus(cx));
9077 #endif /* NOSPL */
9078
9079 #ifndef NOFRILLS
9080 if (cx == XXPRI) {
9081 #ifdef IKSD
9082 #ifdef CK_LOGIN
9083 if (inserver && (isguest || !ENABLED(en_pri))) {
9084 printf("?Sorry, printing is disabled\n");
9085 return(-9);
9086 }
9087 #endif /* CK_LOGIN */
9088 #endif /* IKSD */
9089 if ((x = cmifi("File to print","",&s,&y,xxstring)) < 0) {
9090 if (x == -3) {
9091 printf("?A file specification is required\n");
9092 return(-9);
9093 } else return(x);
9094 }
9095 if (y != 0) {
9096 printf("?Wildcards not allowed\n");
9097 return(-9);
9098 }
9099 ckstrncpy(line,s,LINBUFSIZ);
9100 s = "";
9101 #ifndef NT
9102 if ((x = cmtxt("Local print command options, or carriage return","",&s,
9103 xxstring)) < 0)
9104 return(x);
9105 #endif /* NT */
9106 if ((x = cmcfm()) < 0)
9107 return(x);
9108 return(success = (zprint(s,line) == 0) ? 1 : 0);
9109 }
9110 #endif /* NOFRILLS */
9111
9112 #ifdef TCPSOCKET
9113 #ifndef NOPUSH
9114 if (cx == XXPNG) /* PING an IP host */
9115 return(doping());
9116 #endif /* NOPUSH */
9117
9118 #ifndef NOFTP
9119 if (cx == XXFTP) /* FTP */
9120 #ifdef SYSFTP
9121 #ifndef NOPUSH
9122 return(doftp()); /* Just runs system's ftp program */
9123 #else
9124 return(-2);
9125 #endif /* NOPUSH */
9126 #else
9127 return(doxftp());
9128 #endif /* SYSFTP */
9129 #endif /* NOFTP */
9130 #endif /* TCPSOCKET */
9131
9132 if (cx == XXPWD || cx == XXLPWD) { /* PWD */
9133 #ifdef OS2
9134 char *pwp;
9135 #endif /* OS2 */
9136 if ((x = cmcfm()) < 0)
9137 return(x);
9138 #ifdef LOCUS
9139 if (!locus && cx != XXLPWD) {
9140 #ifdef NOXFER
9141 return(-2);
9142 #else
9143 return(dormt(XZPWD));
9144 #endif /* NOXFER */
9145 }
9146 #endif /* LOCUS */
9147
9148 #ifndef MAC
9149 #ifndef OS2
9150 #ifdef UNIX
9151 printf("%s\n",zgtdir());
9152 #else
9153 xsystem(PWDCMD);
9154 #endif /* UNIX */
9155 return(success = 1); /* Blind faith */
9156 #else /* OS2 */
9157 if (pwp = zgtdir()) {
9158 if (*pwp) {
9159 #ifdef NT
9160 line[0] = NUL;
9161 ckGetLongPathName(pwp,line,LINBUFSIZ);
9162 line[LINBUFSIZ-1] = NUL;
9163 tmpbuf[0] = NUL;
9164 GetShortPathName(pwp,tmpbuf,TMPBUFSIZ);
9165 tmpbuf[TMPBUFSIZ-1] = NUL;
9166 pwp = line;
9167 if (!strcmp(line,tmpbuf)) {
9168 #endif /* NT */
9169 printf("%s\n",pwp);
9170 #ifdef NT
9171 } else {
9172 printf(" Long name: %s\n",line);
9173 printf(" Short name: %s\n",tmpbuf);
9174 }
9175 #endif /* NT */
9176 }
9177 return(success = ((int)strlen(pwp) > 0));
9178 } else return(success = 0);
9179 #endif /* OS2 */
9180 #else /* MAC */
9181 if (pwp = zgtdir()) {
9182 printf("%s\n",pwp);
9183 return(success = ((int)strlen(pwp) > 0));
9184 } else return(success = 0);
9185 #endif /* MAC */
9186 }
9187
9188 if (cx == XXQUI || cx == XXEXI) { /* EXIT, QUIT */
9189 extern int quitting;
9190
9191 if ((y = cmnum("exit status code",ckitoa(xitsta),10,&x,xxstring)) < 0)
9192 return(y);
9193 if ((y = cmtxt("Optional EXIT message","",&s,xxstring)) < 0)
9194 return(y);
9195 s = brstrip(s);
9196 ckstrncpy(line,s,LINBUFSIZ);
9197
9198 if (!hupok(0)) /* Check if connection still open */
9199 return(success = 0);
9200
9201 if (line[0]) { /* Print EXIT message if given */
9202 extern int exitmsg;
9203 switch (exitmsg) {
9204 case 0: break;
9205 case 1: printf("%s\n",(char *)line); break;
9206 case 2: fprintf(stderr,"%s\n",(char *)line); break;
9207 }
9208 }
9209 quitting = 1; /* Flag that we are quitting. */
9210
9211 #ifdef VMS
9212 doexit(GOOD_EXIT,x);
9213 #else
9214 #ifdef OSK
9215 /* Returning any codes here makes the OS-9 shell print an error message. */
9216 doexit(GOOD_EXIT,-1);
9217 #else
9218 #ifdef datageneral
9219 doexit(GOOD_EXIT,x);
9220 #else
9221 doexit(x,-1);
9222 #endif /* datageneral */
9223 #endif /* OSK */
9224 #endif /* VMS */
9225 }
9226
9227 #ifndef NOXFER
9228 #ifndef NOFRILLS
9229 if (cx == XXERR) { /* ERROR */
9230 #ifdef CK_XYZ
9231 if (protocol != PROTO_K) {
9232 printf("Sorry, E-PACKET only works with Kermit protocol\n");
9233 return(-9);
9234 }
9235 #endif /* CK_XYZ */
9236 if ((x = cmcfm()) < 0) return(x);
9237 ttflui();
9238 epktflg = 1;
9239 sstate = 'a';
9240 return(0);
9241 }
9242 #endif /* NOFRILLS */
9243
9244 if (cx == XXFIN) { /* FINISH */
9245 #ifdef NEWFTP
9246 if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
9247 return(ftpbye());
9248 #endif /* NEWFTP */
9249 #ifdef CK_XYZ
9250 if (protocol != PROTO_K) {
9251 printf("Sorry, FINISH only works with Kermit protocol\n");
9252 return(-9);
9253 }
9254 #endif /* CK_XYZ */
9255 if ((x = cmcfm()) < 0) return(x);
9256
9257 #ifdef IKS_OPTION
9258 if (
9259 #ifdef CK_XYZ
9260 protocol == PROTO_K &&
9261 #endif /* CK_XYZ */
9262 !iks_wait(KERMIT_REQ_START,1)) {
9263 printf(
9264 "?A Kermit Server is not available to process this command\n");
9265 return(-9); /* Correct the return code */
9266 }
9267 #endif /* IKS_OPTION */
9268
9269 sstate = setgen('F',"","","");
9270 if (local) ttflui(); /* If local, flush tty input buffer */
9271 return(0);
9272 }
9273 #endif /* NOXFER */
9274
9275 #ifndef NOSPL
9276 if (cx == XXFOR) /* FOR loop */
9277 return(dofor());
9278 #endif /* NOSPL */
9279
9280 #ifndef NOXFER
9281 /* GET MGET REGET RETRIEVE etc */
9282 if (cx == XXGET || cx == XXMGET || cx == XXREGET || cx == XXRETR) {
9283 #ifdef IKSD
9284 if (inserver && !ENABLED(en_sen)) {
9285 printf("?Sorry, reception of files is disabled\n");
9286 return(-9);
9287 }
9288 #endif /* IKSD */
9289 return(doxget(cx));
9290 }
9291 #endif /* NOXFER */
9292
9293 #ifndef NOSPL
9294 #ifndef NOFRILLS
9295 if (cx == XXGOK) { /* GETOK */
9296 return(success = doask(cx));
9297 }
9298 #endif /* NOFRILLS */
9299 #endif /* NOSPL */
9300
9301 if (cx == XXHLP) { /* HELP */
9302 #ifdef NOHELP
9303 return(dohlp(XXHLP));
9304 #else
9305 x = cmkey2(cmdtab,
9306 ncmd,"\nCommand or topic","help",toktab,xxstring,1+2+8);
9307 debug(F111,"HELP command x",cmdbuf,x);
9308 if (x == -5) {
9309 y = chktok(toktab);
9310 debug(F101,"HELP cmkey token","",y);
9311 /* ungword(); */
9312 switch (y) {
9313 #ifndef NOPUSH
9314 case '!':
9315 case '@': x = XXSHE; break;
9316 case '<': x = XXFUN; break;
9317 #endif /* NOPUSH */
9318 case '#': x = XXCOM; break;
9319 case ';': x = XXCOM; break;
9320 #ifndef NOSPL
9321 case '.': x = XXDEF; break;
9322 case ':': x = XXLBL; break;
9323 #ifndef NOSEXP
9324 case '(': x = XXSEXP; break;
9325 #endif /* NOSEXP */
9326 #endif /* NOSPL */
9327 #ifdef CK_RECALL
9328 case '^': x = XXREDO; break;
9329 #endif /* CK_RECALL */
9330 default:
9331 printf("\n?Not a valid command or token - %s\n",cmdbuf);
9332 x = -2;
9333 }
9334 }
9335 makestr(&hlptok,atmbuf);
9336 debug(F111,"HELP token",hlptok,x);
9337 return(dohlp(x));
9338 #endif /* NOHELP */
9339 }
9340
9341 #ifndef NOHELP
9342 if (cx == XXINT) /* INTRO */
9343 return(hmsga(introtxt));
9344 if (cx == XXNEW) { /* NEWS */
9345 int x;
9346 extern char * k_info_dir;
9347 x = hmsga(newstxt);
9348 return(x);
9349 }
9350
9351 #ifdef OS2ONLY
9352 if (cx == XXUPD) { /* View UPDATE file */
9353 extern char exedir[];
9354 char * pTopic;
9355 char updstr[2048];
9356 if ((x = cmtxt("topic name","",&pTopic,xxstring)) < 0)
9357 return x;
9358 #ifdef COMMENT
9359 sprintf(updstr,
9360 "start view %s\\docs\\k2.inf+%s\\docs\\using_ck.inf+\
9361 %s\\docs\\dialing.inf+%s\\docs\\modems.inf %s",
9362 exedir,exedir,exedir,exedir,pTopic
9363 );
9364 #else
9365 if (ckmakxmsg(updstr,
9366 2048,
9367 "start view ",
9368 exedir,
9369 "\\docs\\k2.inf+",
9370 exedir,
9371 "\\docs\\using_ck.inf+",
9372 exedir,
9373 "\\docs\\dialing.inf+",
9374 exedir,
9375 "\\docs\\modems.inf ",
9376 pTopic,
9377 NULL,
9378 NULL
9379 ) > 0)
9380 #endif /* COMMENT */
9381 system(updstr);
9382 return(success = 1);
9383 }
9384 #endif /* OS2ONLY */
9385 #endif /* NOHELP */
9386
9387 #ifndef NOLOCAL
9388 if (cx == XXHAN) { /* HANGUP */
9389 if ((x = cmcfm()) < 0) return(x);
9390 #ifdef NEWFTP
9391 if ((ftpget == 1) || ((ftpget == 2) && !local && ftpisopen()))
9392 return(success = ftpbye());
9393 #endif /* NEWFTP */
9394 #ifndef NODIAL
9395 if ((x = mdmhup()) < 1) {
9396 debug(F101,"HANGUP mdmup","",x);
9397 #endif /* NODIAL */
9398 x = tthang();
9399 debug(F101,"HANGUP tthang","",x);
9400 x = (x > -1);
9401 #ifndef NODIAL
9402 }
9403 dialsta = DIA_UNK;
9404 #endif /* NODIAL */
9405 whyclosed = WC_CLOS;
9406 ttchk(); /* In case of CLOSE-ON-DISCONNECT */
9407 dologend();
9408 #ifdef OS2
9409 if (x)
9410 DialerSend(OPT_KERMIT_HANGUP, 0);
9411 #endif /* OS2 */
9412 if (x) haveline = 0;
9413 return(success = x);
9414 }
9415 #endif /* NOLOCAL */
9416
9417 #ifndef NOSPL
9418 /* INPUT, REINPUT, and MINPUT */
9419
9420 if (cx == XXINP || cx == XXREI || cx == XXMINP) {
9421 long zz;
9422 int flags = 0, incount = 0;
9423 extern int itsapattern, isjoin, isinbuflen;
9424 int c, getval;
9425
9426 struct FDB sw, nu, fl;
9427 int fc, havetime = 0;
9428 char * m;
9429
9430 if (cx == XXREI) {
9431 m = "Timeout in seconds (ignored)";
9432 } else {
9433 m = "Seconds to wait for input,\n or time of day hh:mm:ss,\
9434 or switch";
9435 }
9436 cmfdbi(&sw, /* First FDB - command switches */
9437 _CMKEY, /* fcode */
9438 m, /* helpmsg */
9439 ckitoa(indef), /* default */
9440 "", /* addtl string data */
9441 ninputsw, /* addtl numeric data 1: tbl size */
9442 4, /* addtl numeric data 2: 4 = cmswi */
9443 xxstring, /* Processing function */
9444 inputsw, /* Keyword table */
9445 &nu /* Pointer to next FDB */
9446 );
9447 cmfdbi(&nu,
9448 _CMNUM, /* Number */
9449 m, /* Help message */
9450 ckitoa(indef), /* default */
9451 "", /* N/A */
9452 10, /* Radix = 10 */
9453 0, /* N/A */
9454 xxstring, /* Processing function */
9455 NULL, /* N/A */
9456 &fl /* Next */
9457 );
9458 cmfdbi(&fl, /* Time of day hh:mm:ss */
9459 _CMFLD, /* fcode */
9460 "", /* hlpmsg */
9461 "",
9462 "", /* addtl string data */
9463 0, /* addtl numeric data 1 */
9464 0, /* addtl numeric data 2 */
9465 xxstring,
9466 NULL,
9467 NULL
9468 );
9469 fc = (cx == XXREI) ? cmfdb(&nu) : cmfdb(&sw); /* Parse something */
9470
9471 for (y = 0; y < MINPMAX; y++) { /* Initialize search strings */
9472 mp[y] = 0; /* Assume it's not a pattern */
9473 if (!mpinited) {
9474 ms[y] = NULL;
9475 }
9476 if (ms[y]) {
9477 free(ms[y]); /* Free old strings, if any */
9478 ms[y] = NULL;
9479 }
9480 }
9481 mpinited = 1;
9482 while (!havetime) {
9483 if (fc < 0) { /* Error */
9484 if (fc == -3) {
9485 printf("?Syntax error in INPUT-class command\n");
9486 return(-9);
9487 } else
9488 return(fc);
9489 }
9490 switch (cmresult.fcode) {
9491 case _CMKEY: /* Switch */
9492 c = cmgbrk();
9493 if ((getval = (c == ':' || c == '=')) &&
9494 !(cmgkwflgs() & CM_ARG)) {
9495 printf("?This switch does not take an argument\n");
9496 return(-9);
9497 }
9498 if (getval && cmresult.nresult == INPSW_COU) {
9499 if ((y = cmnum("Number of bytes to read",
9500 "",10,&x,xxstring)) < 0)
9501 return(y);
9502 incount = x;
9503 }
9504 flags |= cmresult.nresult;
9505 fc = cmfdb(&sw); /* Maybe parse more switches */
9506 continue;
9507
9508 case _CMNUM: /* Seconds to time out */
9509 x = cmresult.nresult;
9510 #ifdef CKFLOAT
9511 if (inscale != 1.0) /* Scale */
9512 x *= inscale;
9513 #endif /* CKFLOAT */
9514 havetime++;
9515 break;
9516
9517 case _CMFLD:
9518 zz = tod2sec(atmbuf); /* Convert to secs since midnight */
9519 if (zz < 0L) {
9520 printf("?Number, expression, or time of day required\n");
9521 return(-9);
9522 } else {
9523 char now[32]; /* Current time */
9524 char *p;
9525 long tnow;
9526 p = now;
9527 ztime(&p);
9528 tnow = atol(p+11) * 3600L + atol(p+14) * 60L + atol(p+17);
9529 if (zz < tnow) /* User's time before now */
9530 zz += 86400L; /* So make it tomorrow */
9531 zz -= tnow; /* Seconds from now. */
9532 if (zz > -1L) {
9533 x = zz;
9534 if (zz != (long) x) {
9535 printf(
9536 "Sorry, arithmetic overflow - hh:mm:ss not usable on this platform.\n"
9537 );
9538 return(-9);
9539 }
9540 }
9541 havetime++;
9542 }
9543 break;
9544 default:
9545 printf("?Internal error\n");
9546 return(-9);
9547 }
9548 }
9549 /* Now parse the search text */
9550
9551 #ifdef CK_MINPUT
9552 if (cx == XXMINP) { /* MINPUT */
9553 int i, k = 0, n = 0;
9554 struct stringarray * q;
9555 keepallchars = 1;
9556 while (k < MINPMAX) {
9557 if ((y = cmfld("String or pattern","",&s,xxstring)) < 0) {
9558 if (y == -3) {
9559 if ((y = cmcfm()) < 0)
9560 return(y);
9561 break;
9562 } else {
9563 return(y);
9564 }
9565 }
9566 debug(F111,"MINPUT field",s,k);
9567 if (isjoin) {
9568 if ((q = cksplit(1,0,s," ",(char *)c1chars,3,0,0,0))) {
9569 char ** ap = q->a_head;
9570 n = q->a_size;
9571 debug(F101,"minput cksplit size","",n);
9572 for (i = 1; i <= n && k < MINPMAX; i++) {
9573 if (!ap[i]) /* Add non-empty elements */
9574 continue;
9575 if (!*(ap[i]))
9576 continue;
9577 makestr(&(ms[k]),ap[i]);
9578 debug(F111,"MINPUT JOIN",ms[k],k);
9579 k++;
9580 }
9581 }
9582 } else {
9583 if (s) if (*s) {
9584 makestr(&(ms[k]),brstrip(s));
9585 if (itsapattern) mp[k] = 1;
9586 debug(F111,"MINPUT",ms[k],itsapattern);
9587 k++;
9588 }
9589 }
9590 }
9591 keepallchars = 0;
9592 } else {
9593 #endif /* CK_MINPUT */
9594
9595 /* INPUT or REINPUT */
9596
9597 if (flags & INPSW_COU) {
9598 if ((y = cmcfm()) < 0)
9599 return(y);
9600 } else {
9601 if ((y = cmtxt("Material to be input","",&s,xxstring)) < 0)
9602 return(y);
9603 }
9604 mp[0] = itsapattern ? 1 : 0;
9605 makestr(&(ms[0]),brstrip(s));
9606 ms[1] = NULL;
9607
9608 #ifdef CK_MINPUT
9609 }
9610 #endif /* CK_MINPUT */
9611
9612 if (incount > 0) /* No searching if /COUNT: given */
9613 makestr(&(ms[0]),NULL);
9614
9615 if (cx == XXINP || cx == XXMINP) { /* Not REINPUT... */
9616 i_active = 1;
9617 /* Go try to input the search string */
9618 success = doinput(x,ms,mp,flags,incount);
9619 i_active = 0;
9620 } else { /* REINPUT */
9621 success = doreinp(x,ms[0],itsapattern);
9622 }
9623 if (intime[cmdlvl] && !success) { /* TIMEOUT-ACTION = QUIT? */
9624 popclvl(); /* If so, pop command level. */
9625 if (pflag && cmdlvl == 0) {
9626 if (cx == XXINP) printf("?INPUT timed out\n");
9627 if (cx == XXMINP) printf("?MINPUT timed out\n");
9628 if (cx == XXREI) printf("?REINPUT failed\n");
9629 }
9630 }
9631 return(success); /* Return do(re)input's return code */
9632 }
9633
9634 #endif /* NOSPL */
9635
9636 if (cx == XXLOG) { /* LOG */
9637 x = cmkey(logtab,nlog,"What to log","",xxstring);
9638 if (x == -3) {
9639 printf("?Type of log required\n");
9640 return(-9);
9641 }
9642 if (x < 0) return(x);
9643 x = dolog(x);
9644 if (x < 0)
9645 return(x);
9646 else
9647 return(success = x);
9648 }
9649
9650 if (cx == XXLOGIN) { /* (REMOTE) LOGIN */
9651 #ifdef NEWFTP
9652 if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
9653 return(success = doftpusr());
9654 #endif /* NEWFTP */
9655 #ifdef IKSD
9656 if (inserver) {
9657 printf("?Already logged in\n");
9658 return(-9);
9659 } else
9660 #endif /* IKSD */
9661 {
9662 #ifdef NOXFER
9663 return(-2);
9664 #else
9665 return(dormt(XZLGI));
9666 #endif /* NOXFER */
9667 }
9668 }
9669 if (cx == XXLOGOUT) { /* (REMOTE) LOGOUT */
9670 #ifdef NEWFTP
9671 if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
9672 return(success = doftpres());
9673 #endif /* NEWFTP */
9674
9675 #ifdef IKSD
9676 if (inserver) {
9677 if ((x = cmcfm()) < 0)
9678 return(x);
9679 doexit(GOOD_EXIT,xitsta);
9680 } else
9681 #endif /* IKSD */
9682 if (!local || (network && ttchk() < 0)) {
9683 printf("?No connection.\n");
9684 return(-9);
9685 } else {
9686 #ifdef NOXFER
9687 return(-2);
9688 #else
9689 return(dormt(XZLGO));
9690 #endif /* NOXFER */
9691 }
9692 }
9693
9694 #ifndef NOSCRIPT
9695 if (cx == XXLOGI) { /* UUCP-style script */
9696 if ((x = cmtxt("expect-send expect-send ...","",&s,xxstring)) < 0)
9697 return(x);
9698 #ifdef CK_APC
9699 if ((apcactive == APC_LOCAL) ||
9700 ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
9701 return(success = 0);
9702 #endif /* CK_APC */
9703 #ifdef VMS
9704 conres(); /* For Ctrl-C to work... */
9705 #endif /* VMS */
9706 return(success = dologin(s)); /* Return 1=completed, 0=failed */
9707 }
9708 #endif /* NOSCRIPT */
9709
9710 #ifndef NOXFER
9711 #ifdef PIPESEND
9712 if (cx == XXCREC) { /* CRECEIVE */
9713 if (protocol != PROTO_K) {
9714 printf("?Sorry, CRECEIVE works only with Kermit protocol\n");
9715 return(-9);
9716 } else
9717 return(doxget(cx));
9718 }
9719 if (cx == XXCGET) { /* CGET */
9720 return(doxget(cx));
9721 }
9722 #endif /* PIPESEND */
9723
9724 if (cx == XXREC) /* RECEIVE */
9725 return(doxget(cx));
9726 #endif /* NOXFER */
9727
9728 #ifndef NOXFER
9729 if (cx == XXREM) { /* REMOTE */
9730 #ifdef NEWFTP
9731 if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
9732 return(doftprmt(0,0));
9733 #endif /* NEWFTP */
9734 #ifdef CK_XYZ
9735 if (protocol != PROTO_K) {
9736 printf("Sorry, REMOTE commands only work with Kermit protocol\n");
9737 return(-9);
9738 }
9739 #endif /* CK_XYZ */
9740 x = cmkey(remcmd,nrmt,"Remote Kermit server command","",xxstring);
9741 if (x == -3) {
9742 printf("?You must specify a command for the remote server\n");
9743 return(-9);
9744 }
9745 return(dormt(x));
9746 }
9747 #endif /* NOXFER */
9748
9749 #ifndef NORENAME
9750 #ifndef NOFRILLS
9751 if (cx == XXREN || cx == XXLREN) { /* RENAME */
9752 #ifdef LOCUS
9753 if (!locus && cx != XXLREN) {
9754 #ifdef NOXFER
9755 return(-2);
9756 #else
9757 return(dormt(XZREN));
9758 #endif /* NOXFER */
9759 }
9760 #endif /* LOCUS */
9761 #ifdef IKSD
9762 if (inserver && (!ENABLED(en_ren)
9763 #ifdef CK_LOGIN
9764 || isguest
9765 #endif /* CK_LOGIN */
9766 )) {
9767 printf("?Sorry, renaming of files is disabled\n");
9768 return(-9);
9769 }
9770 #endif /* IKSD */
9771 #ifdef CK_APC
9772 if ((apcactive == APC_LOCAL) ||
9773 ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
9774 return(success = 0);
9775 #endif /* CK_APC */
9776 return(dorenam());
9777 }
9778 #endif /* NOFRILLS */
9779 #endif /* NORENAME */
9780
9781 if (cx == XXEIGHT) { /* EIGHTBIT */
9782 extern int parity, cmask, cmdmsk;
9783 if ((x = cmcfm()) < 0)
9784 return(x);
9785 parity = 0;
9786 cmask = 0xff;
9787 cmdmsk = 0xff;
9788 return(success = 1);
9789 }
9790
9791 #ifndef NOXFER
9792 /* SEND, CSEND, MOVE, MAIL, and RESEND use the new common code */
9793
9794 if (cx == XXSEN /* SEND */
9795 #ifdef PIPESEND
9796 || cx == XXCSEN /* CSEND */
9797 #endif /* PIPESEND */
9798 || cx == XXMOVE /* MOVE */
9799 || cx == XXMAI /* MAIL */
9800 #ifdef CK_RESEND
9801 || cx == XXRSEN /* RESEND */
9802 #endif /* CK_RESEND */
9803 ) {
9804 #ifdef IKSD
9805 if (inserver && !ENABLED(en_get)) {
9806 printf("?Sorry, sending files is disabled\n");
9807 return(-9);
9808 }
9809 #endif /* IKSD */
9810 return(doxsend(cx));
9811 }
9812
9813 /* PSEND, ADD, and REMOVE use special parsing */
9814
9815 #ifdef ADDCMD
9816 /* ADD and REMOVE */
9817 if (cx == XXADD || cx == XXREMV) {
9818 char * m;
9819 m = (cx == XXADD) ? "Add to which list?" : "Remove from which list?";
9820 x = cmkey(addtab,naddtab,m,"",xxstring);
9821 if (x < 0)
9822 return(x);
9823 #ifndef NOMSEND
9824 if (x == ADD_SND)
9825 return(addsend(cx));
9826 else
9827 #endif /* NOMSEND */
9828 return(doadd(cx,x));
9829 }
9830 #endif /* ADDCMD */
9831
9832 #ifdef CK_RESEND
9833 if (cx == XXPSEN) { /* PSEND */
9834 int seekto = 0; /* FIX THIS */
9835
9836 cmarg = cmarg2 = "";
9837 x = cmifi("File to partially send", "", &s, &y, xxstring);
9838 if (x < 0) {
9839 if (x == -3) {
9840 printf("?A file specification is required\n");
9841 return(-9);
9842 } else return(x);
9843 }
9844 nfils = -1; /* Files come from internal list. */
9845 #ifndef NOMSEND
9846 addlist = 0; /* Don't use SEND-LIST. */
9847 filenext = NULL;
9848 #endif /* NOMSEND */
9849 ckstrncpy(line,s,LINBUFSIZ); /* Save copy of string just parsed. */
9850 debug(F110,"PSEND line",line,0);
9851 if (y != 0) {
9852 printf("?Sorry, wildcards not permitted in this command\n");
9853 return(-9);
9854 }
9855 if (sizeof(int) < 4) {
9856 printf("?Sorry, this command needs 32-bit integers\n");
9857 return(-9);
9858 }
9859 x = cmnum("starting position (byte number)",
9860 "",10,&seekto,xxstring);
9861 if (x < 0)
9862 return(x);
9863 zfnqfp(s,fspeclen,fspec); /* Get full path */
9864 if ((x = cmtxt("Name to send it with","",&s,NULL)) < 0)
9865 return(x);
9866 ckstrncpy(tmpbuf,s,TMPBUFSIZ);
9867
9868 #ifdef IKSD
9869 if (inserver && !ENABLED(en_get)) {
9870 printf("?Sorry, sending files is disabled\n");
9871 return(-9);
9872 }
9873 #endif /* IKSD */
9874 #ifdef PIPESEND
9875 if (sndfilter) {
9876 printf("?Sorry, no PSEND while SEND FILTER selected\n");
9877 return(-9);
9878 }
9879 #endif /* PIPESEND */
9880 #ifdef CK_XYZ
9881 if ((protocol == PROTO_X || protocol == PROTO_XC)) {
9882 printf("Sorry, PSEND works only with Kermit protocol\n");
9883 return(-9);
9884 }
9885 #endif /* CK_XYZ */
9886
9887 cmarg2 = brstrip(tmpbuf); /* Strip braces */
9888 cmarg = line; /* File to send */
9889 debug(F110,"PSEND filename",cmarg,0);
9890 debug(F110,"PSEND as-name",cmarg2,0);
9891 sendstart = seekto;
9892 sstate = 's'; /* Set start state to SEND */
9893 #ifndef NOMSEND
9894 addlist = 0;
9895 filenext = NULL;
9896 #endif /* NOMSEND */
9897 sendmode = SM_PSEND;
9898 #ifdef MAC
9899 what = W_SEND;
9900 scrcreate();
9901 #endif /* MAC */
9902 if (local) { /* If in local mode, */
9903 displa = 1; /* enable file transfer display */
9904 }
9905 return(0);
9906 }
9907 #endif /* CK_RESEND */
9908 #endif /* NOXFER */
9909
9910 #ifndef NOXFER
9911 #ifndef NOMSEND
9912 if (cx == XXMSE || cx == XXMMOVE) {
9913 #ifdef NEWFTP
9914 if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
9915 return(doftpput(cx,0));
9916 #endif /* NEWFTP */
9917 #ifdef CK_XYZ
9918 if (protocol == PROTO_X || protocol == PROTO_XC) {
9919 printf(
9920 "Sorry, you can only send one file at a time with XMODEM protocol\n"
9921 );
9922 return(-9);
9923 }
9924 #endif /* CK_XYZ */
9925 return(doxsend(cx));
9926 }
9927
9928 #ifdef COMMENT /* (moved to doxsend) */
9929 if (cx == XXMSE || cx == XXMMOVE) { /* MSEND and MMOVE commands */
9930 nfils = 0; /* Like getting a list of */
9931 lp = line; /* files on the command line */
9932 addlist = 0; /* Do not use SEND-LIST */
9933 filenext = NULL; /* Ditto ! */
9934
9935 while (1) {
9936 char *p;
9937 if ((x = cmifi("Names of files to send, separated by spaces","",
9938 &s,&y,xxstring)) < 0) {
9939 if (x == -3) {
9940 if (nfils <= 0) {
9941 printf("?A file specification is required\n");
9942 return(-9);
9943 } else break;
9944 }
9945 return(x);
9946 }
9947 msfiles[nfils++] = lp; /* Got one, count it, point to it, */
9948 p = lp; /* remember pointer, */
9949 while (*lp++ = *s++) /* and copy it into buffer */
9950 if (lp > (line + LINBUFSIZ)) { /* Avoid memory leak */
9951 printf("?MSEND list too long\n");
9952 line[0] = NUL;
9953 return(-9);
9954 }
9955 debug(F111,"msfiles",msfiles[nfils-1],nfils-1);
9956 if (nfils == 1) *fspec = NUL; /* Take care of \v(filespec) */
9957 #ifdef ZFNQFP
9958 zfnqfp(p,TMPBUFSIZ,tmpbuf);
9959 p = tmpbuf;
9960 #endif /* ZFNQFP */
9961 if (((int)strlen(fspec) + (int)strlen(p) + 1) < fspeclen) {
9962 strcat(fspec,p); /* safe */
9963 strcat(fspec," "); /* safe */
9964 } else printf("WARNING - \\v(filespec) buffer overflow\n");
9965 }
9966 cmlist = msfiles; /* Point cmlist to pointer array */
9967 cmarg2 = ""; /* No internal expansion list (yet) */
9968 sndsrc = nfils; /* Filenames come from cmlist */
9969 sendmode = SM_MSEND; /* Remember this kind of SENDing */
9970 sstate = 's'; /* Set start state for SEND */
9971 if (cx == XXMMOVE) /* If MMOVE'ing, */
9972 moving = 1; /* set this flag. */
9973 #ifdef MAC
9974 what = W_SEND;
9975 scrcreate();
9976 #endif /* MAC */
9977 if (local) { /* If in local mode, */
9978 displa = 1; /* turn on file transfer display */
9979 ttflui(); /* and flush tty input buffer. */
9980 }
9981 return(0);
9982 }
9983 #endif /* COMMENT */
9984 #endif /* NOMSEND */
9985 #endif /* NOXFER */
9986
9987 #ifndef NOSERVER
9988 if (cx == XXSER) { /* SERVER */
9989 #ifdef CK_XYZ
9990 if (protocol != PROTO_K) {
9991 printf("Sorry, SERVER only works with Kermit protocol\n");
9992 return(-9);
9993 }
9994 #endif /* CK_XYZ */
9995 #ifdef COMMENT
9996 /*
9997 Parse for time limit, but since we don't use it yet,
9998 the parsing is commented out.
9999 */
10000 x_ifnum = 1; /* Turn off internal complaints */
10001 y = cmnum("optional time limit, seconds, or time of day as hh:mm:ss",
10002 "0", 10, &x, xxstring
10003 );
10004 x_ifnum = 0;
10005 if (y < 0) {
10006 if (y == -2) { /* Invalid number or expression */
10007 zz = tod2sec(atmbuf); /* Convert to secs since midnight */
10008 if (zz < 0L) {
10009 printf("?Number, expression, or time of day required\n");
10010 return(-9);
10011 } else {
10012 char now[32]; /* Current time */
10013 char *p;
10014 long tnow;
10015 p = now;
10016 ztime(&p);
10017 tnow = atol(p+11) * 3600L + atol(p+14) * 60L + atol(p+17);
10018 if (zz < tnow) /* User's time before now */
10019 zz += 86400L; /* So make it tomorrow */
10020 zz -= tnow; /* Seconds from now. */
10021 }
10022 } else
10023 return(y);
10024 }
10025 if (zz > -1L) {
10026 x = zz;
10027 if (zz != (long) x) {
10028 printf(
10029 "Sorry, arithmetic overflow - hh:mm:ss not usable on this platform.\n"
10030 );
10031 return(-9);
10032 }
10033 }
10034 if (x < 0)
10035 x = 0;
10036 #endif /* COMMENT */
10037
10038 if ((x = cmcfm()) < 0) return(x);
10039 sstate = 'x';
10040 #ifdef MAC
10041 what = W_RECV;
10042 scrcreate();
10043 #endif /* MAC */
10044 if (local) displa = 1;
10045 #ifdef AMIGA
10046 reqoff(); /* No DOS requestors while server */
10047 #endif /* AMIGA */
10048 return(0);
10049 }
10050 #endif /* NOSERVER */
10051
10052 if (cx == XXSAVE) { /* SAVE command */
10053 x = cmkey(savtab,nsav,"option","keymap",xxstring);
10054 if (x == -3) {
10055 printf("?You must specify an option to save\n");
10056 return(-9);
10057 }
10058 if (x < 0) return(x);
10059 /* have to set success separately for each item in doprm()... */
10060 /* actually not really, could have just had doprm return 0 or 1 */
10061 /* and set success here... */
10062 y = dosave(x);
10063 if (y == -3) {
10064 printf("?More fields required\n");
10065 return(-9);
10066 } else return(y);
10067 }
10068
10069 if (cx == XXSET) { /* SET command */
10070 x = cmkey(prmtab,nprm,"Parameter","",xxstring);
10071 if (x == -3) {
10072 printf("?You must specify a parameter to set\n");
10073 return(-9);
10074 }
10075 if (x < 0) return(x);
10076 /* have to set success separately for each item in doprm()... */
10077 /* actually not really, could have just had doprm return 0 or 1 */
10078 /* and set success here... */
10079 y = doprm(x,0);
10080 if (y == -3) {
10081 printf("?More fields required\n");
10082 return(-9);
10083 } else return(y);
10084 }
10085
10086 #ifndef NOPUSH
10087 if (cx == XXSHE /* SHELL (system) command */
10088 || cx == XXEXEC /* exec() */
10089 ) {
10090 int rx = 0;
10091 char * p = NULL;
10092 int i /* ,n */ ;
10093 #ifdef UNIXOROSK
10094 char * args[256];
10095 #endif /* UNIXOROSK */
10096
10097 #ifdef IKSD
10098 if (inserver && (nopush || !ENABLED(en_hos))) {
10099 printf("?Sorry, host command access is disabled\n");
10100 return(-9);
10101 }
10102 #endif /* IKSD */
10103
10104 #ifdef CKEXEC
10105 if (cx == XXEXEC) { /* EXEC (overlay ourselves) */
10106 struct FDB sw, fl;
10107 cmfdbi(&sw, /* First FDB - command switches */
10108 _CMKEY, /* fcode */
10109 "Command to overlay C-Kermit\n or switch", /* hlpmsg */
10110 "", /* default */
10111 "", /* addtl string data */
10112 1, /* addtl numeric data 1: tbl size */
10113 4, /* addtl numeric data 2: 4 = cmswi */
10114 xxstring, /* Processing function */
10115 redirsw, /* Keyword table */
10116 &fl /* Pointer to next FDB */
10117 );
10118 cmfdbi(&fl, /* 2nd FDB - command to exec */
10119 _CMFLD, /* fcode */
10120 "Command to overlay C-Kermit", /* hlpmsg */
10121 "", /* default */
10122 "", /* addtl string data */
10123 0, /* addtl numeric data 1 */
10124 0, /* addtl numeric data 2 */
10125 xxstring,
10126 NULL,
10127 NULL /* No more after this */
10128 );
10129 while (1) {
10130 x = cmfdb(&sw); /* Parse something */
10131 debug(F101,"exec cmfdb","",x);
10132 if (x < 0)
10133 return(x);
10134 /* Generalize this if we add more switches */
10135 if (cmresult.fcode == _CMKEY) {
10136 rx = 1;
10137 continue;
10138 }
10139 if (cmresult.fcode == _CMFLD)
10140 break;
10141 return(-2);
10142 }
10143 ckstrncpy(tmpbuf,cmresult.sresult,TMPBUFSIZ);
10144 if (!tmpbuf[0]) {
10145 printf("?Command required\n");
10146 return(-9);
10147 }
10148 p = brstrip(tmpbuf);
10149 args[0] = NULL; /* Set argv[0] to it */
10150 makestr(&args[0],p);
10151 for (i = 1; i < 255; i++) { /* Get arguments for command */
10152 if ((x = cmfld("Argument","",&s,xxstring)) < 0) {
10153 if (x == -3) {
10154 if ((x = cmcfm()) < 0)
10155 return(x);
10156 break;
10157 } else
10158 return(x);
10159 }
10160 args[i] = NULL;
10161 s = brstrip(s);
10162 makestr(&args[i],s);
10163 }
10164 args[i] = NULL;
10165 } else {
10166 #endif /* CKEXEC */
10167 if ((x = cmtxt("System command to execute","",&s,xxstring)) < 0)
10168 return(x);
10169 #ifdef CKEXEC
10170 }
10171 #endif /* CKEXEC */
10172 if (nopush)
10173 return(success = 0);
10174 #ifdef CK_APC
10175 if (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH))
10176 return(success = 0);
10177 #endif /* CK_APC */
10178 conres(); /* Make console normal */
10179 #ifdef OS2
10180 if (!(s && *s)) {
10181 os2push();
10182 return(success = 1);
10183 } else
10184 #endif /* OS2 */
10185 if (cx == XXSHE) {
10186 x = zshcmd(s);
10187 debug(F101,"RUN zshcmd code","",x);
10188 concb((char)escape);
10189 return(success = x);
10190 #ifdef CKEXEC
10191 } else {
10192 #ifdef DEBUG
10193 if (deblog) {
10194 debug(F111,"EXEC cmd",p,0);
10195 for (i = 0; i < 256 && args[i]; i++)
10196 debug(F111,"EXEC arg",args[i],i);
10197 }
10198 #endif /* DEBUG */
10199 if (p) {
10200 z_exec(p,args,rx); /* Overlay ourself */
10201 debug(F100,"EXEC fails","",0);
10202 concb((char)escape); /* In case it returns */
10203 }
10204 return(success = 0);
10205 #endif /* CKEXEC */
10206 }
10207 }
10208
10209 #ifdef CK_REDIR
10210 if (cx == XXFUN) { /* REDIRECT */
10211 #ifdef CK_APC
10212 if ((apcactive == APC_LOCAL) ||
10213 ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
10214 return(success = 0);
10215 #endif /* CK_APC */
10216 ckmakmsg(tmpbuf,
10217 TMPBUFSIZ,
10218 "Local command to run,\n",
10219 "with its standard input/output redirected to ",
10220 local ? ttname : "the communications connection",
10221 "\n"
10222 );
10223 if ((x = cmtxt(tmpbuf,"",&s,xxstring)) < 0)
10224 return(x);
10225 if (nopush) {
10226 printf("?REDIRECT disabled\n");
10227 return(success=0);
10228 }
10229 if (!local) {
10230 printf("?SET LINE or SET HOST required first\n");
10231 return(-9);
10232 }
10233 if (!*s) {
10234 printf("?REDIRECT requires a command to redirect\n");
10235 return(-9);
10236 }
10237 return(success = ttruncmd(s));
10238 }
10239 #endif /* CK_REDIR */
10240 #endif /* NOPUSH */
10241
10242 #ifndef NOSHOW
10243 if (cx == XXSHO) { /* SHOW */
10244 x = cmkey(shotab,nsho,"","parameters",xxstring);
10245 if (x < 0) return(x);
10246 return(doshow(x));
10247 }
10248 #endif /* NOSHOW */
10249
10250 #ifndef MAC
10251 if (cx == XXSPA) { /* SPACE */
10252 #ifdef IKSD
10253 if (inserver && !ENABLED(en_spa)) {
10254 printf("?Sorry, SPACE command disabled\n");
10255 return(-9);
10256 }
10257 #endif /* IKSD */
10258 #ifdef datageneral
10259 /* AOS/VS can take an argument after its "space" command. */
10260 if ((x = cmtxt("Confirm, or local directory name","",&s,xxstring)) < 0)
10261 return(x);
10262 if (nopush) {
10263 printf("?Sorry, SPACE command disabled\n");
10264 return(-9);
10265 } else if (*s == NUL) {
10266 xsystem(SPACMD);
10267 } else {
10268 ckmakmsg(line,LINBUFSIZ,"space ",s,NULL,NULL);
10269 xsystem(line);
10270 }
10271 #else
10272 #ifdef OS2
10273 if ((x = cmtxt("Press Enter for current disk,\n\
10274 or specify a disk letter like A:","",&s,xxstring)) < 0)
10275 return(x);
10276 if (*s == NUL) { /* Current disk */
10277 unsigned long space = zdskspace(0);
10278 if (space > 0 && space < 1024)
10279 printf(" Free space: unknown\n");
10280 else
10281 printf(" Free space: %ldK\n", space/1024L);
10282 } else {
10283 int drive = toupper(*s);
10284 unsigned long space = zdskspace(drive - 'A' + 1);
10285 if (space > 0 && space < 1024)
10286 printf(" Drive %c: unknown free\n");
10287 else
10288 printf(" Drive %c: %ldK free\n", drive,space / 1024L);
10289 }
10290 #else
10291 #ifdef UNIXOROSK
10292 x = cmdir("Confirm for current disk,\n\
10293 or specify a disk device or directory","",&s,xxstring);
10294 if (x == -3)
10295 s = "";
10296 else if (x < 0)
10297 return(x);
10298 ckstrncpy(tmpbuf,s,TMPBUFSIZ);
10299 s = tmpbuf;
10300 if ((x = cmcfm()) < 0) return(x);
10301 if (nopush) {
10302 printf("?Sorry, SPACE command disabled\n");
10303 return(-9);
10304 }
10305 if (!*s) { /* Current disk */
10306 xsystem(SPACMD);
10307 } else { /* Specified disk */
10308 ckmakmsg(line,LINBUFSIZ,SPACM2," ",s,NULL);
10309 xsystem(line);
10310 }
10311 #else
10312 if ((x = cmcfm()) < 0) return(x);
10313 if (nopush) {
10314 printf("?Sorry, SPACE command disabled\n");
10315 return(-9);
10316 }
10317 xsystem(SPACMD);
10318 #endif /* UNIXOROSK */
10319 #endif /* OS2 */
10320 #endif /* datageneral */
10321 return(success = 1); /* Pretend it worked */
10322 }
10323 #endif /* MAC */
10324
10325 #ifndef NOXFER
10326 if (cx == XXSTA) { /* STATISTICS */
10327 if ((x = cmkey(stattab,2,"Carriage return, or option",
10328 "/brief",xxstring)) < 0)
10329 return(x);
10330 if ((y = cmcfm()) < 0) return(y);
10331 return(success = dostat(x));
10332 }
10333 #endif /* NOXFER */
10334
10335 if (cx == XXSTO || cx == XXEND) { /* STOP, END, or POP */
10336 if ((y = cmnum("exit status code","0",10,&x,xxstring)) < 0)
10337 return(y);
10338 if ((y = cmtxt("Message to print","",&s,xxstring)) < 0)
10339 return(y);
10340 s = brstrip(s);
10341 if (*s) printf("%s\n",s);
10342 if (cx == XXSTO) {
10343 dostop();
10344 } else {
10345 doend(x);
10346 }
10347 return(success = (x == 0));
10348 }
10349 if (cx == XXSUS) { /* SUSPEND */
10350 if ((y = cmcfm()) < 0) return(y);
10351 #ifdef NOJC
10352 printf("Sorry, this version of Kermit cannot be suspended\n");
10353 #else
10354 #ifdef IKSD
10355 if (inserver) {
10356 printf("?Sorry, IKSD can not be suspended\n");
10357 return(-9);
10358 } else
10359 #endif /* IKSD */
10360 if (nopush) {
10361 printf("?Sorry, access to system is disabled\n");
10362 return(-9);
10363 }
10364 stptrap(0);
10365 #endif /* NOJC */
10366 return(0);
10367 }
10368
10369 if (cx == XXTAK) { /* TAKE */
10370 char * scriptenv = NULL;
10371 #ifdef OS2
10372 char * GetAppData(int);
10373 extern char startupdir[],exedir[],inidir[];
10374 char * keymapenv = NULL;
10375 char * appdata0 = NULL, *appdata1 = NULL;
10376 int xx;
10377 #define TAKEPATHLEN 4096
10378 #else /* OS2 */
10379 #define TAKEPATHLEN 1024
10380 #endif /* OS2 */
10381 char takepath[TAKEPATHLEN];
10382
10383 if (tlevel >= MAXTAKE-1) {
10384 printf("?Take files nested too deeply\n");
10385 return(-9);
10386 }
10387 #ifdef OS2
10388 #ifdef NT
10389 scriptenv = getenv("K95SCRIPTS");
10390 keymapenv = getenv("K95KEYMAPS");
10391 makestr(&appdata0,(char *)GetAppData(0));
10392 makestr(&appdata1,(char *)GetAppData(1));
10393 #else /* NT */
10394 scriptenv = getenv("K2SCRIPTS");
10395 keymapenv = getenv("K2KEYMAPS");
10396 #endif /* NT */
10397 #endif /* OS2 */
10398
10399 if (!scriptenv) /* Let this work for Unix etc too */
10400 scriptenv = getenv("CK_SCRIPTS"); /* Use this if defined */
10401 #ifndef OS2
10402 if (!scriptenv) /* Otherwise use home directory */
10403 scriptenv = homepath();
10404 #endif /* OS2 */
10405 if (!scriptenv)
10406 scriptenv = "";
10407 ckstrncpy(takepath,scriptenv,TAKEPATHLEN);
10408 debug(F110,"TAKE initial takepath",takepath,0);
10409
10410 #ifdef OS2
10411 if (!keymapenv)
10412 keymapenv = getenv("CK_KEYMAPS");
10413 if (!keymapenv)
10414 keymapenv = "";
10415
10416 ckstrncat(takepath,
10417 (scriptenv && scriptenv[strlen(scriptenv)-1]==';')?"":";",
10418 TAKEPATHLEN
10419 );
10420 ckstrncat(takepath,keymapenv?keymapenv:"",TAKEPATHLEN);
10421 ckstrncat(takepath,
10422 (keymapenv && keymapenv[strlen(keymapenv)-1]==';')?"":";",
10423 TAKEPATHLEN
10424 );
10425 ckstrncat(takepath,startupdir,TAKEPATHLEN);
10426 ckstrncat(takepath,";",TAKEPATHLEN);
10427 ckstrncat(takepath,startupdir,TAKEPATHLEN);
10428 ckstrncat(takepath,"SCRIPTS/;",TAKEPATHLEN);
10429 ckstrncat(takepath,startupdir,TAKEPATHLEN);
10430 ckstrncat(takepath,"KEYMAPS/;",TAKEPATHLEN);
10431
10432 ckstrncat(takepath,appdata1,TAKEPATHLEN);
10433 ckstrncat(takepath,"Kermit 95/;",TAKEPATHLEN);
10434 ckstrncat(takepath,appdata1,TAKEPATHLEN);
10435 ckstrncat(takepath,"Kermit 95/SCRIPTS/;",TAKEPATHLEN);
10436 ckstrncat(takepath,appdata1,TAKEPATHLEN);
10437 ckstrncat(takepath,"Kermit 95/KEYMAPS/;",TAKEPATHLEN);
10438
10439 ckstrncat(takepath,appdata0,TAKEPATHLEN);
10440 ckstrncat(takepath,"Kermit 95/;",TAKEPATHLEN);
10441 ckstrncat(takepath,appdata0,TAKEPATHLEN);
10442 ckstrncat(takepath,"Kermit 95/SCRIPTS/;",TAKEPATHLEN);
10443 ckstrncat(takepath,appdata0,TAKEPATHLEN);
10444 ckstrncat(takepath,"Kermit 95/KEYMAPS/;",TAKEPATHLEN);
10445
10446 ckstrncat(takepath,inidir,TAKEPATHLEN);
10447 ckstrncat(takepath,";",TAKEPATHLEN);
10448 ckstrncat(takepath,inidir,TAKEPATHLEN);
10449 ckstrncat(takepath,"SCRIPTS/;",TAKEPATHLEN);
10450 ckstrncat(takepath,inidir,TAKEPATHLEN);
10451 ckstrncat(takepath,"KEYMAPS/;",TAKEPATHLEN);
10452
10453 ckstrncat(takepath,zhome(),TAKEPATHLEN);
10454 ckstrncat(takepath,";",TAKEPATHLEN);
10455 ckstrncat(takepath,zhome(),TAKEPATHLEN);
10456 ckstrncat(takepath,"SCRIPTS/;",TAKEPATHLEN);
10457 ckstrncat(takepath,zhome(),TAKEPATHLEN);
10458 ckstrncat(takepath,"KEYMAPS/;",TAKEPATHLEN);
10459
10460 ckstrncat(takepath,exedir,TAKEPATHLEN);
10461 ckstrncat(takepath,";",TAKEPATHLEN);
10462 ckstrncat(takepath,exedir,TAKEPATHLEN);
10463 ckstrncat(takepath,"SCRIPTS/;",TAKEPATHLEN);
10464 ckstrncat(takepath,exedir,TAKEPATHLEN);
10465 ckstrncat(takepath,"KEYMAPS/;",TAKEPATHLEN);
10466 #endif /* OS2 */
10467 debug(F110,"TAKE final takepath",takepath,0);
10468
10469 if ((y = cmifip("Commands from file",
10470 "",&s,&x,0,takepath,xxstring)) < 0) {
10471 if (y == -3) {
10472 printf("?A file name is required\n");
10473 return(-9);
10474 } else
10475 return(y);
10476 }
10477 if (x != 0) {
10478 printf("?Wildcards not allowed in command file name\n");
10479 return(-9);
10480 }
10481 ckstrncpy(line,s,LINBUFSIZ);
10482 debug(F110,"TAKE file",s,0);
10483 if (isdir(s)) {
10484 printf("?Can't execute a directory - \"%s\"\n", s);
10485 return(-9);
10486 }
10487 #ifndef NOTAKEARGS
10488 {
10489 char * p;
10490 x = strlen(line);
10491 debug(F111,"TAKE args",line,x);
10492 p = line + x + 1;
10493 if ((y = cmtxt("Optional arguments","",&s,xxstring)) < 0)
10494 return(y);
10495 if (*s) { /* Args given? */
10496 ckstrncpy(p,s,LINBUFSIZ-x-1);
10497 #ifdef ZFNQFP
10498 zfnqfp(line,TMPBUFSIZ,tmpbuf);
10499 s = tmpbuf;
10500 #else
10501 s = line;
10502 #endif /* ZFNQFP */
10503 debug(F110,"TAKE filename",s,0);
10504 x = strlen(s);
10505 debug(F101,"TAKE new len",s,x);
10506
10507 #ifdef COMMENT
10508 /*
10509 This was added in C-Kermit 7.0 to allow args to be passed from the TAKE
10510 command to the command file. But it overwrites the current argument vector,
10511 which is at best surprising, and at worst unsafe.
10512 */
10513 addmac("%0",s); /* Define %0 = name of file */
10514 varnam[0] = '%';
10515 varnam[2] = '\0';
10516 debug(F110,"take arg 0",s,0);
10517 debug(F110,"take args",p,0);
10518 for (y = 1; y < 10; y++) { /* Clear current args %1..%9 */
10519 varnam[1] = (char) (y + '0');
10520 delmac(varnam,0);
10521 }
10522 xwords(p,MAXARGLIST,NULL,0); /* Assign new args */
10523 debug(F110,"take args",p,0);
10524 #else
10525 /*
10526 This method is used in 8.0. If the TAKE command includes arguments, we
10527 insert an intermediate temporary macro between the current level; we pass
10528 the arguments to the macro and then the macro TAKEs the command file.
10529 If the user Ctrl-C's out of the TAKE file, some temporary macro definitions
10530 and other small malloc'd bits might be left behind.
10531 */
10532 {
10533 char * q = NULL;
10534 char * r = NULL;
10535 int k, m;
10536 m = maclvl;
10537 q = (char *)malloc(x+24);
10538 if (q) {
10539 r = (char *)malloc(x+24);
10540 if (r) {
10541 sprintf(q,"_file[%s](%d)",s,cmdlvl); /* safe */
10542 sprintf(r,"take %s",s); /* safe */
10543 k = addmac(q,r);
10544 if (k > -1) {
10545 dodo(k,p,0);
10546 while (maclvl > m) {
10547 sstate = (CHAR) parser(1);
10548 if (sstate) proto();
10549 }
10550 }
10551 k = delmac(q,0);
10552 free(q);
10553 free(r);
10554 return(success);
10555 }
10556 }
10557 }
10558 return(success = 0);
10559 #endif /* COMMENT */
10560 }
10561 }
10562 #else
10563 if ((y = cmcfm()) < 0) return(y);
10564 #endif /* NOTAKEARGS */
10565 return(success = dotake(line));
10566 }
10567
10568 #ifndef NOLOCAL
10569 #ifdef OS2
10570 if (cx == XXVIEW) { /* VIEW Only Terminal mode */
10571 viewonly = TRUE;
10572 success = doconect(0, 0);
10573 viewonly = FALSE;
10574 return success;
10575 }
10576 #endif /* OS2 */
10577
10578 #ifdef NETCONN
10579 if (cx == XXTEL || cx == XXIKSD) { /* TELNET */
10580 int x,z;
10581 #ifdef OS2
10582 if (!tcp_avail) {
10583 printf("?Sorry, either TCP/IP is not available on this system or\n\
10584 necessary DLLs did not load. Use SHOW NETWORK to check network status.\n");
10585 success = 0;
10586 return(-9);
10587 } else
10588 #endif /* OS2 */
10589 {
10590 x = nettype; /* Save net type in case of failure */
10591 z = ttnproto; /* Save protocol in case of failure */
10592 nettype = NET_TCPB;
10593 ttnproto = (cx == XXTEL) ? NP_TELNET : NP_KERMIT;
10594 if ((y = setlin(XYHOST,0,1)) <= 0) {
10595 nettype = x; /* Failed, restore net type. */
10596 ttnproto = z; /* and protocol */
10597 success = 0;
10598 }
10599 didsetlin++;
10600 }
10601 return(y);
10602 }
10603
10604 #ifndef PTYORPIPE
10605 #ifdef NETCMD
10606 #define PTYORPIPE
10607 #else
10608 #ifdef NETPTY
10609 #define PTYORPIPE
10610 #endif /* NETPTY */
10611 #endif /* NETCMD */
10612 #endif /* PTYORPIPE */
10613
10614 #ifdef PTYORPIPE
10615 if (cx == XXPIPE || cx == XXPTY) { /* PIPE or PTY */
10616 int x;
10617 extern int netsave;
10618 x = nettype; /* Save net type in case of failure */
10619 nettype = (cx == XXPIPE) ? NET_CMD : NET_PTY;
10620 if ((y = setlin(XYHOST,0,1)) < 0) {
10621 nettype = x; /* Failed, restore net type. */
10622 ttnproto = z; /* and protocol */
10623 success = 0;
10624 }
10625 didsetlin++;
10626 netsave = x;
10627 return(y);
10628 }
10629 #endif /* PTYORPIPE */
10630
10631 #ifdef ANYSSH
10632 if (cx == XXSSH) { /* SSH (Secure Shell) */
10633 extern int netsave;
10634 #ifdef SSHBUILTIN
10635 int k, x, havehost = 0, trips = 0;
10636 int tmpver = -1, tmpxfw = -1;
10637 #ifndef SSHTEST
10638 extern int sl_ssh_xfw, sl_ssh_xfw_saved;
10639 extern int sl_ssh_ver, sl_ssh_ver_saved;
10640 #endif /* SSHTEST */
10641 extern int mdmtyp, mdmsav, cxtype, sl_uid_saved;
10642 extern char * slmsg;
10643 extern char uidbuf[], sl_uidbuf[];
10644 extern char pwbuf[], * g_pswd;
10645 extern int pwflg, pwcrypt, g_pflg, g_pcpt, nolocal;
10646 struct FDB sw, kw, fl;
10647
10648 if (ssh_tmpstr)
10649 memset(ssh_tmpstr,0,strlen(ssh_tmpstr));
10650 makestr(&ssh_tmpstr,NULL);
10651 makestr(&ssh_tmpuid,NULL);
10652 makestr(&ssh_tmpcmd,NULL);
10653 makestr(&ssh_tmpport,NULL);
10654
10655 cmfdbi(&kw, /* 1st FDB - commands */
10656 _CMKEY, /* fcode */
10657 "host [ port ],\n or action", /* hlpmsg */
10658 "", /* default */
10659 "", /* addtl string data */
10660 nsshcmd, /* addtl numeric data 1: tbl size */
10661 0, /* addtl numeric data 2: 0 = keyword */
10662 xxstring, /* Processing function */
10663 sshkwtab, /* Keyword table */
10664 &fl /* Pointer to next FDB */
10665 );
10666 cmfdbi(&fl, /* Host */
10667 _CMFLD, /* fcode */
10668 "", /* hlpmsg */
10669 "", /* default */
10670 "", /* addtl string data */
10671 0, /* addtl numeric data 1 */
10672 0, /* addtl numeric data 2 */
10673 xxstring,
10674 NULL,
10675 NULL
10676 );
10677
10678 x = cmfdb(&kw);
10679 if (x == -3) {
10680 printf("?ssh what?\n");
10681 return(-9);
10682 }
10683 if (x < 0)
10684 return(x);
10685 havehost = 0;
10686 if (cmresult.fcode == _CMFLD) {
10687 havehost = 1;
10688 ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Hostname */
10689 cmresult.nresult = XSSH_OPN;
10690 }
10691 switch (cmresult.nresult) { /* SSH keyword */
10692 case XSSH_OPN: /* SSH OPEN */
10693 if (!havehost) {
10694 if ((x = cmfld("Host","",&s,xxstring)) < 0)
10695 return(x);
10696 ckstrncpy(line,s,LINBUFSIZ);
10697 }
10698 /* Parse [ port ] [ switches ] */
10699 cmfdbi(&kw, /* Switches */
10700 _CMKEY,
10701 "Port number or service name,\nor switch",
10702 "",
10703 "",
10704 nsshopnsw,
10705 4,
10706 xxstring,
10707 sshopnsw,
10708 &fl
10709 );
10710 cmfdbi(&fl, /* Port number or service name */
10711 _CMFLD,
10712 "",
10713 "",
10714 "",
10715 0,
10716 0,
10717 xxstring,
10718 NULL,
10719 NULL
10720 );
10721 trips = 0; /* Explained below */
10722 while (1) { /* Parse port and switches */
10723 x = cmfdb(&kw); /* Get a field */
10724 if (x == -3) /* User typed CR so quit from loop */
10725 break;
10726 if (x < 0) /* Other parse error, pass it back */
10727 return(x);
10728 switch (cmresult.fcode) { /* Field or Keyword? */
10729 case _CMFLD: /* Field */
10730 makestr(&ssh_tmpport,cmresult.sresult);
10731 break;
10732 case _CMKEY: /* Keyword */
10733 switch (cmresult.nresult) { /* Which one? */
10734 case SSHSW_USR: /* /USER: */
10735 if (!cmgbrk()) {
10736 printf("?This switch requires an argument\n");
10737 return(-9);
10738 }
10739 if ((y = cmfld("Username","",&s,xxstring)) < 0)
10740 return(y);
10741 s = brstrip(s);
10742 makestr(&ssh_tmpuid,s);
10743 break;
10744 case SSHSW_PWD:
10745 if (!cmgbrk()) {
10746 printf("?This switch requires an argument\n");
10747 return(-9);
10748 }
10749 debok = 0;
10750 if ((x = cmfld("Password","",&s,xxstring)) < 0) {
10751 if (x == -3) {
10752 makestr(&ssh_tmpstr,"");
10753 } else {
10754 return(x);
10755 }
10756 } else {
10757 s = brstrip(s);
10758 if ((x = (int)strlen(s)) > PWBUFL) {
10759 makestr(&slmsg,"Internal error");
10760 printf("?Sorry, too long - max = %d\n",PWBUFL);
10761 return(-9);
10762 }
10763 makestr(&ssh_tmpstr,s);
10764 }
10765 break;
10766
10767 case SSHSW_VER:
10768 if ((x = cmnum("Number","",10,&z,xxstring)) < 0)
10769 return(x);
10770 if (z < 1 || z > 2) {
10771 printf("?Out of range: %d\n",z);
10772 return(-9);
10773 }
10774 tmpver = z;
10775 break;
10776 case SSHSW_CMD:
10777 case SSHSW_SUB:
10778 if ((x = cmfld("Text","",&s,xxstring)) < 0)
10779 return(x);
10780 makestr(&ssh_tmpcmd,s);
10781 ssh_cas = (cmresult.nresult == SSHSW_SUB);
10782 break;
10783 case SSHSW_X11:
10784 if ((x = cmkey(onoff,2,"","on",xxstring)) < 0)
10785 return(x);
10786 tmpxfw = x;
10787 break;
10788 default:
10789 return(-2);
10790 }
10791 }
10792 if (trips++ == 0) { /* After first time through */
10793 cmfdbi(&kw, /* only parse switches, not port. */
10794 _CMKEY,
10795 "Switch",
10796 "",
10797 "",
10798 nsshopnsw,
10799 4,
10800 xxstring,
10801 sshopnsw,
10802 NULL
10803 );
10804 }
10805 }
10806 if ((x = cmcfm()) < 0) /* Get confirmation */
10807 return(x);
10808 if (clskconnx(1) < 0) { /* Close current Kermit connection */
10809 if ( ssh_tmpstr ) {
10810 memset(ssh_tmpstr,0,strlen(ssh_tmpstr));
10811 makestr(&ssh_tmpstr,NULL);
10812 }
10813 return(success = 0);
10814 }
10815 makestr(&ssh_hst,line); /* Stash everything */
10816 if (ssh_tmpuid) {
10817 if (!sl_uid_saved) {
10818 ckstrncpy(sl_uidbuf,uidbuf,UIDBUFLEN);
10819 sl_uid_saved = 1;
10820 }
10821 ckstrncpy(uidbuf,ssh_tmpuid,UIDBUFLEN);
10822 makestr(&ssh_tmpuid,NULL);
10823 }
10824 if (ssh_tmpport) {
10825 makestr(&ssh_prt,ssh_tmpport);
10826 makestr(&ssh_tmpport,NULL);
10827 } else
10828 makestr(&ssh_prt,NULL);
10829
10830 if (ssh_tmpcmd) {
10831 makestr(&ssh_cmd,brstrip(ssh_tmpcmd));
10832 makestr(&ssh_tmpcmd,NULL);
10833 } else
10834 makestr(&ssh_cmd,NULL);
10835
10836 if (tmpver > -1) {
10837 #ifndef SSHTEST
10838 if (!sl_ssh_ver_saved) {
10839 sl_ssh_ver = ssh_ver;
10840 sl_ssh_ver_saved = 1;
10841 }
10842 #endif /* SSHTEST */
10843 ssh_ver = tmpver;
10844 }
10845 if (tmpxfw > -1) {
10846 #ifndef SSHTEST
10847 if (!sl_ssh_xfw_saved) {
10848 sl_ssh_xfw = ssh_xfw;
10849 sl_ssh_xfw_saved = 1;
10850 }
10851 #endif /* SSHTEST */
10852 ssh_xfw = tmpxfw;
10853 }
10854 if (ssh_tmpstr) {
10855 if (ssh_tmpstr[0]) {
10856 ckstrncpy(pwbuf,ssh_tmpstr,PWBUFL+1);
10857 pwflg = 1;
10858 pwcrypt = 0;
10859 } else
10860 pwflg = 0;
10861 makestr(&ssh_tmpstr,NULL);
10862 }
10863 nettype = NET_SSH;
10864 if (mdmsav < 0)
10865 mdmsav = mdmtyp;
10866 mdmtyp = -nettype;
10867 x = 1;
10868
10869 #ifndef NOSPL
10870 makestr(&g_pswd,pwbuf); /* Save global pwbuf */
10871 g_pflg = pwflg; /* and flag */
10872 g_pcpt = pwcrypt;
10873 #endif /* NOSPL */
10874
10875 /* Line parameter to ttopen() is ignored */
10876 debug(F110,"SSH line",line,0);
10877 k = ttopen(line,&x,mdmtyp, 0);
10878 if (k < 0) {
10879 printf("?Unable to connect to %s\n",ssh_hst);
10880 mdmtyp = mdmsav;
10881 slrestor();
10882 return(success = 0);
10883 }
10884 duplex = 0; /* Remote echo */
10885 ckstrncpy(ttname,line,TTNAMLEN); /* Record the command */
10886 debug(F110,"ssh ttname",ttname,0);
10887 makestr(&slmsg,NULL); /* No SET LINE error message */
10888 cxtype = CXT_SSH;
10889 #ifndef NODIAL
10890 dialsta = DIA_UNK;
10891 #endif /* NODIAL */
10892 success = 1; /* SET LINE succeeded */
10893 network = 1; /* Network connection (not serial) */
10894 local = 1; /* Local mode (not remote) */
10895 if ((reliable != SET_OFF || !setreliable))
10896 reliable = SET_ON; /* Transport is reliable end to end */
10897 #ifdef OS2
10898 DialerSend(OPT_KERMIT_CONNECT, 0);
10899 #endif /* OS2 */
10900 setflow(); /* Set appropriate flow control */
10901
10902 haveline = 1;
10903 #ifdef CKLOGDIAL
10904 #ifdef NETCONN
10905 dolognet();
10906 #endif /* NETCONN */
10907 #endif /* CKLOGDIAL */
10908
10909 #ifndef NOSPL
10910 if (local) {
10911 if (nmac) { /* Any macros defined? */
10912 int k; /* Yes */
10913 k = mlook(mactab,"on_open",nmac); /* Look this up */
10914 if (k >= 0) { /* If found, */
10915 if (dodo(k,ssh_hst,0) > -1) /* set it up, */
10916 parser(1); /* and execute it */
10917 }
10918 }
10919 }
10920 #endif /* NOSPL */
10921 #ifdef LOCUS
10922 if (autolocus)
10923 setlocus(1,1);
10924 #endif /* LOCUS */
10925
10926 /* Command was confirmed so we can pre-pop command level. */
10927 /* This is so CONNECT module won't think we're executing a */
10928 /* script if CONNECT was the final command in the script. */
10929 if (cmdlvl > 0)
10930 prepop();
10931 success = doconect(0,cmdlvl == 0 ? 1 : 0);
10932 if (ttchk() < 0)
10933 dologend();
10934 return(success);
10935
10936 case XSSH_CLR:
10937 if ((y = cmkey(sshclr,nsshclr,"","", xxstring)) < 0) {
10938 if (y == -3) {
10939 printf("?clear what?\n");
10940 return(-9);
10941 }
10942 return(y);
10943 }
10944 if ((x = cmcfm()) < 0)
10945 return(x);
10946 switch (y) {
10947 case SSHC_LPF:
10948 ssh_pf_lcl_n = 0;
10949 break;
10950 case SSHC_RPF:
10951 ssh_pf_rmt_n = 0;
10952 break;
10953 default:
10954 return(-2);
10955 }
10956 return(success = 1); /* or whatever */
10957
10958 case XSSH_AGT: { /* SSH AGENT */
10959 int doeach = 0;
10960 if ((y = cmkey(sshagent,nsshagent,"","",xxstring)) < 0)
10961 return(y);
10962 switch (y) {
10963 case SSHA_ADD: /* SSH AGENT ADD ... */
10964 if ((x = cmifi("Identity file","",&s,&y,xxstring)) < 0) {
10965 #ifndef SSHTEST
10966 if (x == -3) /* No name given */
10967 doeach = 1; /* so do them all */
10968 else
10969 #endif /* SSHTEST */
10970 return(x);
10971 }
10972 ckstrncpy(line,s,LINBUFSIZ);
10973 if ((x = cmcfm()) < 0)
10974 return(x);
10975 #ifdef SSHTEST
10976 x = 0;
10977 #else
10978 if (doeach) {
10979 int i;
10980 x = 0;
10981 for (i = 0; i < ssh_idf_n; i++)
10982 x += ssh_agent_add_file(ssh_idf[i]);
10983 } else
10984 x = ssh_agent_add_file(line);
10985 #endif /* SSHTEST */
10986 return(success = (x == 0));
10987
10988 case SSHA_DEL: { /* SSH AGENT DELETE ... */
10989 int doall = 0;
10990 if ((x = cmifi("Identity file","",&s,&y,xxstring)) < 0) {
10991 #ifndef SSHTEST
10992 if (x == -3) /* No name given */
10993 doall = 1; /* so do them all */
10994 else
10995 #endif /* SSHTEST */
10996 return(x);
10997 }
10998 ckstrncpy(line,s,LINBUFSIZ);
10999 if ((x = cmcfm()) < 0)
11000 return(x);
11001 #ifdef SSHTEST
11002 x = 0;
11003 #else
11004 if (doall)
11005 x = ssh_agent_delete_all();
11006 else
11007 x = ssh_agent_delete_file(line);
11008 #endif /* SSHTEST */
11009 return(success = (x == 0));
11010 }
11011 case SSHA_LST: {
11012 int fingerprint = 0;
11013 if ((y = cmswi(sshagtsw,nsshagtsw,"","",xxstring)) < 0) {
11014 if (y != -3)
11015 return(y);
11016 } else if (cmgbrk() > SP) {
11017 printf("?This switch does not take an argument\n");
11018 return(-9);
11019 } else if (y == SSHASW_FP) {
11020 fingerprint = 1;
11021 }
11022 if ((x = cmcfm()) < 0)
11023 return(x);
11024 #ifdef SSHTEST
11025 return(success = 1);
11026 #else
11027 return(success =
11028 (ssh_agent_list_identities(fingerprint) == 0));
11029 #endif /* SSHTEST */
11030 }
11031 default:
11032 return(-2);
11033 }
11034 }
11035 case XSSH_ADD: { /* SSH ADD */
11036 /* ssh add { local, remote } port host port */
11037 int cx, i, j, k;
11038 char * h;
11039 if ((cx = cmkey(addfwd,naddfwd,"","", xxstring)) < 0)
11040 return(cx);
11041 if ((x = cmnum((cx == SSHF_LCL) ?
11042 "Local port number" : "Remote port number",
11043 "",10,&j,xxstring)) < 0)
11044 return(x);
11045 if ((x = cmfld("Host","",&s,xxstring)) < 0)
11046 return(x);
11047 makestr(&h,s);
11048 if ((x = cmnum("Port","",10,&k,xxstring)) < 0)
11049 return(x);
11050 if ((x = cmcfm()) < 0)
11051 return(x);
11052
11053 switch(cx) {
11054 case SSHF_LCL:
11055 if (ssh_pf_lcl_n == 32) {
11056 printf(
11057 "?Maximum number of local port forwardings already specified\n"
11058 );
11059 free(h);
11060 return(success = 0);
11061 }
11062 ssh_pf_lcl[ssh_pf_lcl_n].p1 = j;
11063 makestr(&(ssh_pf_lcl[ssh_pf_lcl_n].host),h);
11064 makestr(&h,NULL);
11065 ssh_pf_lcl[ssh_pf_lcl_n].p2 = k;
11066 ssh_pf_lcl_n++;
11067 break;
11068 case SSHF_RMT:
11069 if (ssh_pf_rmt_n == 32) {
11070 printf(
11071 "?Maximum number of remote port forwardings already specified\n"
11072 );
11073 free(h);
11074 return(success = 0);
11075 }
11076 ssh_pf_rmt[ssh_pf_rmt_n].p1 = j;
11077 makestr(&(ssh_pf_rmt[ssh_pf_rmt_n].host),h);
11078 makestr(&h,NULL);
11079 ssh_pf_rmt[ssh_pf_rmt_n].p2 = k;
11080 ssh_pf_rmt_n++;
11081 }
11082 return(success = 1);
11083 }
11084 /* Not supporting arbitrary forwarding yet */
11085 case XSSH_FLP: /* SSH FORWARD-LOCAL-PORT */
11086 case XSSH_FRP: { /* SSH FORWARD-REMOTE-PORT */
11087 int li_port = 0;
11088 int to_port = 0;
11089 char * fw_host = NULL;
11090 int n;
11091 if ((x = cmnum(cmresult.nresult == XSSH_FLP ?
11092 "local-port":"remote-port",
11093 "",10,&li_port,xxstring)) < 0)
11094 return(x);
11095 if (li_port < 1 || li_port > 65535) {
11096 printf("?Out range - min: 1, max: 65535\n");
11097 return(-9);
11098 }
11099 if ((x = cmfld("host",ssh_hst?ssh_hst:"",&s,xxstring)) < 0)
11100 return(x);
11101 n = ckstrncpy(tmpbuf,s,TMPBUFSIZ);
11102 fw_host = tmpbuf;
11103 if ((x = cmnum("host-port",ckuitoa(li_port),10,
11104 &to_port,xxstring)) < 0)
11105 return(x);
11106 if (to_port < 1 || to_port > 65535) {
11107 printf("?Out range - min: 1, max: 65535\n");
11108 return(-9);
11109 }
11110 if ((x = cmcfm()) < 0)
11111 return(x);
11112 switch (cmresult.nresult) {
11113 case XSSH_FLP: /* SSH FORWARD-LOCAL-PORT */
11114 #ifndef SSHTEST
11115 ssh_fwd_local_port(li_port,fw_host,to_port);
11116 #endif /* SSHTEST */
11117 return(success = 1);
11118 case XSSH_FRP: /* SSH FORWARD-REMOTE-PORT */
11119 #ifndef SSHTEST
11120 ssh_fwd_remote_port(li_port,fw_host,to_port);
11121 #endif /* SSHTEST */
11122 return(success = 1);
11123 }
11124 return(success = 1);
11125 }
11126 case XSSH_V2: /* SSH V2 */
11127 if ((cx = cmkey(ssh2tab,nssh2tab,"","", xxstring)) < 0)
11128 return(cx);
11129 switch (cx) {
11130 case XSSH2_RKE:
11131 if ((x = cmcfm()) < 0)
11132 return(x);
11133 #ifndef SSHTEST
11134 ssh_v2_rekey();
11135 #endif /* SSHTEST */
11136 return(success = 1);
11137 default:
11138 return(-2);
11139 }
11140 case XSSH_KEY:
11141 if ((cx = cmkey(sshkey,nsshkey,"","", xxstring)) < 0)
11142 return(cx);
11143 switch (cx) {
11144 case SSHK_PASS: { /* Change passphrase */
11145 char * oldp = NULL, * newp = NULL;
11146 struct FDB df, sw;
11147 cmfdbi(&sw,
11148 _CMKEY, /* fcode */
11149 "Filename, or switch", /* hlpmsg */
11150 "", /* default */
11151 "", /* addtl string data */
11152 2, /* addtl numeric data 1: tbl size */
11153 4, /* addtl numeric data 2: 4 = cmswi */
11154 xxstring, /* Processing function */
11155 sshkpsw, /* Keyword table */
11156 &df /* Pointer to next FDB */
11157 );
11158 cmfdbi(&df, /* 2nd FDB - file for display */
11159 _CMIFI, /* output file */
11160 "", /* hlpmsg */
11161 "", /* default */
11162 "", /* addtl string data */
11163 0, /* addtl numeric data 1 */
11164 0, /* addtl numeric data 2 */
11165 xxstring,
11166 NULL,
11167 NULL
11168 );
11169 line[0] = NUL;
11170
11171 while (1) {
11172 x = cmfdb(&sw);
11173 if (x == -3) break;
11174 if (x < 0)
11175 return(x);
11176 if (cmresult.fcode != _CMKEY)
11177 break;
11178 if (!cmgbrk()) {
11179 printf("?This switch requires an argument\n");
11180 return(-9);
11181 }
11182 if ((y = cmfld("Passphrase","",&s,xxstring)) < 0)
11183 return(y);
11184 switch (cmresult.nresult) {
11185 case 1: /* Old */
11186 makestr(&oldp,s);
11187 break;
11188 case 2: /* New */
11189 makestr(&newp,s);
11190 }
11191 }
11192 if (cmresult.fcode == _CMIFI) { /* Filename */
11193 ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
11194 if (zfnqfp(line,TMPBUFSIZ,tmpbuf))
11195 ckstrncpy(line,tmpbuf,LINBUFSIZ);
11196 }
11197 if ((x = cmcfm()) < 0) return(x);
11198
11199 #ifndef SSHTEST
11200 x = sshkey_change_passphrase(line[0] ? line : NULL,
11201 oldp, newp);
11202 #endif /* SSHTEST */
11203 makestr(&oldp,NULL);
11204 makestr(&newp,NULL);
11205 success = (x == 0);
11206 return(success);
11207 }
11208 case SSHK_CREA: { /* SSH KEY CREATE /switches... */
11209 int bits = 1024, keytype = SSHKT_2R;
11210 char * pass = NULL, * comment = NULL;
11211 struct FDB df, sw;
11212
11213 /*
11214 * char * sshkey_default_file(int keytype)
11215 * will provide the default filename for a given keytype
11216 * is it possible to have the default value for the 2nd
11217 * FDB set and changed when a /TYPE switch is provided?
11218 * Would this allow for tab completion of the filename?
11219 */
11220 cmfdbi(&sw,
11221 _CMKEY, /* fcode */
11222 "Filename, or switch", /* hlpmsg */
11223 "", /* default */
11224 "", /* addtl string data */
11225 nsshkcrea, /* addtl numeric data 1: tbl size */
11226 4, /* addtl numeric data 2: 4 = cmswi */
11227 xxstring, /* Processing function */
11228 sshkcrea, /* Keyword table */
11229 &df /* Pointer to next FDB */
11230 );
11231 cmfdbi(&df, /* 2nd FDB - file for display */
11232 _CMOFI, /* output file */
11233 "", /* hlpmsg */
11234 "", /* default */
11235 "", /* addtl string data */
11236 0, /* addtl numeric data 1 */
11237 0, /* addtl numeric data 2 */
11238 xxstring,
11239 NULL,
11240 NULL
11241 );
11242 line[0] = NUL;
11243
11244 while (1) {
11245 x = cmfdb(&sw);
11246 if (x == -3) break;
11247 if (x < 0)
11248 return(x);
11249 if (cmresult.fcode != _CMKEY)
11250 break;
11251 if (!cmgbrk()) {
11252 printf("?This switch requires an argument\n");
11253 return(-9);
11254 }
11255 switch (cmresult.nresult) {
11256 case SSHKC_BI: /* /BITS:n */
11257 if ((y = cmnum("","1024",10,&z,xxstring)) < 0)
11258 return(y);
11259 if (z < 512 || z > 4096) {
11260 printf("?Out range - min: 512, max: 4096\n");
11261 return(-9);
11262 }
11263 bits = z;
11264 break;
11265 case SSHKC_PP: /* /PASSPHRASE:blah */
11266 if ((y = cmfld("Passphrase","",&s,xxstring)) < 0)
11267 return(y);
11268 makestr(&pass,s);
11269 break;
11270 case SSHKC_TY: /* /TYPE:keyword */
11271 if ((y = cmkey(sshkcty,nsshkcty,"",
11272 "v2-rsa",xxstring)) < 0)
11273 return(y);
11274 keytype = y;
11275 break;
11276 case SSHKC_1R: /* /COMMENT */
11277 if ((y = cmfld("Text","",&s,xxstring)) < 0)
11278 return(y);
11279 makestr(&comment,s);
11280 break;
11281 }
11282 }
11283 if (cmresult.fcode == _CMOFI) { /* Filename */
11284 if (cmresult.sresult) {
11285 ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
11286 if (zfnqfp(line,TMPBUFSIZ,tmpbuf))
11287 ckstrncpy(line,tmpbuf,LINBUFSIZ);
11288 }
11289 }
11290 if ((y = cmcfm()) < 0) /* Confirm */
11291 return(y);
11292 #ifndef SSHTEST
11293 x = sshkey_create(line[0] ? line : NULL,
11294 bits, pass, keytype, comment);
11295 if (pass)
11296 memset(pass,0,strlen(pass));
11297 #endif /* SSHTEST */
11298 makestr(&pass,NULL);
11299 makestr(&comment,NULL);
11300 return(success = (x == 0));
11301 }
11302 case SSHK_DISP: { /* SSH KEY DISPLAY /switches... */
11303 char c;
11304 int infmt = 0, outfmt = 0;
11305 struct FDB df, sw;
11306 cmfdbi(&sw,
11307 _CMKEY, /* fcode */
11308 "Filename, or switch", /* hlpmsg */
11309 "", /* default */
11310 "", /* addtl string data */
11311 nsshdswi, /* addtl numeric data 1: tbl size */
11312 4, /* addtl numeric data 2: 4 = cmswi */
11313 xxstring, /* Processing function */
11314 sshdswi, /* Keyword table */
11315 &df /* Pointer to next FDB */
11316 );
11317 cmfdbi(&df, /* 2nd FDB - file for display */
11318 _CMIFI, /* fcode */
11319 "", /* hlpmsg */
11320 "", /* default */
11321 "", /* addtl string data */
11322 0, /* addtl numeric data 1 */
11323 0, /* addtl numeric data 2 */
11324 xxstring,
11325 NULL,
11326 NULL
11327 );
11328 line[0] = NUL;
11329
11330 while (1) {
11331 x = cmfdb(&sw);
11332 if (x == -3) break;
11333 if (x < 0)
11334 return(x);
11335 if (cmresult.fcode != _CMKEY)
11336 break;
11337 if (!cmgbrk()) {
11338 printf("?This switch requires an argument\n");
11339 return(-9);
11340 }
11341 switch (cmresult.nresult) {
11342 #ifdef COMMENT
11343 case SSHKD_IN: /* /IN-FORMAT: */
11344 if ((y = cmkey(sshdifmt,nsshdifmt,
11345 "","",xxstring)) < 0)
11346 return(y);
11347 infmt = y;
11348 break;
11349 #endif /* COMMENT */
11350 case SSHKD_OUT: /* /FORMAT: */
11351 if ((y = cmkey(sshdofmt,nsshdofmt,
11352 "","",xxstring)) < 0)
11353 return(y);
11354 outfmt = y;
11355 break;
11356 }
11357 }
11358 if (cmresult.fcode == _CMIFI) { /* Filename */
11359 ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
11360 if (zfnqfp(line,TMPBUFSIZ,tmpbuf))
11361 ckstrncpy(line,tmpbuf,LINBUFSIZ);
11362 }
11363 #ifdef COMMENT
11364 if (!line[0]) {
11365 printf("?Key filename required\n");
11366 return(-9);
11367 }
11368 #endif /* COMMENT */
11369 if ((y = cmcfm()) < 0) /* Confirm */
11370 return(y);
11371 #ifndef SSHTEST
11372 switch (outfmt) {
11373 case SKDF_OSSH:
11374 /* 2nd param is optional passphrase */
11375 x = sshkey_display_public(line[0] ? line : NULL, NULL);
11376 break;
11377 case SKDF_SSHC:
11378 /* 2nd param is optional passphrase */
11379 x = sshkey_display_public_as_ssh2(line[0] ? line : NULL,
11380 NULL);
11381 break;
11382 case SKDF_IETF:
11383 x = sshkey_display_fingerprint(line[0] ? line : NULL, 1);
11384 break;
11385 case SKDF_FING:
11386 x = sshkey_display_fingerprint(line[0] ? line : NULL, 0);
11387 break;
11388 }
11389 #endif /* SSHTEST */
11390 return(success = (x == 0));
11391 }
11392 case SSHK_V1: /* SSH KEY V1 SET-COMMENT */
11393 if ((x = cmkey(sshkv1,1,"","set-comment", xxstring)) < 0)
11394 return(x);
11395 if (x != 1) return(-2);
11396 if ((x = cmifi("Key file name","",&s,&y,xxstring)) < 0) {
11397 if (x == -3) {
11398 printf("?Name of key file required\n");
11399 return(-9);
11400 }
11401 }
11402 ckstrncpy(line,s,LINBUFSIZ);
11403 if ((x = cmtxt("Comment text","",&s,xxstring)) < 0)
11404 return(x);
11405 #ifndef SSHTEST
11406 x = sshkey_v1_change_comment(line, /* filename */
11407 s, /* new comment */
11408 NULL /* passphrase */
11409 );
11410 #endif /* SSHTEST */
11411 success = (x == 0);
11412 return(success);
11413 }
11414 default:
11415 return(-2);
11416 }
11417 #else /* SSHBUILTIN */
11418 #ifdef SSHCMD
11419 x = nettype;
11420 if ((y = setlin(XXSSH,0,1)) < 0) {
11421 if (errno)
11422 printf("?%s\n",ck_errstr());
11423 else
11424 #ifdef COMMENT
11425 /* This isn't right either because it catches command editing */
11426 printf("?Sorry, pseudoterminal open failed\n");
11427 if (hints)
11428 printf("Hint: Try \"ssh -t %s\"\n",line);
11429 #else
11430 return(y);
11431 #endif /* COMMENT */
11432 nettype = x; /* Failed, restore net type. */
11433 ttnproto = z; /* and protocol */
11434 success = 0;
11435 }
11436 didsetlin++;
11437 netsave = x;
11438 return(y);
11439 #endif /* SSHCMD */
11440 #endif /* SSHBUILTIN */
11441 }
11442 #endif /* ANYSSH */
11443
11444 #ifdef SSHBUILTIN
11445 if (cx == XXSKRM) { /* SKERMIT (Secure Shell Kermit) */
11446 extern int netsave;
11447 int k, x, havehost = 0, trips = 0;
11448 int tmpver = -1, tmpxfw = -1;
11449 #ifndef SSHTEST
11450 extern int sl_ssh_xfw, sl_ssh_xfw_saved;
11451 extern int sl_ssh_ver, sl_ssh_ver_saved;
11452 #endif /* SSHTEST */
11453 extern int mdmtyp, mdmsav, cxtype, sl_uid_saved;
11454 extern char * slmsg;
11455 extern char uidbuf[], sl_uidbuf[];
11456 extern char pwbuf[], * g_pswd;
11457 extern int pwflg, pwcrypt, g_pflg, g_pcpt, nolocal;
11458 struct FDB sw, kw, fl;
11459
11460 if (ssh_tmpstr)
11461 memset(ssh_tmpstr,0,strlen(ssh_tmpstr));
11462 makestr(&ssh_tmpstr,NULL);
11463 makestr(&ssh_tmpuid,NULL);
11464 makestr(&ssh_tmpcmd,NULL);
11465 makestr(&ssh_tmpport,NULL);
11466
11467 cmfdbi(&kw, /* 1st FDB - commands */
11468 _CMKEY, /* fcode */
11469 "host [ port ],\n or action", /* hlpmsg */
11470 "", /* default */
11471 "", /* addtl string data */
11472 nsshkermit, /* addtl numeric data 1: tbl size */
11473 0, /* addtl numeric data 2: 0 = keyword */
11474 xxstring, /* Processing function */
11475 sshkermit, /* Keyword table */
11476 &fl /* Pointer to next FDB */
11477 );
11478 cmfdbi(&fl, /* Host */
11479 _CMFLD, /* fcode */
11480 "", /* hlpmsg */
11481 "", /* default */
11482 "", /* addtl string data */
11483 0, /* addtl numeric data 1 */
11484 0, /* addtl numeric data 2 */
11485 xxstring,
11486 NULL,
11487 NULL
11488 );
11489
11490 x = cmfdb(&kw);
11491 if (x == -3) {
11492 printf("?skermit what?\n");
11493 return(-9);
11494 }
11495 if (x < 0)
11496 return(x);
11497 havehost = 0;
11498 if (cmresult.fcode == _CMFLD) {
11499 havehost = 1;
11500 ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Hostname */
11501 cmresult.nresult = SKRM_OPN;
11502 }
11503 switch (cmresult.nresult) { /* SSH keyword */
11504 case SKRM_OPN: /* SSH OPEN */
11505 if (!havehost) {
11506 if ((x = cmfld("Host","",&s,xxstring)) < 0)
11507 return(x);
11508 ckstrncpy(line,s,LINBUFSIZ);
11509 }
11510 /* Parse [ port ] [ switches ] */
11511 cmfdbi(&kw, /* Switches */
11512 _CMKEY,
11513 "Port number or service name,\nor switch",
11514 "",
11515 "",
11516 nsshkrmopnsw,
11517 4,
11518 xxstring,
11519 sshkrmopnsw,
11520 &fl
11521 );
11522 cmfdbi(&fl, /* Port number or service name */
11523 _CMFLD,
11524 "",
11525 "",
11526 "",
11527 0,
11528 0,
11529 xxstring,
11530 NULL,
11531 NULL
11532 );
11533 trips = 0; /* Explained below */
11534 while (1) { /* Parse port and switches */
11535 x = cmfdb(&kw); /* Get a field */
11536 if (x == -3) /* User typed CR so quit from loop */
11537 break;
11538 if (x < 0) /* Other parse error, pass it back */
11539 return(x);
11540 switch (cmresult.fcode) { /* Field or Keyword? */
11541 case _CMFLD: /* Field */
11542 makestr(&ssh_tmpport,cmresult.sresult);
11543 break;
11544 case _CMKEY: /* Keyword */
11545 switch (cmresult.nresult) { /* Which one? */
11546 case SSHSW_USR: /* /USER: */
11547 if (!cmgbrk()) {
11548 printf("?This switch requires an argument\n");
11549 return(-9);
11550 }
11551 if ((y = cmfld("Username","",&s,xxstring)) < 0)
11552 return(y);
11553 s = brstrip(s);
11554 makestr(&ssh_tmpuid,s);
11555 break;
11556 case SSHSW_PWD:
11557 if (!cmgbrk()) {
11558 printf("?This switch requires an argument\n");
11559 return(-9);
11560 }
11561 debok = 0;
11562 if ((x = cmfld("Password","",&s,xxstring)) < 0) {
11563 if (x == -3) {
11564 makestr(&ssh_tmpstr,"");
11565 } else {
11566 return(x);
11567 }
11568 } else {
11569 s = brstrip(s);
11570 if ((x = (int)strlen(s)) > PWBUFL) {
11571 makestr(&slmsg,"Internal error");
11572 printf("?Sorry, too long - max = %d\n",PWBUFL);
11573 return(-9);
11574 }
11575 makestr(&ssh_tmpstr,s);
11576 }
11577 break;
11578
11579 case SSHSW_VER:
11580 if ((x = cmnum("Number","",10,&z,xxstring)) < 0)
11581 return(x);
11582 if (z < 1 || z > 2) {
11583 printf("?Out of range: %d\n",z);
11584 return(-9);
11585 }
11586 tmpver = z;
11587 break;
11588 default:
11589 return(-2);
11590 }
11591 }
11592 if (trips++ == 0) { /* After first time through */
11593 cmfdbi(&kw, /* only parse switches, not port. */
11594 _CMKEY,
11595 "Switch",
11596 "",
11597 "",
11598 nsshkrmopnsw,
11599 4,
11600 xxstring,
11601 sshkrmopnsw,
11602 NULL
11603 );
11604 }
11605 }
11606 if ((x = cmcfm()) < 0) /* Get confirmation */
11607 return(x);
11608 if (clskconnx(1) < 0) { /* Close current Kermit connection */
11609 if ( ssh_tmpstr ) {
11610 memset(ssh_tmpstr,0,strlen(ssh_tmpstr));
11611 makestr(&ssh_tmpstr,NULL);
11612 }
11613 return(success = 0);
11614 }
11615 makestr(&ssh_hst,line); /* Stash everything */
11616 if (ssh_tmpuid) {
11617 if (!sl_uid_saved) {
11618 ckstrncpy(sl_uidbuf,uidbuf,UIDBUFLEN);
11619 sl_uid_saved = 1;
11620 }
11621 ckstrncpy(uidbuf,ssh_tmpuid,UIDBUFLEN);
11622 makestr(&ssh_tmpuid,NULL);
11623 }
11624 if (ssh_tmpport) {
11625 makestr(&ssh_prt,ssh_tmpport);
11626 makestr(&ssh_tmpport,NULL);
11627 } else
11628 makestr(&ssh_prt,NULL);
11629
11630 /* Set the Subsystem to Kermit */
11631 ssh_cas = 1;
11632 makestr(&ssh_cmd,"kermit");
11633
11634 if (tmpver > -1) {
11635 #ifndef SSHTEST
11636 if (!sl_ssh_ver_saved) {
11637 sl_ssh_ver = ssh_ver;
11638 sl_ssh_ver_saved = 1;
11639 }
11640 #endif /* SSHTEST */
11641 ssh_ver = tmpver;
11642 }
11643 /* Disable X11 Forwarding */
11644 #ifndef SSHTEST
11645 if (!sl_ssh_xfw_saved) {
11646 sl_ssh_xfw = ssh_xfw;
11647 sl_ssh_xfw_saved = 1;
11648 }
11649 #endif /* SSHTEST */
11650 ssh_xfw = 0;
11651
11652 if (ssh_tmpstr) {
11653 if (ssh_tmpstr[0]) {
11654 ckstrncpy(pwbuf,ssh_tmpstr,PWBUFL+1);
11655 pwflg = 1;
11656 pwcrypt = 0;
11657 } else
11658 pwflg = 0;
11659 makestr(&ssh_tmpstr,NULL);
11660 }
11661 nettype = NET_SSH;
11662 if (mdmsav < 0)
11663 mdmsav = mdmtyp;
11664 mdmtyp = -nettype;
11665 x = 1;
11666
11667 #ifndef NOSPL
11668 makestr(&g_pswd,pwbuf); /* Save global pwbuf */
11669 g_pflg = pwflg; /* and flag */
11670 g_pcpt = pwcrypt;
11671 #endif /* NOSPL */
11672
11673 /* Line parameter to ttopen() is ignored */
11674 k = ttopen(line,&x,mdmtyp, 0);
11675 if (k < 0) {
11676 printf("?Unable to connect to %s\n",ssh_hst);
11677 mdmtyp = mdmsav;
11678 slrestor();
11679 return(success = 0);
11680 }
11681 duplex = 0; /* Remote echo */
11682 ckstrncpy(ttname,line,TTNAMLEN); /* Record the command */
11683 debug(F110,"ssh ttname",ttname,0);
11684 makestr(&slmsg,NULL); /* No SET LINE error message */
11685 cxtype = CXT_SSH;
11686 #ifndef NODIAL
11687 dialsta = DIA_UNK;
11688 #endif /* NODIAL */
11689 success = 1; /* SET LINE succeeded */
11690 network = 1; /* Network connection (not serial) */
11691 local = 1; /* Local mode (not remote) */
11692 if ((reliable != SET_OFF || !setreliable))
11693 reliable = SET_ON; /* Transport is reliable end to end */
11694 #ifdef OS2
11695 DialerSend(OPT_KERMIT_CONNECT, 0);
11696 #endif /* OS2 */
11697 setflow(); /* Set appropriate flow control */
11698
11699 haveline = 1;
11700 #ifdef CKLOGDIAL
11701 #ifdef NETCONN
11702 dolognet();
11703 #endif /* NETCONN */
11704 #endif /* CKLOGDIAL */
11705
11706 #ifndef NOSPL
11707 if (local) {
11708 if (nmac) { /* Any macros defined? */
11709 int k; /* Yes */
11710 k = mlook(mactab,"on_open",nmac); /* Look this up */
11711 if (k >= 0) { /* If found, */
11712 if (dodo(k,ssh_hst,0) > -1) /* set it up, */
11713 parser(1); /* and execute it */
11714 }
11715 }
11716 }
11717 #endif /* NOSPL */
11718 #ifdef LOCUS
11719 if (autolocus)
11720 setlocus(1,1);
11721 #endif /* LOCUS */
11722
11723 /* Command was confirmed so we can pre-pop command level. */
11724 /* This is so CONNECT module won't think we're executing a */
11725 /* script if CONNECT was the final command in the script. */
11726 if (cmdlvl > 0)
11727 prepop();
11728 return(success = 1);
11729
11730 default:
11731 return(-2);
11732 }
11733 }
11734 #endif /* SSHBUILTIN */
11735
11736 #ifdef SFTP_BUILTIN
11737 if (cx == XXSFTP) { /* SFTP (Secure Shell File Transfer) */
11738 extern int netsave;
11739 int k, x, havehost = 0, trips = 0;
11740 int tmpver = -1, tmpxfw = -1;
11741 #ifndef SSHTEST
11742 extern int sl_ssh_xfw, sl_ssh_xfw_saved;
11743 extern int sl_ssh_ver, sl_ssh_ver_saved;
11744 #endif /* SSHTEST */
11745 extern int mdmtyp, mdmsav, cxtype, sl_uid_saved;
11746 extern char * slmsg;
11747 extern char uidbuf[], sl_uidbuf[];
11748 extern char pwbuf[], * g_pswd;
11749 extern int pwflg, pwcrypt, g_pflg, g_pcpt, nolocal;
11750 struct FDB sw, kw, fl;
11751
11752 if (ssh_tmpstr)
11753 memset(ssh_tmpstr,0,strlen(ssh_tmpstr));
11754 makestr(&ssh_tmpstr,NULL);
11755 makestr(&ssh_tmpuid,NULL);
11756 makestr(&ssh_tmpcmd,NULL);
11757 makestr(&ssh_tmpport,NULL);
11758
11759 cmfdbi(&kw, /* 1st FDB - commands */
11760 _CMKEY, /* fcode */
11761 "host [ port ],\n or action", /* hlpmsg */
11762 "", /* default */
11763 "", /* addtl string data */
11764 nsftpkwtab, /* addtl numeric data 1: tbl size */
11765 0, /* addtl numeric data 2: 0 = keyword */
11766 xxstring, /* Processing function */
11767 sftpkwtab, /* Keyword table */
11768 &fl /* Pointer to next FDB */
11769 );
11770 cmfdbi(&fl, /* Host */
11771 _CMFLD, /* fcode */
11772 "", /* hlpmsg */
11773 "", /* default */
11774 "", /* addtl string data */
11775 0, /* addtl numeric data 1 */
11776 0, /* addtl numeric data 2 */
11777 xxstring,
11778 NULL,
11779 NULL
11780 );
11781
11782 x = cmfdb(&kw);
11783 if (x == -3) {
11784 printf("?sftp what?\n");
11785 return(-9);
11786 }
11787 if (x < 0)
11788 return(x);
11789 havehost = 0;
11790 if (cmresult.fcode == _CMFLD) {
11791 havehost = 1;
11792 ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Hostname */
11793 cmresult.nresult = SFTP_OPN;
11794 }
11795 switch (cmresult.nresult) { /* SFTP keyword */
11796 case SFTP_OPN: /* SFTP OPEN */
11797 if (!havehost) {
11798 if ((x = cmfld("Host","",&s,xxstring)) < 0)
11799 return(x);
11800 ckstrncpy(line,s,LINBUFSIZ);
11801 }
11802 /* Parse [ port ] [ switches ] */
11803 cmfdbi(&kw, /* Switches */
11804 _CMKEY,
11805 "Port number or service name,\nor switch",
11806 "",
11807 "",
11808 nsshkrmopnsw,
11809 4,
11810 xxstring,
11811 sshkrmopnsw,
11812 &fl
11813 );
11814 cmfdbi(&fl, /* Port number or service name */
11815 _CMFLD,
11816 "",
11817 "",
11818 "",
11819 0,
11820 0,
11821 xxstring,
11822 NULL,
11823 NULL
11824 );
11825 trips = 0; /* Explained below */
11826 while (1) { /* Parse port and switches */
11827 x = cmfdb(&kw); /* Get a field */
11828 if (x == -3) /* User typed CR so quit from loop */
11829 break;
11830 if (x < 0) /* Other parse error, pass it back */
11831 return(x);
11832 switch (cmresult.fcode) { /* Field or Keyword? */
11833 case _CMFLD: /* Field */
11834 makestr(&ssh_tmpport,cmresult.sresult);
11835 break;
11836 case _CMKEY: /* Keyword */
11837 switch (cmresult.nresult) { /* Which one? */
11838 case SSHSW_USR: /* /USER: */
11839 if (!cmgbrk()) {
11840 printf("?This switch requires an argument\n");
11841 return(-9);
11842 }
11843 if ((y = cmfld("Username","",&s,xxstring)) < 0)
11844 return(y);
11845 s = brstrip(s);
11846 makestr(&ssh_tmpuid,s);
11847 break;
11848 case SSHSW_PWD:
11849 if (!cmgbrk()) {
11850 printf("?This switch requires an argument\n");
11851 return(-9);
11852 }
11853 debok = 0;
11854 if ((x = cmfld("Password","",&s,xxstring)) < 0) {
11855 if (x == -3) {
11856 makestr(&ssh_tmpstr,"");
11857 } else {
11858 return(x);
11859 }
11860 } else {
11861 s = brstrip(s);
11862 if ((x = (int)strlen(s)) > PWBUFL) {
11863 makestr(&slmsg,"Internal error");
11864 printf("?Sorry, too long - max = %d\n",PWBUFL);
11865 return(-9);
11866 }
11867 makestr(&ssh_tmpstr,s);
11868 }
11869 break;
11870
11871 case SSHSW_VER:
11872 if ((x = cmnum("Number","",10,&z,xxstring)) < 0)
11873 return(x);
11874 if (z < 1 || z > 2) {
11875 printf("?Out of range: %d\n",z);
11876 return(-9);
11877 }
11878 tmpver = z;
11879 break;
11880 default:
11881 return(-2);
11882 }
11883 }
11884 if (trips++ == 0) { /* After first time through */
11885 cmfdbi(&kw, /* only parse switches, not port. */
11886 _CMKEY,
11887 "Switch",
11888 "",
11889 "",
11890 nsshkrmopnsw,
11891 4,
11892 xxstring,
11893 sshkrmopnsw,
11894 NULL
11895 );
11896 }
11897 }
11898 if ((x = cmcfm()) < 0) /* Get confirmation */
11899 return(x);
11900 if (clskconnx(1) < 0) { /* Close current Kermit connection */
11901 if ( ssh_tmpstr ) {
11902 memset(ssh_tmpstr,0,strlen(ssh_tmpstr));
11903 makestr(&ssh_tmpstr,NULL);
11904 }
11905 return(success = 0);
11906 }
11907 makestr(&ssh_hst,line); /* Stash everything */
11908 if (ssh_tmpuid) {
11909 if (!sl_uid_saved) {
11910 ckstrncpy(sl_uidbuf,uidbuf,UIDBUFLEN);
11911 sl_uid_saved = 1;
11912 }
11913 ckstrncpy(uidbuf,ssh_tmpuid,UIDBUFLEN);
11914 makestr(&ssh_tmpuid,NULL);
11915 }
11916 if (ssh_tmpport) {
11917 makestr(&ssh_prt,ssh_tmpport);
11918 makestr(&ssh_tmpport,NULL);
11919 } else
11920 makestr(&ssh_prt,NULL);
11921
11922 /* Set the Subsystem to Kermit */
11923 ssh_cas = 1;
11924 makestr(&ssh_cmd,"sftp");
11925
11926 if (tmpver > -1) {
11927 #ifndef SSHTEST
11928 if (!sl_ssh_ver_saved) {
11929 sl_ssh_ver = ssh_ver;
11930 sl_ssh_ver_saved = 1;
11931 }
11932 #endif /* SSHTEST */
11933 ssh_ver = tmpver;
11934 }
11935 /* Disable X11 Forwarding */
11936 #ifndef SSHTEST
11937 if (!sl_ssh_xfw_saved) {
11938 sl_ssh_xfw = ssh_xfw;
11939 sl_ssh_xfw_saved = 1;
11940 }
11941 #endif /* SSHTEST */
11942 ssh_xfw = 0;
11943
11944 if (ssh_tmpstr) {
11945 if (ssh_tmpstr[0]) {
11946 ckstrncpy(pwbuf,ssh_tmpstr,PWBUFL+1);
11947 pwflg = 1;
11948 pwcrypt = 0;
11949 } else
11950 pwflg = 0;
11951 makestr(&ssh_tmpstr,NULL);
11952 }
11953 nettype = NET_SSH;
11954 if (mdmsav < 0)
11955 mdmsav = mdmtyp;
11956 mdmtyp = -nettype;
11957 x = 1;
11958
11959 #ifndef NOSPL
11960 makestr(&g_pswd,pwbuf); /* Save global pwbuf */
11961 g_pflg = pwflg; /* and flag */
11962 g_pcpt = pwcrypt;
11963 #endif /* NOSPL */
11964
11965 /* Line parameter to ttopen() is ignored */
11966 k = ttopen(line,&x,mdmtyp, 0);
11967 if (k < 0) {
11968 printf("?Unable to connect to %s\n",ssh_hst);
11969 mdmtyp = mdmsav;
11970 slrestor();
11971 return(success = 0);
11972 }
11973 duplex = 0; /* Remote echo */
11974 ckstrncpy(ttname,line,TTNAMLEN); /* Record the command */
11975 debug(F110,"ssh ttname",ttname,0);
11976 makestr(&slmsg,NULL); /* No SET LINE error message */
11977 cxtype = CXT_SSH;
11978 #ifndef NODIAL
11979 dialsta = DIA_UNK;
11980 #endif /* NODIAL */
11981 success = 1; /* SET LINE succeeded */
11982 network = 1; /* Network connection (not serial) */
11983 local = 1; /* Local mode (not remote) */
11984 if ((reliable != SET_OFF || !setreliable))
11985 reliable = SET_ON; /* Transport is reliable end to end */
11986 #ifdef OS2
11987 DialerSend(OPT_KERMIT_CONNECT, 0);
11988 #endif /* OS2 */
11989 setflow(); /* Set appropriate flow control */
11990
11991 haveline = 1;
11992 #ifdef CKLOGDIAL
11993 #ifdef NETCONN
11994 dolognet();
11995 #endif /* NETCONN */
11996 #endif /* CKLOGDIAL */
11997
11998 #ifndef NOSPL
11999 if (local) {
12000 if (nmac) { /* Any macros defined? */
12001 int k; /* Yes */
12002 k = mlook(mactab,"on_open",nmac); /* Look this up */
12003 if (k >= 0) { /* If found, */
12004 if (dodo(k,ssh_hst,0) > -1) /* set it up, */
12005 parser(1); /* and execute it */
12006 }
12007 }
12008 }
12009 #endif /* NOSPL */
12010 #ifdef LOCUS
12011 if (autolocus)
12012 setlocus(1,1);
12013 #endif /* LOCUS */
12014
12015 /* Command was confirmed so we can pre-pop command level. */
12016 /* This is so CONNECT module won't think we're executing a */
12017 /* script if CONNECT was the final command in the script. */
12018 if (cmdlvl > 0)
12019 prepop();
12020
12021 success = sftp_do_init();
12022 return(success = 1);
12023
12024 case SFTP_CD:
12025 case SFTP_CHGRP:
12026 case SFTP_CHMOD:
12027 case SFTP_CHOWN:
12028 case SFTP_RM:
12029 case SFTP_DIR:
12030 case SFTP_GET:
12031 case SFTP_MKDIR:
12032 case SFTP_PUT:
12033 case SFTP_PWD:
12034 case SFTP_REN:
12035 case SFTP_RMDIR:
12036 case SFTP_LINK:
12037 case SFTP_VER:
12038 if ((y = cmtxt("command parameters","",&s,xxstring)) < 0)
12039 return(y);
12040 if (ssh_tchk() < 0 || !ssh_cas || strcmp(ssh_cmd,"sftp")) {
12041 printf("?Not connected to SFTP Service\n");
12042 return(success = 0);
12043 }
12044 success = sftp_do_cmd(cmresult.nresult,s);
12045 return(success);
12046 default:
12047 return(-2);
12048 }
12049 }
12050 #endif /* SFTP_BUILTIN */
12051
12052 if (cx == XXRLOG) { /* RLOGIN */
12053 #ifdef RLOGCODE
12054 int x,z;
12055 #ifdef OS2
12056 if (!tcp_avail) {
12057 printf("?Sorry, either TCP/IP is not available on this system or\n\
12058 necessary DLLs did not load. Use SHOW NETWORK to check network status.\n"
12059 );
12060 success = 0;
12061 return(-9);
12062 } else {
12063 #endif /* OS2 */
12064 x = nettype; /* Save net type in case of failure */
12065 z = ttnproto; /* Save protocol in case of failure */
12066 nettype = NET_TCPB;
12067 ttnproto = NP_RLOGIN;
12068 if ((y = setlin(XYHOST,0,1)) <= 0) {
12069 nettype = x; /* Failed, restore net type. */
12070 ttnproto = z; /* and protocol */
12071 success = 0;
12072 }
12073 didsetlin++;
12074 #ifdef OS2
12075 }
12076 #endif /* OS2 */
12077 return(y);
12078 #else
12079 printf("?Sorry, RLOGIN is not configured in this copy of C-Kermit.\n");
12080 return(-9);
12081 #endif /* RLOGCODE */
12082 }
12083 #endif /* NETCONN */
12084 #endif /* NOLOCAL */
12085
12086 #ifndef NOXMIT
12087 if (cx == XXTRA) { /* TRANSMIT */
12088 extern int xfrxla;
12089 int i, n, xpipe = 0, xbinary = 0, xxlate = 1, xxnowait = 0, getval;
12090 int xxecho = 0;
12091 int scan = 1;
12092 char c;
12093 struct FDB sf, sw, tx; /* FDBs for parse functions */
12094 #ifndef NOCSETS
12095 extern int tcs_transp; /* Term charset is transparent */
12096 #else
12097 int tcs_transp = 1;
12098 #endif /* NOCSETS */
12099
12100 #ifdef COMMENT
12101 xbinary = binary; /* Default text/binary mode */
12102 #else
12103 xbinary = 0; /* Default is text */
12104 #endif /* COMMENT */
12105 xxecho = xmitx;
12106
12107 cmfdbi(&sw, /* First FDB - command switches */
12108 _CMKEY, /* fcode */
12109 "Filename, or switch", /* hlpmsg */
12110 "", /* default */
12111 "", /* addtl string data */
12112 nxmitsw, /* addtl numeric data 1: tbl size */
12113 4, /* addtl numeric data 2: 4 = cmswi */
12114 xxstring, /* Processing function */
12115 xmitsw, /* Keyword table */
12116 &sf /* Pointer to next FDB */
12117 );
12118 cmfdbi(&sf, /* 2nd FDB - file to send */
12119 _CMIFI, /* fcode */
12120 "File to transmit", /* hlpmsg */
12121 "", /* default */
12122 "", /* addtl string data */
12123 0, /* addtl numeric data 1 */
12124 0, /* addtl numeric data 2 */
12125 xxstring,
12126 NULL,
12127 #ifdef PIPESEND
12128 &tx
12129 #else
12130 NULL
12131 #endif /* PIPESEND */
12132 );
12133 #ifdef PIPESEND
12134 cmfdbi(&tx,
12135 _CMTXT, /* fcode */
12136 "Command", /* hlpmsg */
12137 "", /* default */
12138 "", /* addtl string data */
12139 0, /* addtl numeric data 1 */
12140 0, /* addtl numeric data 2 */
12141 xxstring,
12142 NULL,
12143 NULL
12144 );
12145 #endif /* PIPESEND */
12146
12147 while (1) {
12148 x = cmfdb(&sw);
12149 if (x < 0)
12150 return(x);
12151 if (cmresult.fcode != _CMKEY)
12152 break;
12153 c = cmgbrk(); /* Have switch, get break character */
12154 if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
12155 printf("?This switch does not take an argument\n");
12156 return(-9);
12157 }
12158 if (!getval && (cmgkwflgs() & CM_ARG)) {
12159 printf("?This switch requires an argument\n");
12160 return(-9);
12161 }
12162 n = cmresult.nresult; /* Numeric result = switch ID */
12163 switch (n) { /* Process the switch */
12164 #ifdef PIPESEND
12165 case XMI_CMD: /* Transmit from a command */
12166 if (nopush) {
12167 printf("?Sorry, system command access is disabled\n");
12168 return(-9);
12169 }
12170 sw.hlpmsg = "Command, or switch"; /* Change help message */
12171 xpipe = 1; /* (No way to undo this one) */
12172 break;
12173 #endif /* PIPESEND */
12174
12175 case XMI_BIN: /* Binary */
12176 xbinary = 1;
12177 xxlate = 0; /* Don't translate charsets */
12178 scan = 0;
12179 break;
12180
12181 case XMI_TXT: /* Text */
12182 xbinary = 0;
12183 xxlate = !tcs_transp; /* Translate if TERM CHAR not TRANSP */
12184 scan = 0;
12185 break;
12186
12187 case XMI_TRA: /* Transparent text */
12188 xbinary = 0;
12189 xxlate = 0; /* But don't translate charsets */
12190 scan = 0;
12191 break;
12192
12193 #ifdef COMMENT
12194 case XMI_VRB: /* /VERBOSE */
12195 case XMI_QUI: /* /QUIET */
12196 break; /* (not implemented yet) */
12197 #endif /* COMMENT */
12198
12199 case XMI_NOW: /* /NOWAIT */
12200 xxnowait = 1;
12201 break;
12202
12203 case XMI_NOE: /* /NOWAIT */
12204 xxecho = 0;
12205 break;
12206
12207 default:
12208 return(-2);
12209 }
12210
12211 }
12212 if (cmresult.fcode != _CMIFI && cmresult.fcode != _CMTXT)
12213 return(-2);
12214 ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Filename */
12215 if (zfnqfp(line,TMPBUFSIZ,tmpbuf))
12216 ckstrncpy(line,tmpbuf,LINBUFSIZ);
12217 s = line;
12218 if ((y = cmcfm()) < 0) /* Confirm */
12219 return(y);
12220 #ifdef CK_APC
12221 if ((apcactive == APC_LOCAL) ||
12222 ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
12223 return(success = 0);
12224 #endif /* CK_APC */
12225 if (cmresult.nresult != 0) {
12226 printf("?Only a single file may be transmitted\n");
12227 return(-9);
12228 }
12229 #ifdef PIPESEND
12230 if (xpipe) {
12231 s = brstrip(s);
12232 if (!*s) {
12233 printf("?Sorry, a command to send from is required\n");
12234 return(-9);
12235 }
12236 pipesend = 1;
12237 }
12238 #endif /* PIPESEND */
12239
12240 if (scan && (filepeek
12241 #ifndef NOXFER
12242 || patterns
12243 #endif /* NOXFER */
12244 )) { /* If user didn't specify type */
12245 int k, x; /* scan the file to see */
12246 x = -1;
12247 k = scanfile(s,&x,nscanfile);
12248 if (k > 0) xbinary = (k == FT_BIN) ? XYFT_B : XYFT_T;
12249 }
12250 if (!xfrxla) xxlate = 0;
12251 success = transmit(s,
12252 (char) (xxnowait ? '\0' : (char)xmitp),
12253 xxlate,
12254 xbinary,
12255 xxecho
12256 );
12257 return(success);
12258 }
12259 #endif /* NOXMIT */
12260
12261 #ifndef NOFRILLS
12262 if (cx == XXTYP || cx == XXCAT || cx == XXMORE ||
12263 cx == XXHEAD || cx == XXTAIL) {
12264 int paging = 0, havename = 0, head = 0, width = 0;
12265 int height = 0, count = 0;
12266 char pfxbuf[64], * prefix = NULL;
12267 char outfile[CKMAXPATH+1];
12268 struct FDB sf, sw;
12269 char * pat = NULL;
12270 int incs = 0, outcs = 0, cset = -1, number = 0;
12271 #ifdef UNICODE
12272 char * tocs = "";
12273 extern int fileorder;
12274 #ifdef OS2
12275 #ifdef NT
12276 char guibuf[128], * gui_title = NULL;
12277 int gui = 0;
12278 #endif /* NT */
12279 #ifndef NOCSETS
12280 extern int tcsr, tcsl;
12281 #endif /* NOCSETS */
12282 #endif /* OS2 */
12283 #endif /* UNICODE */
12284
12285 outfile[0] = NUL;
12286
12287 if (cx == XXMORE)
12288 paging = 1;
12289 else if (cx == XXCAT)
12290 paging = 0;
12291 else
12292 paging = (typ_page < 0) ? xaskmore : typ_page;
12293 if (paging < 0)
12294 paging = saveask;
12295
12296 if (cx == XXHEAD) {
12297 head = 10;
12298 cx = XXTYP;
12299 } else if (cx == XXTAIL) {
12300 head = -10;
12301 cx = XXTYP;
12302 }
12303
12304 #ifdef IKSD
12305 if (inserver && !ENABLED(en_typ)) {
12306 printf("?Sorry, TYPE command disabled\n");
12307 return(-9);
12308 }
12309 #endif /* IKSD */
12310
12311 cmfdbi(&sw, /* 2nd FDB - optional /PAGE switch */
12312 _CMKEY, /* fcode */
12313 "Filename or switch", /* hlpmsg */
12314 "", /* default */
12315 "", /* addtl string data */
12316 ntypetab, /* addtl numeric data 1: tbl size */
12317 4, /* addtl numeric data 2: 4 = cmswi */
12318 xxstring, /* Processing function */
12319 typetab, /* Keyword table */
12320 &sf /* Pointer to next FDB */
12321 );
12322 cmfdbi(&sf, /* 1st FDB - file to type */
12323 _CMIFI, /* fcode */
12324 "", /* hlpmsg */
12325 "", /* default */
12326 "", /* addtl string data */
12327 0, /* addtl numeric data 1 */
12328 0, /* addtl numeric data 2 */
12329 xxstring,
12330 NULL,
12331 NULL
12332 );
12333
12334 while (!havename) {
12335 x = cmfdb(&sw); /* Parse something */
12336 debug(F101,"type cmfdb","",x);
12337 debug(F101,"type cmresult.fcode","",cmresult.fcode);
12338 debug(F101,"type cmresult.nresult","",cmresult.nresult);
12339 if (x < 0) { /* Error */
12340 if (x == -3) {
12341 x = -9;
12342 printf("?Filename required\n");
12343 }
12344 return(x);
12345 } else if (cmresult.fcode == _CMKEY) {
12346 char c; int getval;
12347 c = cmgbrk();
12348 getval = (c == ':' || c == '=');
12349 if (getval && !(cmgkwflgs() & CM_ARG)) {
12350 printf("?This switch does not take an argument\n");
12351 return(-9);
12352 }
12353 #ifdef COMMENT
12354 if (!getval && (cmgkwflgs() & CM_ARG)) {
12355 printf("?This switch requires an argument\n");
12356 /* Not if it has a default! */
12357 return(-9);
12358 }
12359 #endif /* COMMENT */
12360 switch (cmresult.nresult) {
12361 #ifdef CK_TTGWSIZ
12362 case TYP_PAG:
12363 paging = 1;
12364 break;
12365
12366 case TYP_NOP:
12367 paging = 0;
12368 break;
12369 #endif /* CK_TTGWSIZ */
12370
12371 case TYP_COU:
12372 paging = 0;
12373 count = 1;
12374 break;
12375
12376 case TYP_HEA:
12377 case TYP_TAI:
12378 y = 10;
12379 if (getval)
12380 if ((x = cmnum("Number of lines",
12381 "10",10,&y,xxstring)) < 0)
12382 return(x);
12383 head = (cmresult.nresult == TYP_TAI) ? -y : y;
12384 break;
12385
12386 case TYP_WID:
12387 y = typ_wid > -1 ? typ_wid : cmd_cols;
12388 if (getval)
12389 if ((x = cmnum("Column at which to truncate",
12390 ckitoa(y),10,&y,xxstring)) < 0)
12391 return(x);
12392 width = y;
12393 break;
12394
12395 #ifdef KUI
12396 case TYP_HIG:
12397 if (getval)
12398 if ((x = cmnum("Height of GUI dialog",
12399 ckitoa(y),10,&y,xxstring)) < 0)
12400 return(x);
12401 height = y;
12402 break;
12403 #endif /* KUI */
12404
12405 case TYP_PAT:
12406 if (!getval && (cmgkwflgs() & CM_ARG)) {
12407 printf("?This switch requires an argument\n");
12408 return(-9);
12409 }
12410 if ((x = cmfld("pattern","",&s,xxstring)) < 0)
12411 return(x);
12412 ckstrncpy(tmpbuf,s,TMPBUFSIZ);
12413 pat = tmpbuf;
12414 break;
12415
12416 case TYP_PFX:
12417 if (!getval && (cmgkwflgs() & CM_ARG)) {
12418 printf("?This switch requires an argument\n");
12419 return(-9);
12420 }
12421 if ((x = cmfld("prefix for each line","",&s,xxstring)) < 0)
12422 return(x);
12423 if ((int)strlen(s) > 63) {
12424 printf("?Too long - 63 max\n");
12425 return(-9);
12426 }
12427 ckstrncpy(pfxbuf,s,64);
12428 prefix = brstrip(pfxbuf);
12429 number = 0;
12430 break;
12431
12432 #ifdef KUI
12433 case TYP_GUI:
12434 if (!getval && (cmgkwflgs() & CM_ARG)) {
12435 printf("?This switch requires an argument\n");
12436 return(-9);
12437 }
12438 if ((x = cmfld("Dialog box title","",&s,xxstring)) < 0) {
12439 if (x != -3)
12440 return(x);
12441 } else {
12442 if ((int)strlen(s) > 127) {
12443 printf("?Too long - 127 max\n");
12444 return(-9);
12445 }
12446 ckstrncpy(guibuf,s,128);
12447 gui_title = brstrip(guibuf);
12448 }
12449 gui = 1;
12450 break;
12451 #endif /* KUI */
12452
12453 case TYP_NUM: /* /NUMBER */
12454 number = 1;
12455 prefix = NULL;
12456 break;
12457
12458 #ifdef UNICODE
12459 case TYP_XPA: /* /TRANSPARENT */
12460 incs = 0;
12461 cset = 0;
12462 outcs = -1;
12463 break;
12464
12465 case TYP_XIN: /* /CHARACTER-SET: */
12466 if (!getval && (cmgkwflgs() & CM_ARG)) {
12467 printf("?This switch requires an argument\n");
12468 return(-9);
12469 }
12470 if ((incs = cmkey(fcstab,nfilc,
12471 "character-set name","",xxstring)) < 0) {
12472 if (incs == -3) /* Note: No default */
12473 incs = -2;
12474 return(incs);
12475 }
12476 cset = incs;
12477 break;
12478
12479 case TYP_XUT: /* /TRANSLATE-TO: */
12480 if (!getval && (cmgkwflgs() & CM_ARG)) {
12481 printf("?This switch requires an argument\n");
12482 return(-9);
12483 }
12484 #ifdef OS2
12485 if (!inserver && !k95stdout) {
12486 tocs = "ucs2";
12487 } else {
12488 #ifdef CKOUNI
12489 tocs = rlookup(txrtab,ntxrtab,tcsl);
12490 #else /* CKOUNI */
12491 extern struct keytab ttcstab[];
12492 extern int ntxrtab;
12493 tocs = rlookup(ttcstab,ntermc,tocs);
12494 if (!tocs)
12495 tocs = getdcset();
12496 #endif /* CKOUNI */
12497 }
12498 #else /* OS2 */
12499 tocs = getdcset();
12500 #endif /* OS2 */
12501 if ((outcs = cmkey(fcstab,nfilc,
12502 "character-set",tocs,xxstring)) < 0)
12503 return(outcs);
12504 break;
12505 #endif /* UNICODE */
12506 case TYP_OUT:
12507 if ((x = cmofi("File for result lines","",
12508 &s,xxstring)) < 0)
12509 return(x);
12510 ckstrncpy(outfile,s,CKMAXPATH);
12511 break;
12512 }
12513 } else if (cmresult.fcode == _CMIFI)
12514 havename = 1;
12515 else
12516 return(-2);
12517 }
12518 if (havename) {
12519 ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
12520 y = cmresult.nresult;
12521 } else {
12522 if ((x = cmifi("Filename","",&s,&y,xxstring)) < 0) {
12523 if (x == -3) {
12524 printf("?Name of an existing file required\n");
12525 return(-9);
12526 } else return(x);
12527 }
12528 ckstrncpy(line,s,LINBUFSIZ);
12529 }
12530 if (y != 0) {
12531 printf("?A single file please\n");
12532 return(-9);
12533 }
12534 #ifdef KUI
12535 if ( outfile[0] && gui ) {
12536 printf("?/GUI and /OUTPUT are incompatible\n");
12537 return(-9);
12538 }
12539 #endif /* KUI */
12540
12541 if ((y = cmcfm()) < 0) /* Confirm the command */
12542 return(y);
12543
12544 #ifdef UNICODE
12545 fileorder = -1;
12546 if (cset < 0 && filepeek) { /* If no charset switches given */
12547 int k, x = -1;
12548 k = scanfile(line,&x,nscanfile); /* Call file analyzer */
12549 debug(F111,"type scanfile",line,k);
12550 debug(F101,"type scanfile flag","",x);
12551 switch(k) {
12552 case FT_UTF8: /* which can detect UTF-8... */
12553 cset = 0;
12554 incs = FC_UTF8;
12555 break;
12556 case FT_UCS2: /* and UCS-2... */
12557 cset = 0;
12558 incs = FC_UCS2;
12559 fileorder = x; /* even if there is no BOM. */
12560 debug(F101,"type fileorder","",fileorder);
12561 break;
12562 }
12563 }
12564 #ifdef OS2
12565 if (cset < 0) { /* If input charset still not known */
12566 #ifdef CKOUNI
12567 tocs = rlookup(txrtab,ntxrtab,tcsl);
12568 #else /* CKOUNI */
12569 extern struct keytab ttcstab[];
12570 extern int ntxrtab;
12571 tocs = rlookup(ttcstab,ntermc,incs);
12572 if (!tocs)
12573 tocs = getdcset();
12574 #endif /* CKOUNI */
12575 incs = lookup(fcstab,tocs,nfilc,&x);
12576 }
12577 #endif /* OS2 */
12578
12579 if (outcs == 0 && incs != 0) { /* Supply default target charset */
12580 int x = 0; /* if switch not given. */
12581 tocs = getdcset();
12582 outcs = lookup(fcstab,tocs,nfilc,&x);
12583 }
12584 #else /* !UNICODE */
12585 if (cset < 0) incs = outcs = 0;
12586 #endif /* UNICODE */
12587
12588 if (outfile[0] && paging) /* This combination makes no sense */
12589 paging = 0; /* so turn off paging */
12590
12591 #ifdef KUI
12592 /* No paging when dialog is used */
12593 if ( gui && paging )
12594 paging = 0;
12595
12596 if ( !gui && height ) {
12597 printf("?The /HEIGHT switch is not supported without /GUI\n");
12598 return(-9);
12599 }
12600 #endif /* KUI */
12601
12602 if (count) paging = -1;
12603 debug(F111,"type",line,paging);
12604 #ifdef KUI
12605 if ( gui ) {
12606 s = (char *)1; /* ok, its an ugly hack */
12607 if (gui_text_popup_create(gui_title ?
12608 gui_title : line, height,width) < 0) {
12609 printf("?/GUI not supported on this system\n");
12610 gui = 0;
12611 return(-9);
12612 }
12613 width = 0;
12614 } else
12615 #endif /* KUI */
12616 s = outfile;
12617 success =
12618 dotype(line,paging,0,head,pat,width,prefix,incs,outcs,s,number);
12619 return(success);
12620 }
12621 #endif /* NOFRILLS */
12622
12623 #ifndef NOCSETS
12624 if (cx == XXXLA) { /* TRANSLATE file's charset */
12625 _PROTOTYP (int doxlate, ( void ) );
12626 return(doxlate());
12627 }
12628 #endif /* NOCSETS */
12629
12630 if (cx == XXVER) { /* VERSION */
12631 int n = 0;
12632 extern char * ck_patch, * ck_s_test;
12633 #ifdef COMMENT
12634 extern int hmtopline;
12635 #endif /* COMMENT */
12636 if ((y = cmcfm()) < 0)
12637 return(y);
12638
12639 #ifdef CK_64BIT
12640 printf("\n%s, for%s (64-bit)\n Numeric: %ld",versio,ckxsys,vernum);
12641 #else
12642 printf("\n%s, for%s\n Numeric: %ld",versio,ckxsys,vernum);
12643 #endif /* CK_64BIT */
12644 printf("\n\n");
12645 printf("Authors:\n");
12646 printf(" Frank da Cruz, the Kermit Project %s\n",
12647 "<fdc@kermitproject.org>"
12648 );
12649 printf(" Jeffrey Eric Altman, Secure Endpoints, Inc. %s\n",
12650 "<jaltman@secure-endpoints.com>"
12651 );
12652 printf(" Contributions from many others.\n");
12653 n = 7;
12654 if (*ck_s_test) {
12655 printf("\nTHIS IS A TEST VERSION, NOT FOR PRODUCTION USE.\n");
12656 n += 2;
12657 }
12658 if (*ck_patch) {
12659 printf(" Patches: %s\n", ck_patch);
12660 n++;
12661 }
12662 printf(" Type COPYRIGHT for copyright and license.\n\n");
12663 #ifdef OS2
12664 #ifdef COMMENT
12665 shoreg();
12666 #endif /* COMMENT */
12667 #else
12668 #ifdef COMMENT
12669 hmtopline = n+1;
12670 hmsga(copyright);
12671 hmtopline = 0;
12672 #endif /* COMMENT */
12673 #endif /* OS2 */
12674 return(success = 1);
12675 }
12676
12677 if (cx == XXCPR) { /* COPYRIGHT or LICENSE */
12678 _PROTOTYP( int hmsgaa, (char * [], char *) );
12679 extern char * ck_cryear;
12680 if ((y = cmcfm()) < 0)
12681 return(y);
12682 hmsgaa(copyright,ck_cryear);
12683 return(success = 1);
12684 }
12685
12686 #ifndef MAC /* Only for multiuser systems */
12687 #ifndef OS2
12688 #ifndef NOFRILLS
12689 if (cx == XXWHO) { /* WHO */
12690 char *wc;
12691 #ifdef IKSD
12692 if (inserver && !ENABLED(en_who)) {
12693 printf("?Sorry, WHO command disabled\n");
12694 return(-9);
12695 }
12696 #endif /* IKSD */
12697 #ifdef datageneral
12698 if ((z = cmcfm()) < 0) return(z);
12699 if (nopush) {
12700 printf("?Sorry, who not allowed\n");
12701 return(success = 0);
12702 }
12703 xsystem(WHOCMD);
12704 #else
12705 if ((y = cmtxt("user name","",&s,xxstring)) < 0) return(y);
12706 if (nopush) {
12707 printf("?Sorry, WHO command disabled\n");
12708 return(success = 0);
12709 }
12710 if (!(wc = getenv("CK_WHO"))) wc = WHOCMD;
12711 if (wc)
12712 if ((int) strlen(wc) > 0) {
12713 ckmakmsg(line,LINBUFSIZ,wc," ",s,NULL);
12714 xsystem(line);
12715 }
12716 #endif /* datageneral */
12717 return(success = 1);
12718 }
12719 #endif /* NOFRILLS */
12720 #endif /* OS2 */
12721 #endif /* MAC */
12722
12723 #ifndef NOFRILLS
12724 if (cx == XXWRI || cx == XXWRL || cx == XXWRBL) { /* WRITE */
12725 int x,y; /* On stack in case of \fexec() */
12726 if ((x = cmkey(writab,nwri,"to file or log","",xxstring)) < 0) {
12727 if (x == -3) printf("?Write to what?\n");
12728 return(x);
12729 }
12730 if ((y = cmtxt("text","",&s,xxstring)) < 0) return(y);
12731 s = brstrip(s);
12732 switch (x) {
12733 case LOGD: y = ZDFILE; break;
12734 case LOGP: y = ZPFILE; break;
12735 #ifndef NOLOCAL
12736 case LOGS: y = ZSFILE; break;
12737 #endif /* NOLOCAL */
12738 case LOGT: y = ZTFILE; break;
12739 #ifndef NOSPL
12740 case LOGW: y = ZWFILE; break;
12741 #endif /* NOSPL */
12742 case LOGX: /* SCREEN (stdout) */
12743 case LOGE: /* ERROR (stderr) */
12744 if (x == LOGE) {
12745 debug(F110,
12746 (cx == XXWRL) ? "WRITELN ERROR" : "WRITE ERROR", s,0);
12747 fprintf(stderr,"%s%s",s,(cx == XXWRL) ? "\n" : "");
12748 } else {
12749 debug(F110,
12750 (cx == XXWRL) ? "WRITELN SCREEN" : "WRITE SCREEN", s,0);
12751 printf("%s%s",s,(cx == XXWRL) ? "\n" : "");
12752 }
12753 return(success = 1);
12754 default: return(-2);
12755 }
12756 if (chkfn(y) > 0) {
12757 x = (cx == XXWRI) ? zsout(y,s) : zsoutl(y,s);
12758 debug(F111,"WRITE",
12759 (cx == XXWRI) ? "zsout" : "zsoutl",
12760 x);
12761 if (x < 0) printf("?Write error\n");
12762 } else {
12763 x = -1;
12764 printf("?File or log not open\n");
12765 }
12766 debug(F101,"WRITE x","",x);
12767 return(success = (x == 0) ? 1 : 0);
12768 }
12769 #endif /* NOFRILLS */
12770
12771 #ifndef NOXFER
12772 if (cx == XXASC || cx == XXBIN) {
12773 if ((x = cmcfm()) < 0) return(x);
12774 #ifdef NEWFTP
12775 /*
12776 Make C-Kermit work like other ftp clients, where
12777 the ASCII (TEXT) and BINARY commands are global settings.
12778 */
12779 if (ftpisopen()) {
12780 doftpglobaltype((cx == XXASC) ? XYFT_T : XYFT_B);
12781 /* Fall thru--the command it should apply to both FTP and Kermit */
12782 /* return(success = 1); */
12783 }
12784 #endif /* NEWFTP */
12785
12786 xfermode = XMODE_M; /* Set manual Kermit transfer mode */
12787 binary = (cx == XXASC) ? XYFT_T : XYFT_B;
12788 return(success = 1);
12789 }
12790 #endif /* NOXFER */
12791
12792 if (cx == XXCLS) {
12793 if ((x = cmcfm()) < 0) return(x);
12794 y = ck_cls();
12795 return(success = (y > -1) ? 1 : 0);
12796 }
12797
12798 #ifdef CK_MKDIR
12799 if (cx == XXMKDIR || cx == XXLMKD) {
12800 char *p;
12801 #ifdef LOCUS
12802 if (!locus && cx != XXLMKD) {
12803 #ifdef NOXFER
12804 return(-2);
12805 #else
12806 return(dormt(XZMKD));
12807 #endif /* NOXFER */
12808 }
12809 #endif /* LOCUS */
12810 #ifdef IKSD
12811 if (inserver && !ENABLED(en_mkd)) {
12812 printf("?Sorry, directory creation is disabled\n");
12813 return(-9);
12814 }
12815 #endif /* IKSD */
12816 if ((x = cmfld("Name for new directory","",&s,xxstring)) < 0) {
12817 if (x != -3) {
12818 return(x);
12819 } else {
12820 printf("?Directory name required\n");
12821 return(-9);
12822 }
12823 }
12824 ckstrncpy(line,s,LINBUFSIZ);
12825 s = line;
12826 if ((x = cmcfm()) < 0) return(x);
12827 s = brstrip(s);
12828 bgchk(); /* Set msgflg */
12829 x = ckmkdir(0,s,&p,msgflg,0);
12830 #ifdef COMMENT
12831 if (msgflg && x == 0)
12832 printf("?Directory already exists\n");
12833 #endif /* COMMENT */
12834 return(success = (x < 0) ? 0 : 1);
12835 }
12836 if (cx == XXRMDIR || cx == XXLRMD) { /* RMDIR */
12837 char *p;
12838 #ifdef LOCUS
12839 if (!locus && cx != XXLRMD) {
12840 #ifdef NOXFER
12841 return(-2);
12842 #else
12843 return(dormt(XZRMD));
12844 #endif /* NOXFER */
12845 }
12846 #endif /* LOCUS */
12847 #ifdef IKSD
12848 if (inserver && !ENABLED(en_rmd)) {
12849 printf("?Sorry, directory removal is disabled\n");
12850 return(-9);
12851 }
12852 #endif /* IKSD */
12853 if ((x = cmdir("Name of directory to be removed","",&s,xxstring)) < 0)
12854 return(x);
12855 ckstrncpy(line,s,LINBUFSIZ);
12856 s = line;
12857 if ((x = cmcfm()) < 0) return(x);
12858 s = brstrip(s);
12859 x = ckmkdir(1,s,&p,msgflg,0);
12860 return(success = (x < 0) ? 0 : 1);
12861 }
12862 #endif /* CK_MKDIR */
12863
12864 #ifdef TNCODE
12865 if (cx == XXTELOP)
12866 return(dotelopt());
12867 #endif /* TNCODE */
12868
12869 #ifndef NOPUSH
12870 if (cx == XXNPSH) {
12871 if ((z = cmcfm()) < 0) return(z);
12872 nopush = 1;
12873 #ifndef NOSERVER
12874 en_hos = 0;
12875 #endif /* NOSERVER */
12876 #ifdef PIPESEND
12877 usepipes = 0;
12878 #endif /* PIPESEND */
12879 return(success = 1);
12880 }
12881 #endif /* NOPUSH */
12882
12883 #ifdef OS2
12884 if (cx == XXNSCR) {
12885 if ((z = cmcfm()) < 0) return(z);
12886 tt_scroll = 0;
12887 return(success = 1);
12888 }
12889 #endif /* OS2 */
12890
12891 #ifndef NOSPL
12892 if (cx == XXLOCAL) /* LOCAL variable declarations */
12893 return(success = dolocal());
12894 #endif /* NOSPL */
12895
12896 if (cx == XXKERMI) { /* The KERMIT command */
12897 char * list[65];
12898 extern char **xargv;
12899 extern int xargc;
12900 int i;
12901 if ((y = cmtxt("kermit command-line arguments, -h for help",
12902 "",&s,xxstring)) < 0)
12903 return(y);
12904 ckstrncpy(line,"kermit ",LINBUFSIZ);
12905 ckstrncat(line,s,LINBUFSIZ-8);
12906 xwords(line,64,list,0);
12907 for (i = 1; i < 64; i++) {
12908 if (!list[i])
12909 break;
12910 }
12911 i--;
12912 xargc = i;
12913 xargv = list;
12914 xargv++;
12915 sstate = cmdlin();
12916 if (sstate) {
12917 extern int justone;
12918 debug(F000,"KERMIT sstate","",sstate);
12919 justone = 1; /* Force return to command mode */
12920 proto(); /* after protocol */
12921 return(success);
12922 } else {
12923 debug(F101,"KERMIT sstate","",sstate);
12924 return(success = 1); /* Not exactly right, but... */
12925 }
12926 }
12927 if (cx == XXDATE) { /* DATE command */
12928 extern char cmdatebuf[], * cmdatemsg;
12929
12930 #ifndef COMMENT
12931 char * dp;
12932 if ((y = cmtxt("date and/or time, or carriage return for current",
12933 "",&s,xxstring)) < 0)
12934 return(y);
12935 s = brstrip(s);
12936 dp = cmcvtdate(s,1);
12937 if (!dp) {
12938 printf("?%s\n",cmdatemsg ? cmdatemsg : "Date conversion error");
12939 success = 0;
12940 } else {
12941 printf("%s\n",dp);
12942 success = 1;
12943 }
12944 #else
12945 /* This works fine but messes up my "dates" torture-test script */
12946
12947 if ((x = cmdate("Date and/or time, or carriage return for current",
12948 "",&s,0,xxstring)) < 0) {
12949 return(x);
12950 } else {
12951 printf("%s\n",cmdatebuf);
12952 success = 1;
12953 }
12954 #endif /* COMMENT */
12955 return(success);
12956 }
12957 #ifndef NOPUSH
12958 #ifndef NOFRILLS
12959 if (cx == XXEDIT)
12960 return(doedit());
12961 #endif /* NOFRILLS */
12962 #endif /* NOPUSH */
12963
12964 #ifdef BROWSER /* Defined only ifndef NOPUSH */
12965 if (cx == XXBROWS)
12966 return(dobrowse());
12967 #endif /* BROWSER */
12968
12969 #ifdef CK_TAPI
12970 if (cx == XXTAPI) { /* Microsoft TAPI */
12971 return (success = dotapi());
12972 }
12973 #endif /* CK_TAPI */
12974
12975 #ifndef NOXFER
12976 if (cx == XXWHERE) {
12977 extern char * rfspec, * sfspec, * srfspec, * rrfspec;
12978 if ((x = cmcfm()) < 0) return(x);
12979 printf("\nFile most recently...\n\n");
12980 printf(" Sent: %s\n", sfspec ? sfspec : "(none)");
12981 if (sfspec && srfspec) {
12982 printf(" Stored as: %s\n", srfspec);
12983 printf("\n");
12984 }
12985 printf(" Received: %s\n", rrfspec ? rrfspec : "(none)");
12986 if (rfspec && rrfspec)
12987 printf(" Stored as: %s\n", rfspec);
12988 printf(
12989 "\nIf the full path is not shown, then the file is probably in your current\n"
12990 );
12991 printf(
12992 "directory or your download directory (if any - SHOW FILE to find out).\n\n"
12993 );
12994 return(success = 1);
12995 }
12996 #endif /* NOXFER */
12997
12998 #ifdef CK_RECALL
12999 if (cx == XXREDO)
13000 return(doredo());
13001 #endif /* CK_RECALL */
13002
13003 #ifdef CKROOT
13004 if (cx == XXCHRT) /* Change Kermit's root directory */
13005 return(dochroot());
13006 #endif /* CKROOT */
13007
13008 #ifdef CK_KERBEROS
13009 if (cx == XXAUTH) { /* KERBEROS */
13010 x = cp_auth(); /* Parse it */
13011 #ifdef IKSD
13012 if (inserver) {
13013 printf("?Command disabled in IKSD.\r\n");
13014 return(success = 0);
13015 }
13016 #endif /* IKSD */
13017 if (x < 0) /* Pass parse errors back */
13018 return(x);
13019 return(success = doauth(cx));
13020 }
13021 #endif /* CK_KERBEROS */
13022
13023 #ifndef NOLOCAL
13024 if (cx == XXTERM) {
13025 return(settrmtyp());
13026 }
13027 #endif /* NOLOCAL */
13028
13029 if (cx == XXSTATUS) {
13030 if ((x = cmcfm()) < 0) return(x);
13031 printf( " %s\n", success ? "SUCCESS" : "FAILURE" );
13032 return(0); /* Don't change it */
13033 }
13034
13035 if (cx == XXFAIL) {
13036 if ((x = cmcfm()) < 0) return(x);
13037 return(success = 0);
13038 }
13039
13040 if (cx == XXSUCC) {
13041 if ((x = cmcfm()) < 0) return(x);
13042 return(success = 1);
13043 }
13044
13045 if (cx == XXNLCL) {
13046 extern int nolocal;
13047 if ((x = cmcfm()) < 0) return(x);
13048 nolocal = 1;
13049 return(success = 1);
13050 }
13051
13052 #ifndef NOXFER
13053 if (cx == XXRASG) /* Shortcuts for REMOTE commands */
13054 return(dormt(XZASG));
13055 if (cx == XXRCWD)
13056 return(dormt(XZCWD));
13057 if (cx == XXRCPY)
13058 return(dormt(XZCPY));
13059 if (cx == XXRDEL)
13060 return(dormt(XZDEL));
13061 if (cx == XXRDIR)
13062 return(dormt(XZDIR));
13063 if (cx == XXRXIT)
13064 return(dormt(XZXIT));
13065 if (cx == XXRHLP)
13066 return(dormt(XZHLP));
13067 if (cx == XXRHOS)
13068 return(dormt(XZHOS));
13069 if (cx == XXRKER)
13070 return(dormt(XZKER));
13071 if (cx == XXRPWD)
13072 return(dormt(XZPWD));
13073 if (cx == XXRQUE)
13074 return(dormt(XZQUE));
13075 if (cx == XXRREN)
13076 return(dormt(XZREN));
13077 if (cx == XXRMKD)
13078 return(dormt(XZMKD));
13079 if (cx == XXRMSG)
13080 return(dormt(XZMSG));
13081 if (cx == XXRRMD)
13082 return(dormt(XZRMD));
13083 if (cx == XXRSET)
13084 return(dormt(XZSET));
13085 if (cx == XXRSPA)
13086 return(dormt(XZSPA));
13087 if (cx == XXRTYP)
13088 return(dormt(XZTYP));
13089 if (cx == XXRWHO)
13090 return(dormt(XZWHO));
13091 if (cx == XXRCDUP)
13092 return(dormt(XZCDU));
13093 if (cx == XXRPRI)
13094 return(dormt(XZPRI));
13095 #endif /* NOXFER */
13096
13097 if (cx == XXRESET) { /* RESET */
13098 if ((x = cmcfm()) < 0)
13099 return(x);
13100 concb((char)escape); /* Make command echoing to normal */
13101 doclean(0); /* Close all files */
13102 return(success = 1);
13103 }
13104
13105 #ifndef NOXFER
13106 #ifndef NOCSETS
13107 if (cx == XXASSOC) /* ASSOCIATE */
13108 return(doassoc());
13109 #endif /* NOCSETS */
13110 #endif /* NOXFER */
13111
13112 #ifndef NOSPL
13113 if (cx == XXSHIFT) { /* SHIFT */
13114 if ((y = cmnum("Number of arguments to shift","1",10,&x,xxstring)) < 0)
13115 return(y);
13116 if ((z = cmcfm()) < 0)
13117 return(z);
13118 return(success = doshift(x));
13119 }
13120 #endif /* NOSPL */
13121
13122 #ifndef NOHELP
13123 if (cx == XXMAN)
13124 return(domanual());
13125 #endif /* NOHELP */
13126
13127 #ifndef NOSPL
13128 if (cx == XXSORT) /* SORT an array */
13129 return(dosort());
13130 #endif /* NOSPL */
13131
13132 if (cx == XXPURGE) {
13133 #ifdef IKSD
13134 if (inserver && (!ENABLED(en_del)
13135 #ifdef CK_LOGIN
13136 || isguest
13137 #endif /* CK_LOGIN */
13138 )) {
13139 printf("?Sorry, DELETE is disabled\n");
13140 return(-9);
13141 }
13142 #endif /* IKSD */
13143 #ifdef CK_APC
13144 if ((apcactive == APC_LOCAL) ||
13145 ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
13146 return(success = 0);
13147 #endif /* CK_APC */
13148 #ifdef CKPURGE
13149 return(dopurge());
13150 #else
13151 #ifdef VMS
13152 if ((x = cmtxt("optional switches followed by filespec",
13153 "",&s,xxstring)) < 0)
13154 return(x);
13155 if (nopush) {
13156 printf("?Sorry, DCL access is disabled\n");
13157 return(-9);
13158 }
13159 ckstrncpy(line,s,LINBUFSIZ);
13160 s = line;
13161 x = mlook(mactab,"purge",nmac);
13162 return(success = dodo(x,s,cmdstk[cmdlvl].ccflgs));
13163 #else
13164 return(-2);
13165 #endif /* VMS */
13166 #endif /* CKPURGE */
13167 }
13168
13169 #ifndef NOSPL
13170 if (cx == XXFAST) {
13171 if ((x = cmcfm()) < 0) return(x);
13172 x = mlook(mactab,"fast",nmac);
13173 return(success = dodo(x,NULL,cmdstk[cmdlvl].ccflgs));
13174 }
13175 if (cx == XXCAU) {
13176 if ((x = cmcfm()) < 0) return(x);
13177 x = mlook(mactab,"cautious",nmac);
13178 return(success = dodo(x,NULL,cmdstk[cmdlvl].ccflgs));
13179 }
13180 if (cx == XXROB) {
13181 if ((x = cmcfm()) < 0) return(x);
13182 x = mlook(mactab,"robust",nmac);
13183 return(success = dodo(x,NULL,cmdstk[cmdlvl].ccflgs));
13184 }
13185 #endif /* NOSPL */
13186
13187 if (cx == XXSCRN) { /* SCREEN */
13188 int row, col;
13189 if ((x = cmkey(scntab, nscntab,"screen action","", xxstring)) < 0)
13190 return(x);
13191 switch (x) { /* MOVE-TO (cursor position) */
13192 case SCN_MOV:
13193 if ((y = cmnum("Row (1-based)","",10,&z,xxstring)) < 0)
13194 return(y);
13195 row = z;
13196 y = cmnum("Column (1-based)","1",10,&z,xxstring);
13197 if (y < 0)
13198 return(y);
13199 col = z;
13200 if ((y = cmcfm()) < 0)
13201 return(y);
13202 if (row < 0 || col < 0) {
13203 printf("?Row and Column must be 1 or greater\n");
13204 return(-9);
13205 }
13206 if (cmd_rows > 0 && row > cmd_rows)
13207 row = cmd_rows;
13208 if (cmd_cols > 0 && col > cmd_cols)
13209 col = cmd_cols;
13210 y = ck_curpos(row,col);
13211 return(success = (y > -1) ? 1 : 0);
13212
13213 case SCN_CLR: /* CLEAR */
13214 if ((y = cmcfm()) < 0)
13215 return(y);
13216 debug(F100,"screen calling ck_cls()","",0);
13217 y = ck_cls();
13218 return(success = (y > -1) ? 1 : 0);
13219
13220 case SCN_CLE: /* CLEOL */
13221 if ((y = cmcfm()) < 0)
13222 return(y);
13223 y = ck_cleol();
13224 return(success = (y > -1) ? 1 : 0);
13225 }
13226 }
13227
13228 #ifndef NOHTTP
13229 #ifdef TCPSOCKET
13230 if (cx == XXHTTP)
13231 return(dohttp());
13232 #endif /* TCPSOCKET */
13233 #endif /* NOHTTP */
13234
13235 #ifndef NOSPL
13236 if (cx == XXARRAY) { /* ARRAY */
13237 #ifndef NOSHOW
13238 extern int showarray();
13239 #endif /* NOSHOW */
13240 if ((x = cmkey(arraytab, narraytab,"Array operation","",xxstring)) < 0)
13241 return(x);
13242 switch (x) {
13243 case ARR_DCL:
13244 return(dodcl(XXDCL));
13245 case ARR_SRT:
13246 return(dosort());
13247 #ifndef NOSHOW
13248 case ARR_SHO:
13249 return(showarray());
13250 #endif /* NOSHOW */
13251 case ARR_CPY:
13252 return(copyarray());
13253 case ARR_SET:
13254 case ARR_CLR:
13255 return(clrarray(x));
13256 case ARR_DST:
13257 return(unarray());
13258 case ARR_RSZ:
13259 return(rszarray());
13260 case ARR_EQU:
13261 return(linkarray());
13262
13263 default:
13264 printf("?Sorry, not implemented yet - \"%s\"\n",cmdbuf);
13265 return(-9);
13266 }
13267 }
13268 if (cx == XXTRACE) /* TRACE */
13269 return(dotrace());
13270 #endif /* NOSPL */
13271
13272 #ifdef CK_PERMS
13273 #ifdef UNIX
13274 if (cx == XXCHMOD)
13275 return(douchmod()); /* Do Unix chmod */
13276 #endif /* UNIX */
13277 #endif /* CK_PERMS */
13278
13279 if (cx == XXPROMP)
13280 return(doprompt());
13281
13282 if (cx == XXGREP)
13283 return(dogrep());
13284
13285 if (cx == XXDEBUG) { /* DEBUG */
13286 #ifndef DEBUG
13287 int dummy = 0;
13288 return(seton(&dummy));
13289 #else
13290 return(seton(&deblog));
13291 #endif /* DEBUG */
13292 }
13293 if (cx == XXMSG || cx == XXXMSG) { /* MESSAGE */
13294 extern int debmsg; /* Script debugging messages */
13295 if ((x = cmtxt("Message to print if SET DEBUG MESSAGE is ON or STDERR",
13296 "",&s,xxstring)) < 0)
13297 return(x);
13298 if (!s) /* Watch out for null result */
13299 s = ""; /* Make it an empty string */
13300 else /* Not null */
13301 s = brstrip(s); /* Strip braces and doublequotes */
13302 switch (debmsg) { /* Not debugging - don't print */
13303 case 0:
13304 break;
13305 case 1:
13306 printf("%s",s); /* Print to stdout */
13307 if (cx == XXMSG) printf("\n");
13308 break;
13309 case 2:
13310 fprintf(stderr,"%s",s); /* Ditto but print to stderr */
13311 if (cx == XXMSG) fprintf(stderr,"\n");
13312 break;
13313 }
13314 return(0); /* Return without affecting SUCCESS */
13315 }
13316
13317 #ifdef CKLEARN
13318 if (cx == XXLEARN) { /* LEARN */
13319 struct FDB of, sw, cm;
13320 int closing = 0, off = 0, on = 0, confirmed = 0;
13321 char c;
13322
13323 cmfdbi(&sw, /* 2nd FDB - optional /PAGE switch */
13324 _CMKEY, /* fcode */
13325 "Script file name, or switch", /* hlpmsg */
13326 "", /* default */
13327 "", /* addtl string data */
13328 3, /* addtl numeric data 1: tbl size */
13329 4, /* addtl numeric data 2: 4 = cmswi */
13330 xxstring, /* Processing function */
13331 learnswi, /* Keyword table */
13332 &of /* Pointer to next FDB */
13333 );
13334 cmfdbi(&of,_CMOFI,"","","",0,0,xxstring,NULL,&cm);
13335 cmfdbi(&cm,_CMCFM,"","","",0,0,NULL,NULL,NULL);
13336 line[0] = NUL;
13337
13338 while (!confirmed) {
13339 x = cmfdb(&sw); /* Parse something */
13340 if (x < 0)
13341 return(x);
13342 switch (cmresult.fcode) { /* What was it? */
13343 case _CMOFI: /* Output file name */
13344 ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
13345 break;
13346 case _CMKEY: /* Switch */
13347 c = cmgbrk();
13348 if ((c == ':' || c == '=') && !(cmgkwflgs() & CM_ARG)) {
13349 printf("?This switch does not take an argument\n");
13350 return(-9);
13351 }
13352 switch (cmresult.nresult) {
13353 case 2: /* /CLOSE */
13354 closing = 1; /* Fall thru on purpose */
13355 case 0: /* /OFF */
13356 off = 1;
13357 on = 0;
13358 break;
13359 case 1: /* /ON */
13360 on = 1;
13361 off = 0;
13362 break;
13363 }
13364 break;
13365 case _CMCFM: /* Confirmation */
13366 confirmed++;
13367 break;
13368 }
13369 }
13370 if (closing) {
13371 if (learnfp) {
13372 fclose(learnfp);
13373 learnfp = NULL;
13374 }
13375 makestr(&learnfile,NULL);
13376 }
13377 if (line[0]) {
13378 if (!on && !off)
13379 on = 1;
13380 if (learnfp) {
13381 fclose(learnfp);
13382 learnfp = NULL;
13383 }
13384 makestr(&learnfile,line);
13385 if (learnfile) {
13386 char * modes = "w";
13387 learnfp = fopen(learnfile,modes);
13388 if (!learnfp) {
13389 debug(F110,"LEARN file open error",learnfile,0);
13390 perror(learnfile);
13391 return(-9);
13392 } else {
13393 #ifdef ZFNQFP
13394 if (zfnqfp(learnfile,TMPBUFSIZ,tmpbuf))
13395 makestr(&learnfile,tmpbuf);
13396 #endif /* ZFNQFP */
13397 debug(F110,"LEARN file open ok",learnfile,0);
13398 if (!quiet) {
13399 printf("Recording to %s...\n\n",learnfile);
13400 printf(
13401 " WARNING: If you type your password during script recording, it will appear\n\
13402 in the file. Be sure to edit it or take other appropriate precautions.\n\n"
13403 );
13404 }
13405 fputs( "; Scriptfile: ",learnfp);
13406 fputs(learnfile,learnfp);
13407 fputs("\n; Directory: ",learnfp);
13408 fputs(zgtdir(),learnfp);
13409 fputs("\n; Recorded: ",learnfp);
13410 fputs(ckdate(),learnfp);
13411 fputs("\n",learnfp);
13412 }
13413 }
13414 }
13415 if (on) {
13416 learning = 1;
13417 } else if (off) {
13418 learning = 0;
13419 }
13420 debug(F101,"LEARN learning","",learning);
13421 return(success = 1);
13422 }
13423 #endif /* CKLEARN */
13424
13425 #ifdef NEWFTP
13426 if (cx == XXUSER || cx == XXACCT) {
13427 if (!ftpisopen()) {
13428 printf("?FTP connection is not open\n");
13429 return(-9);
13430 }
13431 return(success = (cx == XXUSER) ? doftpusr() : doftpacct());
13432 }
13433 if (cx == XXSITE || cx == XXPASV) {
13434 if (!ftpisopen()) {
13435 printf("?FTP connection is not open\n");
13436 return(-9);
13437 }
13438 return(success = (cx == XXSITE) ? doftpsite() : dosetftppsv());
13439 }
13440 #endif /* NEWFTP */
13441
13442 if (cx == XXORIE) { /* ORIENTATION */
13443 extern char * myname;
13444 int i, y, n = 0;
13445 char * s, *p, vbuf[32];
13446 char * vars[16]; char * legend[16];
13447
13448 if ((y = cmcfm()) < 0)
13449 return(y);
13450
13451 printf("\nProgram name:\n %s\n\n",myname);
13452 n += 4;
13453
13454 #ifdef NT
13455 vars[0] = "home"; legend[0] = "Your home directory";
13456 vars[1] = "directory"; legend[1] = "K95's current directory";
13457 vars[2] = "exedir"; legend[2] = "K95 Program directory";
13458 vars[3] = "inidir"; legend[3] = "K95 Initialization file directory";
13459 vars[4] = "startup"; legend[4] = "Current directory when started";
13460
13461 vars[5] = "common";
13462 legend[5] = "K95 data for all users and K95SITE.INI file";
13463
13464 vars[6] = "personal"; legend[6] = "Your personal data directory tree";
13465 vars[7] = "desktop"; legend[7] = "Your deskop directory tree";
13466
13467 vars[8] = "appdata";
13468 legend[8] = "Your personal K95 data tree and K95CUSTOM.INI file";
13469
13470 vars[9] = "download"; legend[9] = "Your K95 download directory";
13471 vars[10] = "tmpdir"; legend[10] = "Your TEMP directory";
13472 vars[11] = NULL; legend[11] = NULL;
13473
13474 for (i = 0; i < 16 && vars[i]; i++) {
13475 printf("%s:\n",legend[i]);
13476 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13477 ckmakmsg(vbuf,32,"\\v(",vars[i],")",NULL);
13478 printf(" Variable: %s\n",vbuf);
13479 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13480 y = TMPBUFSIZ;
13481 s = tmpbuf;
13482 zzstring(vbuf,&s,&y);
13483 line[0] = NUL;
13484 ckGetLongPathName(tmpbuf,line,LINBUFSIZ);
13485 printf(" Long name: %s\n",line);
13486 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13487 line[0] = NUL;
13488 GetShortPathName(tmpbuf,line,LINBUFSIZ);
13489 printf(" Short name: %s\n",line);
13490 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13491 printf("\n");
13492 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13493 }
13494 #else /* NT */
13495
13496 vars[0] = "home"; legend[0] = "Your home directory";
13497 vars[1] = "directory"; legend[1] = "Kermit's current directory";
13498 vars[2] = "exedir"; legend[2] = "Kermit's program directory";
13499 vars[3] = "inidir"; legend[3] = "Initialization file directory";
13500 vars[4] = "startup"; legend[4] = "Current directory when started";
13501 vars[5] = "download"; legend[5] = "Kermit download directory";
13502 vars[6] = NULL; legend[6] = NULL;
13503
13504 for (i = 0; i < 16 && vars[i]; i++) {
13505 printf("%s:\n",legend[i]);
13506 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13507 ckmakmsg(vbuf,32,"\\v(",vars[i],")",NULL);
13508 printf(" Variable: %s\n",vbuf);
13509 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13510 y = TMPBUFSIZ;
13511 s = tmpbuf;
13512 zzstring(vbuf,&s,&y);
13513 printf(" Value: %s\n",tmpbuf);
13514 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13515 printf("\n");
13516 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13517 }
13518 #endif /* NT */
13519 return(success = 1);
13520 }
13521
13522 #ifdef NT
13523 if (cx == XXDIALER) {
13524 StartDialer();
13525 return(success = 1);
13526 }
13527 #endif /* NT */
13528
13529 if (cx == XXCONT) { /* CONTINUE */
13530 if ((x = cmcfm()) < 0)
13531 return(x);
13532 if (!xcmdsrc) { /* At prompt: continue script */
13533 if (cmdlvl > 0)
13534 popclvl(); /* Pop command level */
13535 return(success = 1); /* always succeeds */
13536 #ifndef NOSPL
13537 } else { /* In script: whatever... */
13538 x = mlook(mactab,"continue",nmac);
13539 /* Don't set success */
13540 return(dodo(x,NULL,cmdstk[cmdlvl].ccflgs));
13541 #endif /* NOSPL */
13542 }
13543 }
13544 #ifdef UNIX
13545 #ifndef NOPUTENV
13546 /*
13547 NOTE: Syntax is PUTENV name value, not PUTENV name=value.
13548 I could check for this but it would be too much magic.
13549 */
13550 if (cx == XXPUTE) { /* PUTENV */
13551 char * t = tmpbuf; /* Create or alter environment var */
13552 char * s1 = NULL, * s2 = NULL;
13553 if ((x = cmfld("Variable name","",&s,xxstring)) < 0)
13554 return(x);
13555 if (s) if (s == "") s = NULL;
13556 (VOID) makestr(&s1,s);
13557 if (s && !s1) {
13558 printf("?PUTENV - memory allocation failure\n");
13559 return(-9);
13560 }
13561 if ((x = cmtxt("Value","",&s,xxstring)) < 0)
13562 return(x);
13563 if (s) if (s == "") s = NULL;
13564 (VOID) makestr(&s2,s);
13565 success = doputenv(s1,s2);
13566 (VOID) makestr(&s1,NULL);
13567 (VOID) makestr(&s2,NULL);
13568 return(success);
13569 }
13570 #endif /* NOPUTENV */
13571 #endif /* UNIX */
13572
13573 if (cx == XXNOTAV) { /* Command in table not available */
13574 ckstrncpy(tmpbuf,atmbuf,TMPBUFSIZ);
13575 if ((x = cmtxt("Rest of command","",&s,NULL)) < 0)
13576 return(x);
13577 printf("Sorry, \"%s\" not configured in this version of Kermit.\n",
13578 tmpbuf
13579 );
13580 return(success = 0);
13581 }
13582 return(-2); /* None of the above */
13583
13584 } /* end of docmd() */
13585
13586 #endif /* NOICP */
13587