1 #include "ckcsym.h"
2
3 /* C K U U S 7 -- "User Interface" for C-Kermit, part 7 */
4
5 /*
6 Authors:
7 Frank da Cruz <fdc@columbia.edu>,
8 The Kermit Project, New York City
9 Jeffrey E Altman <jaltman@secure-endpoints.com>
10 Secure Endpoints Inc., New York City
11
12 Copyright (C) 1985, 2020,
13 Trustees of Columbia University in the City of New York.
14 All rights reserved. See the C-Kermit COPYING.TXT file or the
15 copyright text in the ckcmai.c module for disclaimer and permissions.
16 */
17
18 /*
19 This file created from parts of ckuus3.c, which became too big for
20 Mark Williams Coherent compiler to handle.
21 */
22
23 /*
24 Definitions here supersede those from system include files.
25 */
26 #include "ckcdeb.h" /* Debugging & compiler things */
27 #include "ckcasc.h" /* ASCII character symbols */
28 #include "ckcker.h" /* Kermit application definitions */
29 #include "ckcxla.h" /* Character set translation */
30 #include "ckcnet.h" /* Network symbols */
31 #include "ckuusr.h" /* User interface symbols */
32 #include "ckucmd.h"
33 #include "ckclib.h"
34
35 #ifdef VMS
36 #ifndef TCPSOCKET
37 #include <errno.h>
38 #endif /* TCPSOCKET */
39 #endif /* VMS */
40
41 #ifdef OS2
42 #ifndef NT
43 #define INCL_NOPM
44 #define INCL_VIO /* Needed for ckocon.h */
45 #define INCL_DOSMODULEMGR
46 #include <os2.h>
47 #undef COMMENT
48 #else /* NT */
49 #define APIRET ULONG
50 #include <windows.h>
51 #include <tapi.h>
52 #include "cknwin.h"
53 #include "ckntap.h"
54 #endif /* NT */
55 #include "ckowin.h"
56 #include "ckocon.h"
57 #include "ckodir.h"
58 #ifdef OS2MOUSE
59 #include "ckokey.h"
60 #endif /* OS2MOUSE */
61 #ifdef KUI
62 #include "ikui.h"
63 #endif /* KUI */
64 #ifdef putchar
65 #undef putchar
66 #endif /* putchar */
67 #define putchar(x) conoc(x)
68 extern int mskkeys;
69 extern int mskrename;
70 #endif /* OS2 */
71
72 #ifdef CK_AUTHENTICATION
73 #include "ckuath.h"
74 #endif /* CK_AUTHENTICATION */
75 #ifdef CK_SSL
76 #include "ck_ssl.h"
77 #endif /* CK_SSL */
78 #ifdef SSHBUILTIN
79 #include "ckossh.h"
80 #endif /* SSHBUILTIN */
81 #ifdef STRATUS /* Stratus Computer, Inc. VOS */
82 #ifdef putchar
83 #undef putchar
84 #endif /* putchar */
85 #define putchar(x) conoc(x)
86 #ifdef getchar
87 #undef getchar
88 #endif /* getchar */
89 #define getchar(x) coninc(0)
90 #endif /* STRATUS */
91
92 char * slmsg = NULL;
93
94 static int x, y = 0, z;
95 static char *s;
96
97 extern CHAR feol;
98 extern int g_matchdot, hints, xcmdsrc, rcdactive;
99
100 extern char * k_info_dir;
101
102 #ifdef CK_LOGIN
103 #ifdef CK_PAM
104 int gotemptypasswd = 0; /* distinguish empty passwd from none given */
105 #endif /* CK_PAM */
106 #endif /* CK_LOGIN */
107
108 #ifndef NOSPL
109 extern int nmac;
110 extern struct mtab *mactab;
111 #endif /* NOSPL */
112
113 #ifndef NOXFER
114 #ifdef CK_SPEED
115 extern short ctlp[]; /* Control-char prefixing table */
116 #endif /* CK_SPEED */
117
118 #ifdef PIPESEND
119 extern char * sndfilter, * g_sfilter;
120 extern char * rcvfilter, * g_rfilter;
121 #endif /* PIPESEND */
122
123 extern char * snd_move;
124 extern char * snd_rename;
125 extern char * g_snd_move;
126 extern char * g_snd_rename;
127 extern char * rcv_move;
128 extern char * rcv_rename;
129 extern char * g_rcv_move;
130 extern char * g_rcv_rename;
131
132 #ifdef PATTERNS
133 extern char *binpatterns[], *txtpatterns[];
134 extern int patterns;
135 #endif /* PATTERNS */
136
137 extern char * remdest;
138 #ifdef CK_TMPDIR
139 char * dldir = NULL;
140 #endif /* CK_TMPDIR */
141
142 extern struct ck_p ptab[];
143
144 extern int protocol, remfile, rempipe, remappd, reliable, xreliable, fmask,
145 fncnv, frecl, maxrps, wslotr, bigsbsiz, bigrbsiz, urpsiz, rpsiz, spsiz,
146 bctr, npad, timef, timint, spsizr, spsizf, maxsps, spmax, nfils, displa,
147 atcapr, pkttim, rtimo, fncact, mypadn, fdispla, f_save, pktpaus, setreliable,
148 fnrpath, fnspath, atenci, atenco, atdati, atdato, atleni, atleno, atblki,
149 atblko, attypi, attypo, atsidi, atsido, atsysi, atsyso, atdisi, atdiso;
150
151 extern int stathack;
152
153 extern int atfrmi, atfrmo;
154 #ifdef STRATUS
155 extern int atcrei, atcreo, atacti, atacto;
156 #endif /* STRATUS */
157 #ifdef CK_PERMS
158 extern int atlpri, atlpro, atgpri, atgpro;
159 #endif /* CK_PERMS */
160
161 extern CHAR
162 sstate, eol, seol, stchr, mystch, mypadc, padch, ctlq, myctlq;
163
164 #ifdef IKSD
165 extern int inserver;
166 #ifdef IKSDCONF
167 extern int iksdcf;
168 #endif /* IKSDCONF */
169 #endif /* IKSD */
170
171 extern char *cmarg, *cmarg2;
172
173 #ifndef NOFRILLS
174 extern char optbuf[]; /* Buffer for MAIL or PRINT options */
175 extern int rprintf; /* REMOTE PRINT flag */
176 #endif /* NOFRILLS */
177 #endif /* NOXFER */
178
179 #ifdef CK_TRIGGER
180 extern char * tt_trigger[];
181 #endif /* CK_TRIGGER */
182
183 extern int tcs_transp;
184 #ifdef PCTERM
185 extern int tt_pcterm;
186 #endif /* PCTERM */
187 #ifdef NT
188 extern int tt_vtnt;
189 #endif /* NT */
190
191 #ifdef SSHBUILTIN
192 int sl_ssh_xfw = 0;
193 int sl_ssh_xfw_saved = 0;
194 int sl_ssh_ver = 0;
195 int sl_ssh_ver_saved = 0;
196 #endif /* SSHBUILTIN */
197
198 #ifdef CK_AUTHENTICATION
199 extern int auth_type_user[];
200 int sl_auth_type_user[AUTHTYPLSTSZ] = {AUTHTYPE_NULL, AUTHTYPE_NULL};
201 int sl_auth_saved = 0;
202 int sl_topt_a_su = 0;
203 int sl_topt_a_s_saved = 0;
204 int sl_topt_a_cm = 0;
205 int sl_topt_a_c_saved = 0;
206 #endif /* CK_AUTHENTICATION */
207 #ifdef CK_ENCRYPTION
208 extern int cx_type;
209 int sl_cx_type = 0;
210 int sl_cx_saved = 0;
211 int sl_topt_e_su = 0;
212 int sl_topt_e_sm = 0;
213 int sl_topt_e_s_saved = 0;
214 int sl_topt_e_cu = 0;
215 int sl_topt_e_cm = 0;
216 int sl_topt_e_c_saved = 0;
217 #endif /* CK_ENCRYPTION */
218 extern char uidbuf[];
219 static int uidflag = 0;
220 char sl_uidbuf[UIDBUFLEN] = { NUL, NUL };
221 int sl_uid_saved = 0;
222 #ifdef TNCODE
223 int sl_tn_wait = 0;
224 int sl_tn_saved = 0;
225 #endif /* TNCODE */
226
227 #ifdef TNCODE
228 extern int tn_wait_flg;
229 #endif /* TNCODE */
230
231 VOID
slrestor()232 slrestor() {
233 #ifdef CK_AUTHENTICATION
234 int x;
235 if (sl_auth_saved) {
236 for (x = 0; x < AUTHTYPLSTSZ; x++)
237 auth_type_user[x] = sl_auth_type_user[x];
238 sl_auth_saved = 0;
239 }
240 if (sl_topt_a_s_saved) {
241 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = sl_topt_a_su;
242 sl_topt_a_s_saved = 0;
243 }
244 if (sl_topt_a_c_saved) {
245 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = sl_topt_a_cm;
246 sl_topt_a_c_saved = 0;
247 }
248 #endif /* CK_AUTHENTICATION */
249 #ifdef CK_ENCRYPTION
250 if (sl_cx_saved) {
251 cx_type = sl_cx_type;
252 sl_cx_saved = 0;
253 }
254 if (sl_topt_e_s_saved) {
255 TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = sl_topt_e_su;
256 TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = sl_topt_e_sm;
257 sl_topt_e_s_saved = 0;
258 }
259 if (sl_topt_e_c_saved) {
260 TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = sl_topt_e_cu;
261 TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = sl_topt_e_cm;
262 sl_topt_e_c_saved = 0;
263 }
264 #endif /* CK_ENCRYPTION */
265 if (sl_uid_saved) {
266 ckstrncpy(uidbuf,sl_uidbuf,UIDBUFLEN);
267 sl_uid_saved = 0;
268 }
269 #ifdef TNCODE
270 if (sl_tn_saved) {
271 tn_wait_flg = sl_tn_wait;
272 sl_tn_saved = 0;
273 }
274 #endif /* TNCODE */
275 #ifdef SSHBUILTIN
276 if (sl_ssh_xfw_saved) {
277 ssh_xfw = sl_ssh_xfw;
278 sl_ssh_xfw_saved = 0;
279 }
280 if (sl_ssh_ver_saved) {
281 ssh_ver = sl_ssh_ver;
282 sl_ssh_ver_saved = 0;
283 }
284 #endif /* SSHBUILTIN */
285 }
286
287 int oldplex = -1; /* Duplex holder around network */
288
289 #ifndef NOICP
290 #ifdef LOCUS
291 extern int locus, autolocus;
292 #endif /* LOCUS */
293 #ifndef NODIAL
294 extern int dialsta;
295 #endif /* NODIAL */
296
297 /* Note: gcc -Wall wants braces around each keyword table entry. */
298
299 static struct keytab psltab[] = { /* SET LINE/PORT command options */
300 { "/connect", SL_CNX, 0 },
301 #ifdef OS2ORVMS
302 { "/noshare", SL_NSH, 0 },
303 #endif /* OS2ORVMS */
304 { "/server", SL_SRV, 0 },
305 #ifdef OS2ORVMS
306 { "/share", SL_SHR, 0 },
307 #endif /* OS2ORVMS */
308 { "", 0, 0 }
309 };
310 static int npsltab = sizeof(psltab)/sizeof(struct keytab) - 1;
311
312 #ifdef NETCONN
313 static struct keytab shtab[] = { /* SET HOST command options */
314 #ifdef NETCMD
315 /* (COMMAND is also a network type) */
316 { "/command", SL_CMD, CM_INV },
317 #endif /* NETCMD */
318 { "/connect", SL_CNX, 0 },
319 { "/network-type", SL_NET, CM_ARG },
320 { "/nowait", SL_NOWAIT, 0 },
321 #ifndef NOSPL
322 #ifdef CK_AUTHENTICATION
323 { "/password", SL_PSW, CM_ARG },
324 #endif /* CK_AUTHENTICATION */
325 #endif /* NOSPL */
326 #ifdef NETCMD
327 { "/pipe", SL_CMD, 0 },
328 #endif /* NETCMD */
329 #ifdef NETPTY
330 { "/pty", SL_PTY, 0 },
331 #endif /* NETPTY */
332 { "/server", SL_SRV, 0 },
333 { "/timeout", SL_TMO, CM_ARG },
334 { "/userid", SL_UID, CM_ARG },
335 { "/wait", SL_WAIT, 0 },
336 { "", 0, 0 }
337 };
338 static int nshtab = sizeof(shtab)/sizeof(struct keytab) - 1;
339
340 static struct keytab shteltab[] = { /* TELNET command options */
341 #ifdef CK_AUTHENTICATION
342 { "/auth", SL_AUTH, CM_ARG },
343 #endif /* CK_AUTHENTICATION */
344 #ifdef CK_ENCRYPTION
345 { "/encrypt", SL_ENC, CM_ARG },
346 #endif /* CK_ENCRYPTION */
347 { "/nowait", SL_NOWAIT, 0 },
348 #ifndef NOSPL
349 #ifdef CK_AUTHENTICATION
350 { "/password", SL_PSW, CM_ARG },
351 #endif /* CK_AUTHENTICATION */
352 #endif /* NOSPL */
353 { "/timeout", SL_TMO, CM_ARG },
354 { "/userid", SL_UID, CM_ARG },
355 { "/wait", SL_WAIT, 0 },
356 { "", 0 ,0 }
357 };
358 static int nshteltab = sizeof(shteltab)/sizeof(struct keytab) - 1;
359
360 #ifdef RLOGCODE
361 static struct keytab shrlgtab[] = { /* SET HOST RLOGIN command options */
362 #ifdef CK_KERBEROS
363 #ifdef CK_ENCRYPTION
364 { "/encrypt", SL_ENC, 0 },
365 #endif /* CK_ENCRYPTION */
366 { "/k4", SL_KRB4, CM_INV },
367 { "/k5", SL_KRB5, CM_INV },
368 { "/kerberos4", SL_KRB4, 0 },
369 { "/kerberos5", SL_KRB5, 0 },
370 { "/kerberos_iv", SL_KRB4, CM_INV },
371 { "/kerberos_v", SL_KRB5, CM_INV },
372 { "/krb4", SL_KRB4, CM_INV },
373 { "/krb5", SL_KRB5, CM_INV },
374 #endif /* CK_KERBEROS */
375 { "", 0 ,0 }
376 };
377 static int nshrlgtab = sizeof(shrlgtab)/sizeof(struct keytab)-1;
378 #endif /* RLOGCODE */
379
380 extern struct keytab netcmd[];
381 extern int nnets;
382 #ifndef NODIAL
383 extern int dirline;
384 extern int nnetdir; /* Network services directory */
385 extern char *netdir[];
386 _PROTOTYP( VOID ndreset, (void) );
387 char *nh_p[MAXDNUMS + 1]; /* Network directory entry pointers */
388 char *nh_p2[MAXDNUMS + 1]; /* Network directory entry nettype */
389 char *nh_px[4][MAXDNUMS + 1]; /* Network-specific stuff... */
390 #endif /* NODIAL */
391 int nhcount = 0;
392 int ndinited = 0;
393 char * n_name = NULL; /* Network name pointer */
394 #endif /* NETCONN */
395
396 _PROTOTYP(int remtxt, (char **) );
397 _PROTOTYP(VOID rmsg, (void) );
398 _PROTOTYP(static int remcfm, (void) );
399
400 extern int nopush;
401
402 int mdmsav = -1; /* Save modem type around network */
403 extern int isguest; /* Global flag for anonymous login */
404
405 extern xx_strp xxstring;
406
407 extern int success, binary, b_save, ckwarn, msgflg, quiet, cmask, pflag, local,
408 nettype, escape, mdmtyp, duplex, dfloc, network, cdtimo, autoflow, tnlm,
409 sosi, tlevel, lf_opts, backgrd, flow, debses, parity, ttnproto, ckxech,
410 x_ifnum, cmflgs, haveline, cxtype, cxflow[], maclvl;
411
412 #ifdef DCMDBUF
413 extern struct cmdptr *cmdstk; /* The command stack itself */
414 #else
415 extern struct cmdptr cmdstk[]; /* The command stack itself */
416 #endif /* DCMDBUF */
417 extern FILE * tfile[];
418 extern char * macp[];
419
420 extern char psave[]; /* For saving & restoring prompt */
421 extern int sprmlen, rprmlen;
422
423 #ifdef OS2
424 static struct keytab strmkeytab[] = {
425 { "clear", 0, 0 },
426 { "default", 1, 0 }
427 };
428 static int nstrmkeytab = sizeof(strmkeytab)/sizeof(struct keytab);
429
430 static struct keytab strmswitab[] = {
431 { "/literal", 0, 0 }
432 };
433 static int nstrmswitab = sizeof(strmswitab)/sizeof(struct keytab);
434
435 static struct keytab normrev[] = {
436 { "dark-display", 0, 0 },
437 { "light-display", 1, 0 },
438 { "normal", 0, 0 },
439 { "reverse", 1, 0 }
440 };
441
442 static struct keytab prnmtab[] = {
443 { "auto", 1, 0 },
444 { "copy", 2, 0 },
445 { "off", 0, 0 },
446 { "on", 1, CM_INV }, /* Compatibility with XPRINT version */
447 { "user", 3, 0 },
448 { "transparent", 3, CM_INV } /* not really transparent */
449 };
450 static int nprnmtab = sizeof(prnmtab)/sizeof(struct keytab);
451
452 extern int tt_diff_upd;
453
454 #ifdef NT
455 #define stricmp _stricmp
456 extern int tt_attr_bug;
457 #endif /* NT */
458 extern int tt_rows[], tt_cols[];
459 extern int tt_cols_usr;
460 extern int tt_szchng[VNUM];
461 int tt_modechg = TVC_ENA;
462 extern int tt_url_hilite, tt_url_hilite_attr;
463 extern struct _vtG G[4];
464 extern int priority;
465 extern bool send_c1;
466 int send_c1_usr = FALSE;
467 extern int sgrcolors;
468 extern int marginbell, marginbellcol;
469 extern int autoscroll, wy_autopage;
470 extern int tt_sac;
471 extern int dec_nrc, dec_lang, dec_kbd;
472 #else /* OS2 */
473 extern int tt_rows, tt_cols;
474 #endif /* OS2 */
475
476 extern int tt_escape;
477 extern long speed;
478
479 extern char *dftty;
480
481 extern char *tp, *lp; /* Temporary buffer & pointers */
482 extern char ttname[];
483
484 #ifdef CK_TAPI
485 int tttapi = 0; /* is Line TAPI? */
486 struct keytab * tapilinetab = NULL;
487 struct keytab * _tapilinetab = NULL;
488 int ntapiline = 0;
489 #endif /* CK_TAPI */
490
491 #ifdef NETCONN /* Network items */
492
493 #ifdef ANYX25
494 extern int revcall, closgr, cudata, nx25;
495 extern char udata[];
496 extern struct keytab x25tab[];
497 #ifndef IBMX25
498 extern int npadx3;
499 extern CHAR padparms[];
500 extern struct keytab padx3tab[];
501 #endif /* IBMX25 */
502 #endif /* ANYX25 */
503
504 #ifdef OS2
505 extern bool ttshare;
506 #ifndef NT
507 extern bool ttslip,ttppp;
508 #endif /* NT */
509 #endif /* OS2 */
510 #ifdef NPIPE
511 extern char pipename[];
512 #endif /* NPIPE */
513
514 #ifdef TCPSOCKET
515 static struct keytab tcprawtab[] = { /* SET HOST options */
516 { "/default", NP_DEFAULT, CM_INV },
517 #ifdef CK_AUTHENTICATION
518 #ifdef CK_KERBEROS
519 #ifdef RLOGCODE
520 { "/ek4login", NP_EK4LOGIN, 0 },
521 { "/ek5login", NP_EK5LOGIN, 0 },
522 { "/k4login", NP_K4LOGIN, 0 },
523 { "/k5login", NP_K5LOGIN, 0 },
524 #endif /* RLOGCODE */
525 #ifdef KRB5_U2U
526 { "/k5user2user", NP_K5U2U, 0 },
527 #endif /* KRB5_U2U */
528 #endif /* CK_KERBEROS */
529 #endif /* CK_AUTHENTICATION */
530 { "/no-telnet-init", NP_NONE, 0 },
531 { "/none", NP_NONE, CM_INV },
532 { "/raw-socket", NP_TCPRAW, 0 },
533 #ifdef RLOGCODE
534 { "/rlogin", NP_RLOGIN, 0 },
535 #endif /* RLOGCODE */
536 #ifdef CK_SSL
537 { "/ssl", NP_SSL, 0 },
538 { "/ssl-raw", NP_SSL_RAW, 0 },
539 { "/ssl-telnet", NP_SSL_TELNET, 0 },
540 #endif /* CK_SSL */
541 { "/telnet", NP_TELNET, 0 },
542 #ifdef CK_SSL
543 { "/tls", NP_TLS, 0 },
544 { "/tls-raw", NP_TLS_RAW, 0 },
545 { "/tls-telnet", NP_TLS_TELNET, 0 },
546 #endif /* CK_SSL */
547 { "", 0, 0 }
548 };
549 static int ntcpraw = (sizeof(tcprawtab) / sizeof(struct keytab)) - 1;
550
551 #ifdef RLOGCODE
552 _PROTOTYP( int rlog_naws, (void) );
553 #endif /* RLOGCODE */
554 #endif /* TCPSOCKET */
555
556 #ifdef SUPERLAT
557 extern char slat_pwd[18];
558 #endif /* SUPERLAT */
559 #endif /* NETCONN */
560
561 #ifdef COMMENT
562 #ifndef NOSETKEY
563 extern KEY *keymap;
564 #ifndef OS2
565 #define mapkey(x) keymap[x]
566 #endif /* OS2 */
567 extern MACRO *macrotab;
568 #ifndef NOKVERBS
569 extern struct keytab kverbs[];
570 extern int nkverbs;
571 #endif /* NOKVERBS */
572 #endif /* NOSETKEY */
573 #else
574 #ifndef NOSETKEY
575 extern KEY *keymap;
576 extern MACRO *macrotab;
577 #ifndef NOKVERBS
578 extern struct keytab kverbs[];
579 extern int nkverbs;
580 #endif /* NOKVERBS */
581 #endif /* NOSETKEY */
582 #endif /* COMMENT */
583
584 #ifdef OS2 /* AUTODOWNLOAD parameters */
585 extern int adl_kmode, adl_zmode; /* Match Packet to signal download */
586 extern char * adl_kstr; /* KERMIT Download String */
587 extern char * adl_zstr; /* ZMODEM Download String */
588 extern int adl_kc0, adl_zc0; /* Process ADL C0s in emulation */
589 #endif /* OS2 */
590
591 /* Keyword tables ... */
592
593 extern struct keytab onoff[], rltab[];
594 extern int nrlt;
595
596 #ifndef NOCSETS
597 static struct keytab fdfltab[] = {
598 { "7bit-character-set", 7, 0 },
599 { "8bit-character-set", 8, 0 }
600 };
601 static int nfdflt = (sizeof(fdfltab) / sizeof(struct keytab));
602 #endif /* NOCSETS */
603
604 /* SET FILE parameters */
605
606 static struct keytab filtab[] = {
607 #ifndef NOXFER
608 #ifdef PATTERNS
609 { "binary-patterns", XYFIBP, 0 },
610 #endif /* PATTERNS */
611 { "bytesize", XYFILS, 0 },
612 #ifndef NOCSETS
613 { "character-set", XYFILC, 0 },
614 #endif /* NOCSETS */
615 { "collision", XYFILX, 0 },
616 { "default", XYF_DFLT, 0 },
617 { "destination", XYFILY, 0 },
618 { "display", XYFILD, CM_INV },
619 #ifdef CK_TMPDIR
620 { "download-directory", XYFILG, 0 },
621 #endif /* CK_TMPDIR */
622 #endif /* NOXFER */
623 { "end-of-line", XYFILA, 0 },
624 { "eol", XYFILA, CM_INV },
625 #ifdef CK_CTRLZ
626 { "eof", XYFILV, 0 },
627 #endif /* CK_CTRLZ */
628 #ifndef NOXFER
629 { "fastlookups", 9997, CM_INV },
630 { "incomplete", XYFILI, 0 },
631 #ifndef datageneral
632 { "inspection", XYF_INSP, CM_INV },
633 #endif /* datageneral */
634 #ifdef CK_LABELED
635 { "label", XYFILL, 0 },
636 #endif /* CK_LABELED */
637
638 #ifdef UNIX
639 #ifdef DYNAMIC
640 { "listsize", XYF_LSIZ, 0 },
641 #endif /* DYNAMIC */
642 #endif /* UNIX */
643
644 { "names", XYFILN, 0 },
645 #ifdef UNIX
646 { "output", XYFILH, 0 },
647 #endif /* UNIX */
648 #ifdef PATTERNS
649 { "patterns", XYFIPA, 0 },
650 #endif /* PATTERNS */
651 #ifdef COMMENT /* Not implemented (but see CHMOD) */
652 { "permissions", XYF_PRM, CM_INV },
653 { "protection", XYF_PRM, 0 },
654 #endif /* COMMENt */
655 #ifdef VMS
656 { "record-length", XYFILR, 0 },
657 #endif /* VMS */
658 #ifndef datageneral
659 { "scan", XYF_INSP, 0 },
660 #endif /* datageneral */
661
662 #ifdef UNIX
663 #ifdef DYNAMIC
664 { "stringspace", XYF_SSPA, 0 },
665 #endif /* DYNAMIC */
666 #endif /* UNIX */
667
668 #ifdef PATTERNS
669 { "t", XYFILT, CM_INV|CM_ABR },
670 { "text-patterns", XYFITP, 0 },
671 #endif /* PATTERNS */
672 #endif /* NOXFER */
673 { "type", XYFILT, 0 },
674 #ifdef UNICODE
675 { "ucs", XYFILU, 0 },
676 #endif /* UNICODE */
677 #ifndef NOXFER
678 { "warning", XYFILW, CM_INV }
679 #endif /* NOXFER */
680 };
681 static int nfilp = (sizeof(filtab) / sizeof(struct keytab));
682
683 struct keytab pathtab[] = {
684 { "absolute", PATH_ABS, 0 },
685 { "none", PATH_OFF, CM_INV },
686 { "off", PATH_OFF, 0 },
687 { "on", PATH_ABS, CM_INV },
688 { "relative", PATH_REL, 0 }
689 };
690 int npathtab = (sizeof(pathtab) / sizeof(struct keytab));
691
692 struct keytab rpathtab[] = {
693 { "absolute", PATH_ABS, 0 },
694 { "auto", PATH_AUTO, 0 },
695 { "none", PATH_OFF, CM_INV },
696 { "off", PATH_OFF, 0 },
697 { "on", PATH_ABS, CM_INV },
698 { "relative", PATH_REL, 0 }
699 };
700 int nrpathtab = (sizeof(rpathtab) / sizeof(struct keytab));
701
702 #ifdef CK_CTRLZ
703 struct keytab eoftab[] = { /* EOF detection method */
704 { "ctrl-z", 1, 0 },
705 { "length", 0, 0 },
706 { "noctrl-z", 0, CM_INV }
707 };
708 #endif /* CK_CTRLZ */
709
710 struct keytab fttab[] = { /* File types for SET FILE TYPE */
711 { "ascii", XYFT_T, CM_INV },
712 #ifdef VMS
713 { "b", XYFT_B, CM_INV|CM_ABR },
714 #endif /* VMS */
715 { "binary", XYFT_B, 0 },
716 #ifdef VMS
717 { "block", XYFT_I, CM_INV },
718 { "image", XYFT_I, 0 },
719 #endif /* VMS */
720 #ifdef CK_LABELED
721 { "labeled", XYFT_L, 0 },
722 #endif /* CK_LABELED */
723 #ifdef MAC
724 { "macbinary", XYFT_M, 0 },
725 #endif /* MAC */
726 { "text", XYFT_T, 0 }
727 };
728 int nfttyp = (sizeof(fttab) / sizeof(struct keytab));
729
730 static struct keytab rfttab[] = { /* File types for REMOTE SET FILE */
731 { "ascii", XYFT_T, CM_INV },
732 { "binary", XYFT_B, 0 },
733 #ifdef VMS
734 { "labeled", XYFT_L, 0 },
735 #else
736 #ifdef OS2
737 { "labeled", XYFT_L, 0 },
738 #endif /* OS2 */
739 #endif /* VMS */
740 { "text", XYFT_T, 0 }
741 };
742 static int nrfttyp = (sizeof(rfttab) / sizeof(struct keytab));
743
744 #ifdef OS2ORUNIX
745 #define ZOF_BLK 0
746 #define ZOF_NBLK 1
747 #define ZOF_BUF 2
748 #define ZOF_NBUF 3
749 static struct keytab zoftab[] = {
750 { "blocking", ZOF_BLK, 0 },
751 { "buffered", ZOF_BUF, 0 },
752 { "nonblocking", ZOF_NBLK, 0 },
753 { "unbuffered", ZOF_NBUF, 0 }
754 };
755 static int nzoftab = (sizeof(zoftab) / sizeof(struct keytab));
756 #endif /* OS2ORUNIX */
757
758 extern int query; /* Global flag for QUERY active */
759
760 #ifndef NOSPL
761 #ifndef NOXFER
762 static struct keytab vartyp[] = { /* Variable types for REMOTE QUERY */
763 { "global", (int) 'G', CM_INV },
764 { "kermit", (int) 'K', 0 },
765 { "system", (int) 'S', 0 },
766 { "user", (int) 'G', 0 }
767 };
768 static int nvartyp = (sizeof(vartyp) / sizeof(struct keytab));
769 #endif /* NOXFER */
770 #endif /* NOSPL */
771
772 #ifdef CK_TIMERS
773 static struct keytab timotab[] = { /* Timer types */
774 { "dynamic", 1, 0 },
775 { "fixed", 0, 0 }
776 };
777 #endif /* CK_TIMERS */
778
779 #ifdef DCMDBUF
780 extern char *atxbuf, *atmbuf; /* Atom buffer */
781 extern char *cmdbuf; /* Command buffer */
782 extern char *line, *tmpbuf; /* Character buffers for anything */
783 extern int *intime; /* INPUT TIMEOUT */
784
785 #else /* Not DCMDBUF ... */
786
787 extern char atxbuf[], atmbuf[]; /* Atom buffer */
788 extern char cmdbuf[]; /* Command buffer */
789 extern char line[], tmpbuf[]; /* Character buffer for anything */
790 extern int intime[];
791
792 #endif /* DCMDBUF */
793
794 #ifndef NOCSETS
795 extern struct keytab fcstab[]; /* For SET FILE CHARACTER-SET */
796 extern struct csinfo fcsinfo[]; /* File character set info. */
797 extern struct keytab ttcstab[];
798 extern int nfilc, fcharset, tcharset, ntermc, tcsr, tcsl, dcset7, dcset8;
799 #ifdef CKOUNI
800 extern int tt_utf8;
801 #endif /* CKOUNI */
802 #ifdef OS2
803 _PROTOTYP( int os2setcp, (int) );
804 _PROTOTYP( int os2getcp, (void) );
805 _PROTOTYP( void os2debugoff, (void) );
806 #endif /* OS2 */
807 #endif /* NOCSETS */
808
809 extern int cmdlvl; /* Overall command level */
810
811 #ifndef NOSPL
812 #ifdef DCMDBUF
813 extern int *inpcas; /* INPUT CASE setting on cmd stack */
814 #else
815 extern int inpcas[];
816 #endif /* DCMDBUF */
817 #endif /* NOSPL */
818
819 #ifdef CK_CURSES
820 #ifndef VMS
821 _PROTOTYP(int tgetent,(char *, char *));
822 #else
823 #ifdef __DECC
824 _PROTOTYP(int tgetent,(char *, char *));
825 #endif /* __DECC */
826 #endif /* VMS */
827 #endif /* CK_CURSES */
828
829 #ifndef NOXMIT
830 #define XMITF 0 /* SET TRANSMIT values */
831 #define XMITL 1 /* (Local to this module) */
832 #define XMITP 2
833 #define XMITE 3
834 #define XMITX 4
835 #define XMITS 5
836 #define XMITW 6
837 #define XMITT 7
838
839 #define XMBUFL 50
840 extern int xmitf, xmitl, xmitp, xmitx, xmits, xmitw, xmitt;
841 char xmitbuf[XMBUFL+1] = { NUL }; /* TRANSMIT eof string */
842
843 struct keytab xmitab[] = { /* SET TRANSMIT */
844 { "echo", XMITX, 0 },
845 { "eof", XMITE, 0 },
846 { "fill", XMITF, 0 },
847 { "linefeed", XMITL, 0 },
848 { "locking-shift", XMITS, 0 },
849 { "pause", XMITW, 0 },
850 { "prompt", XMITP, 0 },
851 { "timeout", XMITT, 0 }
852 };
853 int nxmit = (sizeof(xmitab) / sizeof(struct keytab));
854 #endif /* NOXMIT */
855
856 /* For SET FILE COLLISION */
857 /* Some of the following may be possible for some C-Kermit implementations */
858 /* but not others. Those that are not possible for your implementation */
859 /* should be ifdef'd out. */
860
861 struct keytab colxtab[] = { /* SET FILE COLLISION options */
862 #ifndef MAC
863 { "append", XYFX_A, 0 }, /* append to old file */
864 #endif /* MAC */
865 #ifdef COMMENT
866 { "ask", XYFX_Q, 0 }, /* ask what to do (not implemented) */
867 #endif
868 { "backup", XYFX_B, 0 }, /* rename old file */
869 #ifndef MAC
870 /* This crashes Mac Kermit. */
871 { "discard", XYFX_D, CM_INV }, /* don't accept new file */
872 { "no-supersede", XYFX_D, CM_INV }, /* ditto (MSK compatibility) */
873 #endif /* MAC */
874 { "overwrite", XYFX_X, 0 }, /* overwrite the old file */
875 { "reject", XYFX_D, 0 }, /* (better word than discard) */
876 { "rename", XYFX_R, 0 }, /* rename the incoming file */
877 #ifndef MAC /* This crashes Mac Kermit. */
878 { "update", XYFX_U, 0 }, /* replace if newer */
879 #endif /* MAC */
880 { "", 0, 0 }
881 };
882 int ncolx = (sizeof(colxtab) / sizeof(struct keytab)) - 1;
883
884 static struct keytab rfiltab[] = { /* for REMOTE SET FILE */
885 #ifndef NOCSETS
886 { "character-set", XYFILC, 0 },
887 #endif /* NOCSETS */
888 { "collision", XYFILX, 0 },
889 { "incomplete", XYFILI, 0 },
890 { "names", XYFILN, 0 },
891 { "record-length", XYFILR, 0 },
892 { "type", XYFILT, 0 }
893 };
894 int nrfilp = (sizeof(rfiltab) / sizeof(struct keytab));
895
896 struct keytab eoltab[] = { /* File eof delimiters */
897 { "cr", XYFA_C, 0 },
898 { "crlf", XYFA_2, 0 },
899 { "lf", XYFA_L, 0 }
900 };
901 static int neoltab = (sizeof(eoltab) / sizeof(struct keytab));
902
903 struct keytab fntab[] = { /* File naming */
904 { "converted", XYFN_C, 0 },
905 { "literal", XYFN_L, 0 },
906 { "standard", XYFN_C, CM_INV }
907 };
908 int nfntab = (sizeof(fntab) / sizeof(struct keytab));
909
910 #ifndef NOLOCAL
911 /* Terminal parameters table */
912 static struct keytab trmtab[] = {
913 #ifdef OS2
914 { "answerback", XYTANS, 0 },
915 #endif /* OS2 */
916 #ifdef CK_APC
917 { "apc", XYTAPC, 0 },
918 #endif /* CK_APC */
919 #ifdef OS2
920 { "arrow-keys", XYTARR, 0 },
921 #endif /* OS2 */
922 #ifdef NT
923 { "at", XYTATTR, CM_INV|CM_ABR },
924 { "att", XYTATTR, CM_INV|CM_ABR },
925 { "attr", XYTATTR, CM_INV|CM_ABR },
926 { "attr-bug", XYTATTBUG, CM_INV },
927 #endif /* NT */
928 #ifdef OS2
929 { "attribute", XYTATTR, 0 },
930 #endif /* OS2 */
931 #ifdef CK_APC
932 #ifdef CK_AUTODL
933 { "autodownload", XYTAUTODL, 0, },
934 #endif /* CK_AUTODL */
935 #endif /* CK_APC */
936 #ifdef OS2
937 { "autopage", XYTAPAGE, 0 },
938 { "autoscroll", XYTASCRL, 0 },
939 { "bell", XYTBEL, CM_INV },
940 #endif /* OS2 */
941 { "bytesize", XYTBYT, 0 },
942 #ifndef NOCSETS
943 { "character-set", XYTCS, 0 },
944 #endif /* NOCSETS */
945 #ifdef OS2
946 { "code-page", XYTCPG, 0 },
947 { "color", XYTCOL, 0 },
948 { "controls", XYTCTRL, 0 },
949 #endif /* OS2 */
950 { "cr-display", XYTCRD, 0 },
951 #ifdef OS2
952 { "cursor", XYTCUR, 0 },
953 #endif /* OS2 */
954 { "debug", XYTDEB, 0 },
955 #ifdef OS2
956 { "dg-unix-mode", XYTUNX, 0 },
957 #endif /* OS2 */
958 { "echo", XYTEC, 0 },
959 { "escape-character", XYTESC, 0 },
960 #ifdef OS2
961 #ifdef PCFONTS
962 { "font", XYTFON, 0 },
963 #else
964 #ifdef KUI
965 { "font", XYTFON, 0 },
966 #endif /* KUI */
967 #endif /* PCFONTS */
968 #endif /* OS2 */
969 { "height", XYTHIG, 0 },
970 #ifdef CKTIDLE
971 { "idle-action", XYTIACT, 0 },
972 { "idle-limit", XYTITMO, CM_INV },
973 { "idle-send", XYTIDLE, CM_INV },
974 { "idle-timeout", XYTITMO, 0 },
975 #endif /* CKTIDLE */
976 #ifdef OS2
977 #ifndef NOCSETS
978 { "kbd-follows-gl/gr", XYTKBDGL, 0 },
979 #endif /* NOCSETS */
980 { "key", XYTKEY, 0 },
981 { "keyboard-mode", XYTKBMOD, 0 },
982 { "keypad-mode", XYTKPD, 0 },
983 #endif /* OS2 */
984 { "lf-display", XYTLFD, 0 },
985 #ifndef NOCSETS
986 #ifdef OS2
987 #ifndef KUI
988 { "line-spacing", XYTLSP, CM_INV },
989 { "local-character-set", XYTLCS, 0 },
990 #else
991 { "line-spacing", XYTLSP, 0 },
992 { "local-character-set", XYTLCS, CM_INV },
993 #endif /* KUI */
994 #else
995 { "local-character-set", XYTLCS, CM_INV },
996 #endif /* OS2 */
997 #endif /* NOCSETS */
998 { "locking-shift", XYTSO, 0 },
999 #ifdef OS2
1000 { "margin-bell", XYTMBEL, 0 },
1001 #endif /* OS2 */
1002 #ifdef OS2MOUSE
1003 { "mouse", XYTMOU, CM_INV },
1004 #endif /* OS2MOUSE */
1005 { "newline-mode", XYTNL, 0 },
1006 #ifdef OS2
1007 { "output-pacing", XYTPAC, 0 },
1008 #ifdef PCTERM
1009 { "pcterm", XYTPCTERM, 0 },
1010 #endif /* PCTERM */
1011 #endif /* OS2 */
1012 #ifdef OS2ORUNIX
1013 { "print", XYTPRN, 0 },
1014 #endif /* OS2ORUNIX */
1015 #ifndef NOCSETS
1016 #ifdef OS2
1017 { "remote-character-set", XYTRCS, 0 },
1018 #else
1019 { "remote-character-set", XYTRCS, CM_INV },
1020 #endif /* OS2 */
1021 #endif /* NOCSETS */
1022 #ifdef OS2
1023 { "roll-mode", XYTROL, 0 },
1024 { "s", XYTUPD, CM_ABR|CM_INV },
1025 { "sc", XYTUPD, CM_ABR|CM_INV },
1026 { "scr", XYTUPD, CM_ABR|CM_INV },
1027 { "scree", XYTUPD, CM_ABR|CM_INV },
1028 { "screen", XYTUPD, CM_ABR|CM_INV },
1029 { "screen-", XYTUPD, CM_ABR|CM_INV },
1030 { "screen-mode", XYTSCNM, 0 },
1031 { "screen-optimize", XYTOPTI, 0 },
1032 { "screen-update", XYTUPD, 0 },
1033 { "scrollback", XYSCRS, 0 },
1034 { "send-data", XYTSEND, 0 },
1035 { "send-end-of-block", XYTSEOB, 0 },
1036 { "sgr-colors", XYTSGRC, 0 },
1037 { "sni-ch.code", XYTSNICC, 0 },
1038 { "sni-firmware-versions", XYTSNIFV, 0 },
1039 { "sni-language", XYTVTLNG, 0 },
1040 { "sni-pagemode", XYTSNIPM, CM_INV },
1041 { "sni-scrollmode", XYTSNISM, CM_INV },
1042 { "spacing-attribute-character", XYTSAC, CM_INV },
1043 { "statusline", XYTSTAT, 0 },
1044 { "tra", XYTCTS, CM_INV|CM_ABR },
1045 { "transmit-timeout", XYTCTS, 0 },
1046 #endif /* OS2 */
1047
1048 #ifdef OS2ORUNIX
1049 { "transparent-print", XYTPRN, CM_INV },
1050 #endif /* OS2ORUNIX */
1051
1052 #ifdef CK_TRIGGER
1053 { "trigger", XYTRIGGER,0 },
1054 #endif /* CK_TRIGGER */
1055 #ifdef OS2
1056 { "type", XYTTYP, 0 },
1057 #else
1058 { "type", XYTTYP, CM_INV },
1059 #endif /* OS2 */
1060
1061 #ifndef NOCSETS
1062 #ifdef UNICODE
1063 #ifdef CKOUNI
1064 { "unicode", XYTUNI, CM_INV },
1065 #endif /* CKOUNI */
1066 #endif /* UNICODE */
1067 #endif /* NOCSETS */
1068 #ifdef OS2
1069 { "unix-mode", XYTUNX, CM_INV },
1070 { "url-highlight", XYTURLHI, 0 },
1071 #ifdef NT
1072 { "video-change", XYTVCH, 0 },
1073 #endif /* NT */
1074 { "vt-language", XYTVTLNG, 0 },
1075 { "vt-nrc-mode", XYTVTNRC, 0 },
1076 #endif /* OS2 */
1077 { "width", XYTWID, 0 },
1078 #ifdef OS2
1079 { "wrap", XYTWRP, 0 },
1080 #endif /* OS2 */
1081 { "", 0, 0 }
1082 };
1083 int ntrm = (sizeof(trmtab) / sizeof(struct keytab)) - 1;
1084
1085 #ifdef OS2
1086 struct keytab termctrl[] = { /* SET TERM CONTROLS */
1087 { "7", 7, 0 },
1088 { "8", 8, 0 }
1089 };
1090 int ntermctrl = (sizeof(termctrl) / sizeof(struct keytab));
1091
1092 struct keytab curontab[] = { /* SET TERM CURSOR */
1093 #ifdef KUI
1094 { "noblink", 2, 0 },
1095 #else
1096 { "noblink", 2, CM_INV },
1097 #endif /* KUI */
1098 { "off", 0, 0 },
1099 { "on", 1, 0 }
1100 };
1101 int ncuron = (sizeof(curontab) / sizeof(struct keytab));
1102
1103 struct keytab rolltab[] = { /* Set TERM Roll Options */
1104 { "insert", TTR_INSERT, 0 },
1105 { "keystrokes",TTR_KEYS, 0 },
1106 { "off", TTR_OVER, CM_INV },
1107 { "on", TTR_INSERT, CM_INV },
1108 { "overwrite", TTR_OVER, 0 }
1109 };
1110 int nroll = (sizeof(rolltab) / sizeof(struct keytab));
1111
1112 struct keytab rollkeytab[] = { /* Set TERM ROLL KEYSTROKES */
1113 { "ignore", TTRK_IGN, 0 },
1114 { "restore-and-send", TTRK_RST, 0 },
1115 { "send", TTRK_SND, 0 }
1116 };
1117 int nrollkey = (sizeof(rollkeytab) / sizeof(struct keytab));
1118
1119 #define TT_GR_ALL 4
1120 #define TT_GR_G0 0
1121 #define TT_GR_G1 1
1122 #define TT_GR_G2 2
1123 #define TT_GR_G3 3
1124 #define TT_GR_KBD 4
1125 struct keytab graphsettab[] = { /* DEC VT Graphic Sets */
1126 { "all", TT_GR_ALL, 0 },
1127 { "g0", TT_GR_G0, 0 },
1128 { "g1", TT_GR_G1, 0 },
1129 { "g2", TT_GR_G2, 0 },
1130 { "g3", TT_GR_G3, 0 },
1131 { "keyboard", TT_GR_KBD, 0 }
1132 };
1133 int ngraphset = (sizeof(graphsettab) / sizeof(struct keytab));
1134 #endif /* OS2 */
1135
1136 struct keytab adltab[] = { /* Autodownload Options */
1137 { "ask", TAD_ASK, 0 },
1138 { "error", TAD_ERR, 0 },
1139 #ifdef OS2
1140 { "kermit", TAD_K, 0 },
1141 #endif /* OS2 */
1142 { "off", TAD_OFF, 0 },
1143 { "on", TAD_ON, 0 },
1144 #ifdef OS2
1145 { "zmodem", TAD_Z, 0 },
1146 #endif /* OS2 */
1147 { "", 0, 0 }
1148 };
1149 int nadltab = (sizeof(adltab) / sizeof(struct keytab)) - 1;
1150
1151 struct keytab adlerrtab[] = { /* Autodownload Error Options */
1152 { "continue", 0, 0 },
1153 { "go", 0, CM_INV },
1154 { "stop", 1, 0 }
1155 };
1156 int nadlerrtab = (sizeof(adlerrtab) / sizeof(struct keytab));
1157
1158 #ifdef OS2
1159 struct keytab adlxtab[] = { /* Autodownload Options */
1160 { "c0-conflicts", TAD_X_C0, 0 },
1161 { "detection-method", TAD_X_DETECT, 0 },
1162 { "string", TAD_X_STR, 0 }
1163 };
1164 int nadlxtab = (sizeof(adlxtab) / sizeof(struct keytab));
1165
1166 struct keytab adldtab[] = { /* Auto-dl Detection Methods */
1167 { "packet", ADL_PACK, 0 },
1168 { "string", ADL_STR, 0 }
1169 };
1170 int nadldtab = (sizeof(adldtab) / sizeof(struct keytab));
1171
1172 struct keytab adlc0tab[] = { /* Auto-dl Detection Methods */
1173 { "ignored-by-emulator", 0, 0 },
1174 { "processed-by-emulator", 1, 0 }
1175 };
1176 int nadlc0tab = (sizeof(adlc0tab) / sizeof(struct keytab));
1177
1178 #ifndef NOCSETS
1179 struct keytab vtlangtab[] = {
1180 { "belgian", VTL_BELGIAN , 0 },
1181 { "british", VTL_BRITISH , 0 },
1182 { "canadian", VTL_CANADIAN, 0 },
1183 { "czech", VTL_CZECH , 0 },
1184 { "danish", VTL_DANISH , 0 },
1185 { "dutch", VTL_DUTCH , 0 },
1186 { "finnish", VTL_FINNISH , 0 },
1187 { "french", VTL_FRENCH , 0 },
1188 { "french-canadian",VTL_FR_CAN , 0 },
1189 { "german", VTL_GERMAN , 0 },
1190 { "greek", VTL_GREEK , 0 },
1191 { "hebrew", VTL_HEBREW , 0 },
1192 { "hungarian", VTL_HUNGARIA, 0 },
1193 { "italian", VTL_ITALIAN , 0 },
1194 { "latin-american", VTL_LATIN_AM, 0 },
1195 { "north-american", VTL_NORTH_AM, 0 },
1196 { "norwegian", VTL_NORWEGIA, 0 },
1197 { "polish", VTL_POLISH , 0 },
1198 { "portugese", VTL_PORTUGES, 0 },
1199 { "romanian", VTL_ROMANIAN, 0 },
1200 { "russian", VTL_RUSSIAN , 0 },
1201 { "scs", VTL_SCS , CM_INV },
1202 { "slovak", VTL_SLOVAK , 0 },
1203 { "spanish", VTL_SPANISH , 0 },
1204 { "swedish", VTL_SWEDISH , 0 },
1205 { "swiss-french", VTL_SW_FR , 0 },
1206 { "swiss-german", VTL_SW_GR , 0 },
1207 { "turkish-f", VTL_TURK_F , CM_INV },
1208 { "turkish-q", VTL_TURK_Q , CM_INV }
1209 };
1210 int nvtlangtab = (sizeof(vtlangtab) / sizeof(struct keytab));
1211 #endif /* NOCSETS */
1212 #endif /* OS2 */
1213
1214 struct keytab crdtab[] = { /* Carriage-return display */
1215 { "crlf", 1, 0 },
1216 { "normal", 0, 0 }
1217 };
1218 extern int tt_crd; /* Carriage-return display variable */
1219 extern int tt_lfd; /* Linefeed display variable */
1220
1221 #ifdef CK_APC
1222 extern int apcstatus, apcactive;
1223 static struct keytab apctab[] = { /* Terminal APC parameters */
1224 { "no-input", APC_ON|APC_NOINP,0 },
1225 { "off", APC_OFF, 0 },
1226 { "on", APC_ON, 0 },
1227 { "unchecked", APC_ON|APC_UNCH, 0 },
1228 { "unchecked-no-input", APC_ON|APC_NOINP|APC_UNCH, 0 }
1229 };
1230 int napctab = (sizeof(apctab) / sizeof(struct keytab));
1231 #endif /* CK_APC */
1232 #endif /* NOLOCAL */
1233
1234 extern int autodl, adl_err, adl_ask;
1235
1236 struct keytab beltab[] = { /* Terminal bell mode */
1237 #ifdef OS2
1238 { "audible", XYB_AUD, 0 },
1239 { "none", XYB_NONE, 0 },
1240 #else
1241 { "audible", XYB_AUD, CM_INV },
1242 { "none", XYB_NONE, CM_INV },
1243 #endif /* OS2 */
1244 #ifdef OS2
1245 { "off", XYB_NONE, CM_INV },
1246 { "on", XYB_AUD, CM_INV },
1247 #else
1248 { "off", XYB_NONE, 0 },
1249 { "on", XYB_AUD, 0 },
1250 #endif /* OS2 */
1251 #ifdef OS2
1252 { "visible", XYB_VIS, 0 },
1253 #endif /* OS2 */
1254 { "", 0, 0 }
1255 };
1256 int nbeltab = sizeof(beltab)/sizeof(struct keytab) - 1;
1257
1258 int tt_unicode = 1; /* Use Unicode if possible */
1259 #ifdef CKTIDLE
1260 int tt_idlesnd_tmo = 0; /* Idle Send Timeout, disabled */
1261 char * tt_idlesnd_str = NULL; /* Idle Send String, none */
1262 char * tt_idlestr = NULL;
1263 extern int tt_idleact, tt_idlelimit;
1264 #endif /* CKTIDLE */
1265
1266 #ifdef OS2
1267 #ifndef NOLOCAL
1268 /*
1269 OS/2 serial communication devices.
1270 */
1271 struct keytab os2devtab[] = {
1272 { "1", 1, CM_INV }, /* Invisible synonyms, like */
1273 { "2", 2, CM_INV }, /* "set port 1" */
1274 { "3", 3, CM_INV },
1275 { "4", 4, CM_INV },
1276 { "5", 5, CM_INV },
1277 { "6", 6, CM_INV },
1278 { "7", 7, CM_INV },
1279 { "8", 8, CM_INV },
1280 { "com1", 1, 0 }, /* Real device names */
1281 { "com2", 2, 0 },
1282 { "com3", 3, 0 },
1283 { "com4", 4, 0 },
1284 { "com5", 5, 0 },
1285 { "com6", 6, 0 },
1286 { "com7", 7, 0 },
1287 { "com8", 8, 0 },
1288 #ifdef OS2ONLY
1289 { "slipcom1", 1, 0 }, /* For use with SLIP driver */
1290 { "slipcom2", 2, 0 }, /* shared access */
1291 { "slipcom3", 3, 0 },
1292 { "slipcom4", 4, 0 },
1293 { "slipcom5", 5, 0 },
1294 { "slipcom6", 6, 0 },
1295 { "slipcom7", 7, 0 },
1296 { "slipcom8", 8, 0 },
1297 { "pppcom1", 1, 0 }, /* For use with PPP driver */
1298 { "pppcom2", 2, 0 }, /* shared access */
1299 { "pppcom3", 3, 0 },
1300 { "pppcom4", 4, 0 },
1301 { "pppcom5", 5, 0 },
1302 { "pppcom6", 6, 0 },
1303 { "pppcom7", 7, 0 },
1304 { "pppcom8", 8, 0 }
1305 #endif /* OS2ONLY */
1306 };
1307 int nos2dev = (sizeof(os2devtab) / sizeof(struct keytab)) - 1;
1308
1309 #ifdef OS2ONLY
1310 struct keytab os2ppptab[] = {
1311 { "0", 0, CM_INV },
1312 { "1", 1, CM_INV }, /* Invisible synonyms, like */
1313 { "2", 2, CM_INV }, /* "set port 1" */
1314 { "3", 3, CM_INV },
1315 { "4", 4, CM_INV },
1316 { "5", 5, CM_INV },
1317 { "6", 6, CM_INV },
1318 { "7", 7, CM_INV },
1319 { "8", 8, CM_INV },
1320 { "9", 9, CM_INV },
1321 { "ppp0", 0, 0 },
1322 { "ppp1", 1, 0 }, /* For use with PPP driver */
1323 { "ppp2", 2, 0 }, /* shared access */
1324 { "ppp3", 3, 0 },
1325 { "ppp4", 4, 0 },
1326 { "ppp5", 5, 0 },
1327 { "ppp6", 6, 0 },
1328 { "ppp7", 7, 0 },
1329 { "ppp8", 8, 0 },
1330 { "ppp9", 9, 0 }
1331 };
1332 int nos2ppp = (sizeof(os2ppptab) / sizeof(struct keytab));
1333 #endif /* OS2ONLY */
1334
1335 /*
1336 Terminal parameters that can be set by SET commands.
1337 Used by the ck?con.c terminal emulator code.
1338 For now, only used for #ifdef OS2. Should add these for Macintosh.
1339 */
1340 int tt_arrow = TTK_NORM; /* Arrow key mode: normal (cursor) */
1341 int tt_keypad = TTK_NORM; /* Keypad mode: normal (numeric) */
1342 int tt_shift_keypad = 0; /* Keypad Shift mode: Off */
1343 int tt_wrap = 1; /* Terminal wrap, 1 = On */
1344 int tt_type = TT_VT220; /* Terminal type, initially VT220 */
1345 int tt_type_mode = TT_VT220; /* Terminal type set by host command */
1346 int tt_cursor = 0; /* Terminal cursor, 0 = Underline */
1347 int tt_cursor_usr = 0; /* Users Terminal cursor type */
1348 int tt_cursorena_usr = 1; /* Users Terminal cursor enabled */
1349 int tt_cursor_blink = 1; /* Terminal Cursor Blink */
1350 int tt_answer = 0; /* Terminal answerback (disabled) */
1351 int tt_scrsize[VNUM] = {512,512,512,1}; /* Terminal scrollback buffer size */
1352 int tt_roll[VNUM] = {1,1,1,1}; /* Terminal roll (on) */
1353 int tt_rkeys[VNUM] = {1,1,1,1}; /* Terminal roll keys (send) */
1354 int tt_pacing = 0; /* Terminal output-pacing (none) */
1355 int tt_ctstmo = 15; /* Terminal transmit-timeout */
1356 int tt_codepage = -1; /* Terminal code-page */
1357 int tt_update = 100; /* Terminal screen-update interval */
1358 int tt_updmode = TTU_FAST; /* Terminal screen-update mode FAST */
1359 extern int updmode;
1360 #ifndef KUI
1361 int tt_status[VNUM] = {1,1,0,0}; /* Terminal status line displayed */
1362 int tt_status_usr[VNUM] = {1,1,0,0};
1363 #else /* KUI */
1364 extern CKFLOAT floatval;
1365 CKFLOAT tt_linespacing[VNUM] = {1.0,1.0,1.0,1.0};
1366 #ifdef K95G
1367 int tt_status[VNUM] = {1,1,0,0}; /* Terminal status line displayed */
1368 int tt_status_usr[VNUM] = {1,1,0,0};
1369 #else /* K95G */
1370 int tt_status[VNUM] = {0,0,0,0}; /* Terminal status line displayed */
1371 int tt_status_usr[VNUM] = {0,0,0,0};
1372 #endif /* K95G */
1373 #endif /* KUI */
1374 int tt_senddata = 0; /* Let host read terminal data */
1375 extern int wy_blockend; /* Terminal Send Data EOB type */
1376 int tt_hidattr = 1; /* Attributes are hidden */
1377
1378 extern unsigned char colornormal, colorselect,
1379 colorunderline, colorstatus, colorhelp, colorborder,
1380 colorgraphic, colordebug, colorreverse, coloritalic;
1381
1382 extern int trueblink, trueunderline, truereverse, trueitalic, truedim;
1383
1384 extern int bgi, fgi;
1385 extern int scrninitialized[];
1386
1387 struct keytab audibletab[] = { /* Terminal Bell Audible mode */
1388 { "beep", XYB_BEEP, 0 }, /* Values ORd with bell mode */
1389 { "system-sounds", XYB_SYS, 0 }
1390 };
1391 int naudibletab = sizeof(audibletab)/sizeof(struct keytab);
1392
1393 struct keytab akmtab[] = { /* Arrow key mode */
1394 { "application", TTK_APPL, 0 },
1395 { "cursor", TTK_NORM, 0 }
1396 };
1397 struct keytab kpmtab[] = { /* Keypad mode */
1398 { "application", TTK_APPL, 0 },
1399 { "numeric", TTK_NORM, 0 }
1400 };
1401
1402 struct keytab ttcolmodetab[] = {
1403 { "current-color", 0, 0 },
1404 { "default-color", 1, 0 }
1405 };
1406 int ncolmode = sizeof(ttcolmodetab)/sizeof(struct keytab);
1407
1408 #define TTCOLNOR 0
1409 #define TTCOLREV 1
1410 #define TTCOLUND 2
1411 #define TTCOLSTA 3
1412 #define TTCOLHLP 4
1413 #define TTCOLBOR 5
1414 #define TTCOLSEL 6
1415 #define TTCOLDEB 7
1416 #define TTCOLGRP 8
1417 #define TTCOLITA 9
1418 #define TTCOLRES 10
1419 #define TTCOLERA 11
1420
1421 struct keytab ttycoltab[] = { /* Terminal Screen coloring */
1422 { "border", TTCOLBOR, 0 }, /* Screen border color */
1423 { "debug-terminal", TTCOLDEB, 0 }, /* Debug color */
1424 { "erase", TTCOLERA, 0 }, /* Erase mode */
1425 { "graphic", TTCOLGRP, 0 }, /* Graphic Color */
1426 { "help-text", TTCOLHLP, 0 }, /* Help screens */
1427 { "italic", TTCOLITA, 0 }, /* Italic Color */
1428 { "normal", TTCOLNOR, CM_INV }, /* Normal screen text */
1429 { "reset-on-esc[0m", TTCOLRES, 0 }, /* Reset on ESC [ 0 m */
1430 { "reverse-video", TTCOLREV, 0 }, /* Reverse video */
1431 { "status-line", TTCOLSTA, 0 }, /* Status line */
1432 { "selection", TTCOLSEL, 0 }, /* Selection color */
1433 { "terminal-screen", TTCOLNOR, 0 }, /* Better name than "normal" */
1434 { "underlined-text", TTCOLUND, 0 } /* Underlined text */
1435 };
1436 int ncolors = (sizeof(ttycoltab) / sizeof(struct keytab));
1437
1438 #define TTATTNOR 0
1439 #define TTATTBLI 1
1440 #define TTATTREV 2
1441 #define TTATTUND 3
1442 #define TTATTPRO 4
1443 #define TTATTBLD 5
1444 #define TTATTDIM 6
1445 #define TTATTINV 7
1446 #define TTATTITA 8
1447 #define TTATTDONE 9
1448
1449 struct keytab ttyattrtab[] = {
1450 { "blink", TTATTBLI, 0 },
1451 { "dim", TTATTDIM, 0 },
1452 { "italic", TTATTITA, 0 },
1453 { "protected", TTATTPRO, 0 },
1454 { "reverse", TTATTREV, 0 },
1455 { "underline", TTATTUND, 0 }
1456 };
1457 int nattrib = (sizeof(ttyattrtab) / sizeof(struct keytab));
1458
1459 struct keytab ttyprotab[] = {
1460 { "blink", TTATTBLI, 0 },
1461 { "bold", TTATTBLD, 0 },
1462 { "dim", TTATTDIM, 0 },
1463 { "done", TTATTDONE, CM_INV },
1464 { "invisible", TTATTINV, 0 },
1465 { "italic", TTATTITA, 0 },
1466 { "normal", TTATTNOR, 0 },
1467 { "reverse", TTATTREV, 0 },
1468 { "underlined", TTATTUND, 0 }
1469
1470 };
1471 int nprotect = (sizeof(ttyprotab) / sizeof(struct keytab));
1472
1473 struct keytab ttyseobtab[] = {
1474 { "crlf_etx", 1, 0 },
1475 { "us_cr", 0, 0 }
1476 };
1477
1478 struct keytab ttyclrtab[] = { /* Colors */
1479 { "black", 0, 0 },
1480 { "blue", 1, 0 },
1481 { "brown", 6, 0 },
1482 { "cyan", 3, 0 },
1483 { "darkgray", 8, CM_INV },
1484 { "dgray", 8, 0 },
1485 { "green", 2, 0 },
1486 { "lblue", 9, CM_INV },
1487 { "lcyan", 11, CM_INV },
1488 { "lgray", 7, CM_INV },
1489 { "lgreen", 10, CM_INV },
1490 { "lightblue", 9, 0 },
1491 { "lightcyan", 11, 0 },
1492 { "lightgray", 7, 0 },
1493 { "lightgreen", 10, 0 },
1494 { "lightmagenta", 13, 0 },
1495 { "lightred", 12, 0 },
1496 { "lmagenta", 13, CM_INV },
1497 { "lred", 12, CM_INV },
1498 { "magenta", 5, 0 },
1499 { "red", 4, 0 },
1500 { "white", 15, 0 },
1501 { "yellow", 14, 0 }
1502 };
1503 int nclrs = (sizeof (ttyclrtab) / sizeof (struct keytab));
1504
1505 struct keytab ttycurtab[] = {
1506 { "full", TTC_BLOCK, 0 },
1507 { "half", TTC_HALF, 0 },
1508 { "underline", TTC_ULINE, 0 }
1509 };
1510 int ncursors = 3;
1511
1512 struct keytab ttyptab[] = {
1513 { "aaa", TT_AAA, CM_INV }, /* AnnArbor */
1514 { "adm3a", TT_ADM3A, 0 }, /* LSI ADM-3A */
1515 { "adm5", TT_ADM5, 0 }, /* LSI ADM-5 */
1516 { "aixterm", TT_AIXTERM, 0 }, /* IBM AIXterm */
1517 { "annarbor", TT_AAA, 0 }, /* AnnArbor */
1518 { "ansi-bbs", TT_ANSI, 0 }, /* ANSI.SYS (BBS) */
1519 { "at386", TT_AT386, 0 }, /* Unixware ANSI */
1520 { "avatar/0+",TT_ANSI, 0 }, /* AVATAR/0+ */
1521 { "ba80", TT_BA80, 0 }, /* Nixdorf BA80 */
1522 { "be", TT_BEOS, CM_INV|CM_ABR },
1523 { "beos-ansi",TT_BEOS, CM_INV }, /* BeOS ANSI */
1524 { "beterm", TT_BEOS, 0 }, /* BeOS Terminal (as of PR2 ) */
1525 { "d200", TT_DG200, CM_INV|CM_ABR }, /* Data General DASHER 200 */
1526 { "d210", TT_DG210, CM_INV|CM_ABR }, /* Data General DASHER 210 */
1527 { "d217", TT_DG217, CM_INV|CM_ABR }, /* Data General DASHER 217 */
1528 { "dg200", TT_DG200, 0 }, /* Data General DASHER 200 */
1529 { "dg210", TT_DG210, 0 }, /* Data General DASHER 210 */
1530 { "dg217", TT_DG217, 0 }, /* Data General DASHER 217 */
1531 { "h1500", TT_HZL1500, CM_INV }, /* Hazeltine 1500 */
1532 { "h19", TT_H19, CM_INV }, /* Heath-19 */
1533 { "heath19", TT_H19, 0 }, /* Heath-19 */
1534 { "hft", TT_HFT, 0 }, /* IBM High Function Terminal */
1535 { "hp2621a", TT_HP2621, 0 }, /* HP 2621A */
1536 { "hpterm", TT_HPTERM, 0 }, /* HP TERM */
1537 { "hz1500", TT_HZL1500, 0 }, /* Hazeltine 1500 */
1538 { "ibm3151", TT_IBM31, 0 }, /* IBM 3101-xx,3161 */
1539 { "linux", TT_LINUX, 0 }, /* Linux */
1540 { "qansi", TT_QANSI, 0 }, /* QNX ANSI */
1541 { "qnx", TT_QNX, 0 }, /* QNX Console */
1542 { "scoansi", TT_SCOANSI, 0 }, /* SCO ANSI */
1543 { "sni-97801",TT_97801, 0 }, /* SNI 97801 */
1544 { "sun", TT_SUN, 0 }, /* SUN Console */
1545 /*
1546 The idea of NONE is to let the console driver handle the escape sequences,
1547 which, in theory at least, would give not only ANSI emulation, but also any
1548 other kind of emulation that might be provided by alternative console
1549 drivers, if any existed.
1550
1551 For this to work, ckocon.c would need to be modified to make higher-level
1552 calls, like VioWrtTTY(), DosWrite(), or (simply) write(), rather than
1553 VioWrt*Cell() and similar, and it would also have to give up its rollback
1554 feature, and its status line and help screens would also have to be
1555 forgotten or else done in an ANSI way.
1556
1557 As matters stand, we already have perfectly good ANSI emulation built in,
1558 and there are no alternative console drivers available, so there is no point
1559 in having a terminal type of NONE, so it is commented out. However, should
1560 you uncomment it, it will work like a "glass tty" -- no escape sequence
1561 interpretation at all; somewhat similar to debug mode, except without the
1562 debugging (no highlighting of control chars or escape sequences); help
1563 screens, status line, and rollback will still work.
1564 */
1565 #ifdef OS2PM
1566 #ifdef COMMENT
1567 { "tek4014", TT_TEK40, 0 },
1568 #endif /* COMMENT */
1569 #endif /* OS2PM */
1570 { "tty", TT_NONE, 0 },
1571 { "tvi910+", TT_TVI910, 0 },
1572 { "tvi925", TT_TVI925, 0 },
1573 { "tvi950", TT_TVI950, 0 },
1574 { "vc404", TT_VC4404, 0 },
1575 { "vc4404", TT_VC4404, CM_INV },
1576 { "vip7809", TT_VIP7809,0 },
1577 { "vt100", TT_VT100, 0 },
1578 { "vt102", TT_VT102, 0 },
1579 { "vt220", TT_VT220, 0 },
1580 { "vt220pc", TT_VT220PC,0 },
1581 { "vt320", TT_VT320, 0 },
1582 { "vt320pc", TT_VT320PC,0 },
1583 { "vt52", TT_VT52, 0 },
1584 #ifdef NT
1585 { "vtnt", TT_VTNT, 0 },
1586 #else /* NT */
1587 { "vtnt", TT_VTNT, CM_INV },
1588 #endif /* NT */
1589 { "wy160", TT_WY160, 0 },
1590 { "wy30", TT_WY30, 0 },
1591 { "wy370", TT_WY370, 0 },
1592 { "wy50", TT_WY50, 0 },
1593 { "wy60", TT_WY60, 0 },
1594 { "wyse30", TT_WY30, CM_INV },
1595 { "wyse370", TT_WY370, CM_INV },
1596 { "wyse50", TT_WY50, CM_INV },
1597 { "wyse60", TT_WY60, CM_INV }
1598 };
1599 int nttyp = (sizeof(ttyptab) / sizeof(struct keytab));
1600
1601 struct keytab ttkeytab[] = {
1602 { "aaa", TT_AAA, CM_INV }, /* AnnArbor */
1603 { "adm3a", TT_ADM3A, 0 }, /* LSI ADM-3A */
1604 { "adm5", TT_ADM5, 0 }, /* LSI ADM-5 */
1605 { "aixterm", TT_AIXTERM, 0 }, /* IBM AIXterm */
1606 { "annarbor", TT_AAA, 0 }, /* AnnArbor */
1607 { "ansi-bbs", TT_ANSI, 0 }, /* ANSI.SYS (BBS) */
1608 { "at386", TT_AT386, 0 }, /* Unixware ANSI */
1609 { "avatar/0+", TT_ANSI, 0 }, /* AVATAR/0+ */
1610 { "ba80", TT_BA80, 0 }, /* Nixdorf BA80 */
1611 { "be", TT_BEOS, CM_INV|CM_ABR },
1612 { "beos-ansi", TT_BEOS, CM_INV }, /* BeOS ANSI */
1613 { "beterm", TT_BEOS, 0 }, /* BeOS Terminal (DR2) */
1614 { "d200", TT_DG200, CM_INV|CM_ABR }, /* DG DASHER 200 */
1615 { "d210", TT_DG210, CM_INV|CM_ABR }, /* DG DASHER 210 */
1616 { "d217", TT_DG217, CM_INV|CM_ABR }, /* DG DASHER 217 */
1617 { "dg200", TT_DG200, 0 }, /* DG DASHER 200 */
1618 { "dg210", TT_DG210, 0 }, /* DG DASHER 210 */
1619 { "dg217", TT_DG217, 0 }, /* DG DASHER 217 */
1620 { "emacs", TT_KBM_EMACS, 0 }, /* Emacs mode */
1621 { "h19", TT_H19, CM_INV }, /* Heath-19 */
1622 { "heath19", TT_H19, 0 }, /* Heath-19 */
1623 { "hebrew", TT_KBM_HEBREW, 0 }, /* Hebrew mode */
1624 { "hft", TT_HFT, 0 }, /* IBM High Function Term */
1625 { "hp2621a", TT_HP2621, 0 }, /* HP 2621A */
1626 { "hpterm", TT_HPTERM, 0 }, /* HP TERM */
1627 { "hz1500", TT_HZL1500, 0 }, /* Hazeltine 1500 */
1628 { "ibm3151", TT_IBM31, 0 }, /* IBM 3101-xx,3161 */
1629 { "linux", TT_LINUX, 0 }, /* Linux */
1630 { "qansi", TT_QANSI, 0 }, /* QNX ANSI */
1631 { "qnx", TT_QNX, 0 }, /* QNX */
1632 { "russian", TT_KBM_RUSSIAN,0 }, /* Russian mode */
1633 { "scoansi", TT_SCOANSI, 0 }, /* SCO ANSI */
1634 { "sni-97801", TT_97801, 0 }, /* SNI 97801 */
1635 { "sun", TT_SUN, 0 }, /* SUN Console */
1636 #ifdef OS2PM
1637 #ifdef COMMENT
1638 { "tek4014", TT_TEK40, 0 },
1639 #endif /* COMMENT */
1640 #endif /* OS2PM */
1641 { "tty", TT_NONE, 0 },
1642 { "tvi910+", TT_TVI910, 0 },
1643 { "tvi925", TT_TVI925, 0 },
1644 { "tvi950", TT_TVI950, 0 },
1645 { "vc404", TT_VC4404, 0 },
1646 { "vc4404", TT_VC4404, CM_INV },
1647 { "vip7809", TT_VIP7809, 0 },
1648 { "vt100", TT_VT100, 0 },
1649 { "vt102", TT_VT102, 0 },
1650 { "vt220", TT_VT220, 0 },
1651 { "vt220pc", TT_VT220PC, 0 },
1652 { "vt320", TT_VT320, 0 },
1653 { "vt320pc", TT_VT320PC, 0 },
1654 { "vt52", TT_VT52, 0 },
1655 { "vtnt", TT_VTNT, CM_INV },
1656 { "wp", TT_KBM_WP, 0 }, /* Word Perfect mode */
1657 { "wy160", TT_WY160, 0 },
1658 { "wy30", TT_WY30, 0 },
1659 { "wy370", TT_WY370, 0 },
1660 { "wy50", TT_WY50, 0 },
1661 { "wy60", TT_WY60, 0 },
1662 { "wyse30", TT_WY30, CM_INV },
1663 { "wyse370", TT_WY370, CM_INV },
1664 { "wyse50", TT_WY50, CM_INV },
1665 { "wyse60", TT_WY60, CM_INV }
1666 };
1667 int nttkey = (sizeof(ttkeytab) / sizeof(struct keytab));
1668
1669 #ifndef NOSETKEY
1670 struct keytab kbmodtab[] = {
1671 { "emacs", KBM_EM, 0 },
1672 { "english", KBM_EN, CM_INV },
1673 { "hebrew", KBM_HE, 0 },
1674 { "normal", KBM_EN, 0 },
1675 { "none", KBM_EN, CM_INV },
1676 { "russian", KBM_RU, 0 },
1677 { "wp", KBM_WP, 0 }
1678 };
1679 int nkbmodtab = (sizeof(kbmodtab) / sizeof(struct keytab));
1680 #endif /* NOSETKEY */
1681 #endif /* NOLOCAL */
1682
1683 int tt_inpacing = 0; /* input-pacing (none) */
1684
1685 struct keytab prtytab[] = { /* OS/2 Priority Levels */
1686 { "foreground-server", XYP_SRV, 0 },
1687 { "idle", XYP_IDLE, CM_INV },
1688 { "regular", XYP_REG, 0 },
1689 { "time-critical", XYP_RTP, 0 }
1690 };
1691 int nprty = (sizeof(prtytab) / sizeof(struct keytab));
1692 #endif /* OS2 */
1693
1694 #ifdef NT
1695 struct keytab win95tab[] = { /* Win95 work-arounds */
1696 { "8.3-filenames", XYW8_3, 0 },
1697 { "alt-gr", XYWAGR, 0 },
1698 { "horizontal-scan-line-substitutions", XYWHSL, 0 },
1699 { "keyboard-translation", XYWKEY, 0 },
1700 { "lucida-substitutions", XYWLUC, 0 },
1701 { "overlapped-io", XYWOIO, 0 },
1702 { "popups", XYWPOPUP, 0 },
1703 { "select-bug", XYWSELECT, 0 }
1704 };
1705 int nwin95 = (sizeof(win95tab) / sizeof(struct keytab));
1706 #endif /* NT */
1707
1708 #ifdef OS2MOUSE
1709 extern int wideresult;
1710 int tt_mouse = 1; /* Terminal mouse on/off */
1711
1712 struct keytab mousetab[] = { /* Mouse items */
1713 { "activate", XYM_ON, 0 },
1714 { "button", XYM_BUTTON, 0 },
1715 { "clear", XYM_CLEAR, 0 },
1716 { "debug", XYM_DEBUG, 0 }
1717 };
1718 int nmtab = (sizeof(mousetab)/sizeof(struct keytab));
1719
1720 struct keytab mousebuttontab[] = { /* event button */
1721 { "1", XYM_B1, 0 },
1722 { "2", XYM_B2, 0 },
1723 { "3", XYM_B3, 0 },
1724 { "one", XYM_B1, CM_INV },
1725 { "three", XYM_B3, CM_INV },
1726 { "two", XYM_B2, CM_INV }
1727 };
1728 int nmbtab = (sizeof(mousebuttontab) / sizeof(struct keytab));
1729
1730 struct keytab mousemodtab[] = { /* event button key modifier */
1731 { "alt", XYM_ALT, 0 },
1732 { "alt-shift", XYM_SHIFT|XYM_ALT, 0 },
1733 { "ctrl", XYM_CTRL, 0 },
1734 { "ctrl-alt", XYM_CTRL|XYM_ALT, 0 },
1735 { "ctrl-alt-shift", XYM_CTRL|XYM_SHIFT|XYM_ALT, 0 },
1736 { "ctrl-shift", XYM_CTRL|XYM_SHIFT, 0 },
1737 { "none", 0, 0 },
1738 { "shift", XYM_SHIFT, 0 }
1739 };
1740 int nmmtab = (sizeof(mousemodtab) / sizeof(struct keytab));
1741
1742 struct keytab mclicktab[] = { /* event button click modifier */
1743 { "click", XYM_C1, 0 },
1744 { "drag", XYM_DRAG, 0 },
1745 { "double-click", XYM_C2, 0 }
1746 };
1747 int nmctab = (sizeof(mclicktab) / sizeof(struct keytab));
1748
1749 #ifndef NOKVERBS
1750 extern int nkverbs;
1751 extern struct keytab kverbs[];
1752 #endif /* NOKVERBS */
1753 #endif /* OS2MOUSE */
1754
1755 /* #ifdef VMS */
1756 struct keytab fbtab[] = { /* Binary record types for VMS */
1757 { "fixed", XYFT_B, 0 }, /* Fixed is normal for binary */
1758 { "undefined", XYFT_U, 0 } /* Undefined if they ask for it */
1759 };
1760 int nfbtyp = (sizeof(fbtab) / sizeof(struct keytab));
1761 /* #endif */
1762
1763 #ifdef VMS
1764 struct keytab lbltab[] = { /* Labeled File info */
1765 { "acl", LBL_ACL, 0 },
1766 { "backup-date", LBL_BCK, 0 },
1767 { "name", LBL_NAM, 0 },
1768 { "owner", LBL_OWN, 0 },
1769 { "path", LBL_PTH, 0 }
1770 };
1771 int nlblp = (sizeof(lbltab) / sizeof(struct keytab));
1772 #else
1773 #ifdef OS2
1774 struct keytab lbltab[] = { /* Labeled File info */
1775 { "archive", LBL_ARC, 0 },
1776 { "extended", LBL_EXT, 0 },
1777 { "hidden", LBL_HID, 0 },
1778 { "read-only", LBL_RO, 0 },
1779 { "system", LBL_SYS, 0 }
1780 };
1781 int nlblp = (sizeof(lbltab) / sizeof(struct keytab));
1782 #endif /* OS2 */
1783 #endif /* VMS */
1784
1785 #ifdef CK_CURSES
1786 #ifdef CK_PCT_BAR
1787 static struct keytab fdftab[] = { /* SET FILE DISPLAY FULL options */
1788 { "thermometer", 1, 0, },
1789 { "no-thermometer", 0, 0 }
1790 };
1791 extern int thermometer;
1792 #endif /* CK_PCT_BAR */
1793 #endif /* CK_CURSES */
1794
1795 static struct keytab fdtab[] = { /* SET FILE DISPLAY options */
1796 #ifdef MAC /* Macintosh */
1797 { "fullscreen", XYFD_R, 0 }, /* Full-screen but not curses */
1798 { "none", XYFD_N, 0 },
1799 { "off", XYFD_N, CM_INV },
1800 { "on", XYFD_R, CM_INV },
1801 { "quiet", XYFD_N, CM_INV },
1802 #else /* Not Mac */
1803 { "brief", XYFD_B, 0 }, /* Brief */
1804 { "crt", XYFD_S, 0 }, /* CRT display */
1805 #ifdef CK_CURSES
1806 #ifdef COMMENT
1807 { "curses", XYFD_C, CM_INV }, /* Full-screen, curses */
1808 #endif /* COMMENT */
1809 { "fullscreen", XYFD_C, 0 }, /* Full-screen, whatever the method */
1810 #endif /* CK_CURSES */
1811 #ifdef KUI
1812 { "gui", XYFD_G, 0 }, /* GUI */
1813 #endif /* KUI */
1814 { "none", XYFD_N, 0 }, /* No display */
1815 { "off", XYFD_N, CM_INV }, /* Ditto */
1816 { "on", XYFD_R, CM_INV }, /* On = Serial */
1817 { "quiet", XYFD_N, CM_INV }, /* No display */
1818 { "serial", XYFD_R, 0 }, /* Serial */
1819 #endif /* MAC */
1820 { "", 0, 0 }
1821 };
1822 int nfdtab = (sizeof(fdtab) / sizeof(struct keytab)) - 1;
1823
1824 struct keytab rsrtab[] = { /* For REMOTE SET RECEIVE */
1825 { "packet-length", XYLEN, 0 },
1826 { "timeout", XYTIMO, 0 }
1827 };
1828 int nrsrtab = (sizeof(rsrtab) / sizeof(struct keytab));
1829
1830 /* Send/Receive Parameters */
1831
1832 struct keytab srtab[] = {
1833 { "backup", XYBUP, 0 },
1834 #ifndef NOCSETS
1835 { "character-set-selection", XYCSET, 0 },
1836 #endif /* NOCSETS */
1837 { "control-prefix", XYQCTL, 0 },
1838 #ifdef CKXXCHAR
1839 { "double-character", XYDBL, 0 },
1840 #endif /* CKXXCHAR */
1841 { "end-of-packet", XYEOL, 0 },
1842 #ifdef PIPESEND
1843 { "filter", XYFLTR, 0 },
1844 #endif /* PIPESEND */
1845 #ifdef CKXXCHAR
1846 { "ignore-character", XYIGN, 0 },
1847 #endif /* CKXXCHAR */
1848 { "i-packets", 993, 0 },
1849 { "move-to", XYMOVE, 0 },
1850 { "negotiation-string-max-length", XYINIL, CM_INV },
1851 { "packet-length", XYLEN, 0 },
1852 { "pad-character", XYPADC, 0 },
1853 { "padding", XYNPAD, 0 },
1854 { "pathnames", XYFPATH, 0 },
1855 { "pause", XYPAUS, 0 },
1856 #ifdef CK_PERMS
1857 { "permissions", 994, 0}, /* 206 */
1858 #endif /* CK_PERMS */
1859 { "quote", XYQCTL, CM_INV }, /* = CONTROL-PREFIX */
1860 { "rename-to", XYRENAME, 0 },
1861 { "start-of-packet", XYMARK, 0 },
1862 { "timeout", XYTIMO, 0 },
1863 #ifdef VMS
1864 { "version-numbers", 887, 0 }, /* VMS version numbers */
1865 #endif /* VMS */
1866 { "", 0, 0 }
1867 };
1868 int nsrtab = (sizeof(srtab) / sizeof(struct keytab)) - 1;
1869
1870 #ifdef UNICODE
1871 #define UCS_BOM 1
1872 #define UCS_BYT 2
1873 static struct keytab ucstab[] = {
1874 { "bom", UCS_BOM, 0 },
1875 { "byte-order", UCS_BYT, 0 },
1876 { "", 0, 0 }
1877 };
1878 int nucstab = (sizeof(ucstab) / sizeof(struct keytab)) - 1;
1879
1880 static struct keytab botab[] = {
1881 { "big-endian", 0, 0 },
1882 { "little-endian", 1, 0 }
1883 };
1884 static int nbotab = 2;
1885 #endif /* UNICODE */
1886
1887 /* REMOTE SET */
1888
1889 struct keytab rmstab[] = {
1890 { "attributes", XYATTR, 0 },
1891 { "block-check", XYCHKT, 0 },
1892 { "file", XYFILE, 0 },
1893 { "incomplete", XYIFD, CM_INV }, /* = REMOTE SET FILE INCOMPLETE */
1894 { "match", XYMATCH,0 },
1895 { "receive", XYRECV, 0 },
1896 { "retry", XYRETR, 0 },
1897 { "server", XYSERV, 0 },
1898 { "transfer", XYXFER, 0 },
1899 { "window", XYWIND, 0 },
1900 { "xfer", XYXFER, CM_INV }
1901 };
1902 int nrms = (sizeof(rmstab) / sizeof(struct keytab));
1903
1904 struct keytab attrtab[] = {
1905 #ifdef STRATUS
1906 { "account", AT_ACCT, 0 },
1907 #endif /* STRATUS */
1908 { "all", AT_XALL, 0 },
1909 #ifdef COMMENT
1910 { "blocksize", AT_BLKS, 0 }, /* (not used) */
1911 #endif /* COMMENT */
1912 #ifndef NOCSETS
1913 { "character-set", AT_ENCO, 0 },
1914 #endif /* NOCSETS */
1915 #ifdef STRATUS
1916 { "creator", AT_CREA, 0 },
1917 #endif /* STRATUS */
1918 { "date", AT_DATE, 0 },
1919 { "disposition", AT_DISP, 0 },
1920 { "encoding", AT_ENCO, CM_INV },
1921 { "format", AT_RECF, CM_INV },
1922 { "length", AT_LENK, 0 },
1923 { "off", AT_ALLN, 0 },
1924 { "on", AT_ALLY, 0 },
1925 #ifdef COMMENT
1926 { "os-specific", AT_SYSP, 0 }, /* (not used by UNIX or VMS) */
1927 #endif /* COMMENT */
1928 #ifdef CK_PERMS
1929 { "protection", AT_LPRO, 0 },
1930 { "permissions", AT_LPRO, CM_INV },
1931 #endif /* CK_PERMS */
1932 { "record-format", AT_RECF, 0 },
1933 { "system-id", AT_SYSI, 0 },
1934 { "type", AT_FTYP, 0 }
1935 };
1936 int natr = (sizeof(attrtab) / sizeof(struct keytab)); /* how many attributes */
1937
1938 #ifdef CKTIDLE
1939 struct keytab idlacts[] = {
1940 { "exit", IDLE_EXIT, 0 },
1941 { "hangup", IDLE_HANG, 0 },
1942 { "output", IDLE_OUT, 0 },
1943 { "return", IDLE_RET, 0 },
1944 #ifdef TNCODE
1945 { "telnet-nop", IDLE_TNOP, 0 },
1946 { "telnet-ayt", IDLE_TAYT, 0 },
1947 #endif /* TNCODE */
1948 { "", 0, 0 }
1949 };
1950 int nidlacts = (sizeof(idlacts) / sizeof(struct keytab)) - 1;
1951 #endif /* CKTIDLE */
1952
1953 #ifndef NOSPL
1954 extern int indef, inecho, insilence, inbufsize, inautodl, inintr;
1955 #ifdef CKFLOAT
1956 extern CKFLOAT inscale;
1957 #endif /* CKFLOAT */
1958 extern char * inpbuf, * inpbp;
1959 #ifdef OS2
1960 extern int interm;
1961 #endif /* OS2 */
1962 struct keytab inptab[] = { /* SET INPUT parameters */
1963 #ifdef CK_AUTODL
1964 { "autodownload", IN_ADL, 0 },
1965 #endif /* CK_AUTODL */
1966 { "buffer-length", IN_BUF, 0 },
1967 { "cancellation", IN_CAN, 0 },
1968 { "case", IN_CAS, 0 },
1969 { "default-timeout", IN_DEF, CM_INV }, /* There is no default timeout */
1970 { "echo", IN_ECH, 0 },
1971 #ifdef OS2
1972 { "pacing", IN_PAC, CM_INV },
1973 #endif /* OS2 */
1974 { "scale-factor", IN_SCA, 0 },
1975 { "silence", IN_SIL, 0 },
1976 #ifdef OS2
1977 { "terminal", IN_TRM, 0 },
1978 #endif /* OS2 */
1979 { "timeout-action", IN_TIM, 0 }
1980 };
1981 int ninp = (sizeof(inptab) / sizeof(struct keytab));
1982
1983 struct keytab intimt[] = { /* SET INPUT TIMEOUT parameters */
1984 { "proceed", 0, 0 }, /* 0 = proceed */
1985 { "quit", 1, 0 } /* 1 = quit */
1986 };
1987
1988 struct keytab incast[] = { /* SET INPUT CASE parameters */
1989 { "ignore", 0, 0 }, /* 0 = ignore */
1990 { "observe", 1, 0 } /* 1 = observe */
1991 };
1992 #endif /* NOSPL */
1993
1994 struct keytab nabltab[] = { /* For any command that needs */
1995 { "disabled", 0, 0 },
1996 { "enabled", 1, 0 },
1997 { "off", 0, CM_INV }, /* these keywords... */
1998 { "on", 1, CM_INV }
1999 };
2000 int nnabltab = sizeof(nabltab) / sizeof(struct keytab);
2001
2002 #ifdef OS2
2003 struct keytab tvctab[] = { /* SET TERM VIDEO-CHANGE */
2004 { "disabled", TVC_DIS, 0 },
2005 { "enabled", TVC_ENA, 0 },
2006 #ifdef NT
2007 { "win95-safe", TVC_W95, 0 },
2008 #endif /* NT */
2009 { "", 0, 0 }
2010 };
2011 int ntvctab = (sizeof(tvctab) / sizeof(struct keytab)) - 1;
2012
2013 struct keytab msktab[] = { /* SET MS-DOS KERMIT compatibilities */
2014 #ifdef COMMENT
2015 { "color", MSK_COLOR, 0 },
2016 #endif /* COMMENT */
2017 { "file-renaming", MSK_REN, 0 },
2018 { "keycodes", MSK_KEYS, 0 }
2019 };
2020 int nmsk = (sizeof(msktab) / sizeof(struct keytab));
2021
2022 struct keytab scrnupd[] = { /* SET TERMINAL SCREEN-UPDATE */
2023 { "fast", TTU_FAST, 0 },
2024 { "smooth", TTU_SMOOTH, 0 }
2025 };
2026 int nscrnupd = (sizeof(scrnupd) / sizeof(struct keytab));
2027
2028 #ifdef PCFONTS
2029 /* This definition of the term_font[] table is only for */
2030 /* the OS/2 Full Screen Session and is not used on Windows */
2031 struct keytab term_font[] = { /* SET TERMINAL FONT */
2032 #ifdef COMMENT
2033 { "cp111", TTF_111, 0 },
2034 { "cp112", TTF_112, 0 },
2035 { "cp113", TTF_113, 0 },
2036 #endif /* COMMENT */
2037 { "cp437", TTF_437, 0 },
2038 { "cp850", TTF_850, 0 },
2039 #ifdef COMMENT
2040 { "cp851", TTF_851, 0 },
2041 #endif /* COMMENT */
2042 { "cp852", TTF_852, 0 },
2043 #ifdef COMMENT
2044 { "cp853", TTF_853, 0 },
2045 { "cp860", TTF_860, 0 },
2046 { "cp861", TTF_861, 0 },
2047 #endif /* COMMENT */
2048 { "cp862", TTF_862, 0 },
2049 #ifdef COMMENT
2050 { "cp863", TTF_863, 0 },
2051 { "cp864", TTF_864, 0 },
2052 { "cp865", TTF_865, 0 },
2053 #endif /* COMMENT */
2054 { "cp866", TTF_866, 0 },
2055 #ifdef COMMENT
2056 { "cp880", TTF_880, 0 },
2057 { "cp881", TTF_881, 0 },
2058 { "cp882", TTF_882, 0 },
2059 { "cp883", TTF_883, 0 },
2060 { "cp884", TTF_884, 0 },
2061 { "cp885", TTF_885, 0 },
2062 #endif /* COMMENT */
2063 { "default",TTF_ROM,0 }
2064 };
2065 int ntermfont = (sizeof(term_font) / sizeof(struct keytab));
2066 int tt_font = TTF_ROM; /* Terminal screen font */
2067 #else /* PCFONTS */
2068 #ifdef NT
2069 #ifdef KUI
2070 struct keytab * term_font = NULL;
2071 struct keytab * _term_font = NULL;
2072 char * tt_facename = NULL;
2073 int ntermfont = 0;
2074 int tt_font = 0;
2075 int tt_font_size = 0;
2076 #endif /* KUI */
2077 #endif /* NT */
2078 #endif /* PCFONTS */
2079
2080 struct keytab anbktab[] = { /* For any command that needs */
2081 { "message", 2, 0 }, /* these keywords... */
2082 { "off", 0, 0 },
2083 { "on", 1, 0 },
2084 { "unsafe-messag0", 99, CM_INV },
2085 { "unsafe-message", 3, CM_INV }
2086 };
2087 int nansbk = (sizeof(anbktab) / sizeof(struct keytab));
2088
2089 int win95_popup = 1;
2090 #ifdef NT
2091 #ifdef KUI
2092 int win95lucida = 0;
2093 int win95hsl = 1;
2094 #else /* KUI */
2095 int win95lucida = 1;
2096 int win95hsl = 1;
2097 #endif /* KUI */
2098 #else /* NT */
2099 int win95lucida = 0;
2100 int win95hsl = 1;
2101 #endif /* NT */
2102 #ifdef NT
2103 int win95altgr = 0;
2104 extern int win95selectbug;
2105 extern int win95_8_3;
2106
2107 #ifdef COMMENT
2108 extern CHAR (*xlr[MAXTCSETS+1][MAXFCSETS+1])(CHAR);
2109 extern struct keytab tcstab[];
2110 extern int ntcs;
2111 #endif /* COMMENT */
2112 extern int maxow, maxow_usr; owwait; /* Overlapped I/O variables */
2113 #endif /* NT */
2114 #endif /* OS2 */
2115
2116
2117 /* The following routines broken out of doprm() to give compilers a break. */
2118
2119 /* S E T O N -- Parse on/off (default on), set parameter to result */
2120
2121 int
seton(prm)2122 seton(prm) int *prm; {
2123 int x, y;
2124 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
2125 if ((x = cmcfm()) < 0) return(x);
2126 *prm = y;
2127 return(1);
2128 }
2129
2130 /* S E T O N A U T O -- Parse on/off/auto (default auto) & set result */
2131
2132 struct keytab onoffaut[] = {
2133 { "auto", SET_AUTO, 0 }, /* 2 */
2134 { "off", SET_OFF, 0 }, /* 0 */
2135 { "on", SET_ON, 0 } /* 1 */
2136 };
2137
2138 int
setonaut(prm)2139 setonaut(prm) int *prm; {
2140 int x, y;
2141 if ((y = cmkey(onoffaut,3,"","auto",xxstring)) < 0) return(y);
2142 if ((x = cmcfm()) < 0) return(x);
2143 *prm = y;
2144 return(1);
2145 }
2146
2147 /* S E T N U M -- Set parameter to result of cmnum() parse. */
2148 /*
2149 Call with pointer to integer variable to be set,
2150 x = number from cnum parse, y = return code from cmnum,
2151 max = maximum value to accept, -1 if no maximum.
2152 Returns -9 on failure, after printing a message, or 1 on success.
2153 */
2154 int
setnum(prm,x,y,max)2155 setnum(prm,x,y,max) int x, y, *prm, max; {
2156 debug(F101,"setnum","",y);
2157 if (y == -3) {
2158 printf("\n?Value required\n");
2159 return(-9);
2160 }
2161 if (y == -2) {
2162 printf("%s?Not a number: %s\n",cmflgs == 1 ? "" : "\n", atxbuf);
2163 return(-9);
2164 }
2165 if (y < 0) return(y);
2166 if (max > -1 && x > max) {
2167 printf("?Sorry, %d is the maximum\n",max);
2168 return(-9);
2169 }
2170 if ((y = cmcfm()) < 0) return(y);
2171 *prm = x;
2172 return(1);
2173 }
2174
2175 /* S E T C C -- Set parameter var to an ASCII control character value. */
2176 /*
2177 Parses a number, or a literal control character, or a caret (^) followed
2178 by an ASCII character whose value is 63-95 or 97-122, then gets confirmation,
2179 then sets the parameter to the code value of the character given. If there
2180 are any parse errors, they are returned, otherwise on success 1 is returned.
2181 */
2182 int
setcc(dflt,var)2183 setcc(dflt,var) char *dflt; int *var; {
2184 int x, y;
2185 unsigned int c;
2186 char *hlpmsg = "Control character,\n\
2187 numeric ASCII value,\n\
2188 or in ^X notation,\n\
2189 or preceded by a backslash and entered literally";
2190
2191 /* This is a hack to turn off complaints from expression evaluator. */
2192 x_ifnum = 1;
2193 y = cmnum(hlpmsg, dflt, 10, &x, xxstring); /* Parse a number */
2194 x_ifnum = 0; /* Allow complaints again */
2195 if (y < 0) { /* Parse failed */
2196 if (y != -2) /* Reparse needed or somesuch */
2197 return(y); /* Pass failure back up the chain */
2198 }
2199 /* Real control character or literal 8-bit character... */
2200
2201 for (c = strlen(atmbuf) - 1; c > 0; c--) /* Trim */
2202 if (atmbuf[c] == SP) atmbuf[c] = NUL;
2203
2204 if (y < 0) { /* It was not a number */
2205 if (((c = atmbuf[0])) && !atmbuf[1]) { /* Literal character? */
2206 c &= 0xff;
2207 if (((c > 31) && (c < 127)) || (c > 255)) {
2208 printf("\n?%d: Out of range - must be 0-31 or 127-255\n",c);
2209 return(-9);
2210 } else {
2211 if ((y = cmcfm()) < 0) /* Confirm */
2212 return(y);
2213 *var = c; /* Set the variable */
2214 return(1);
2215 }
2216 } else if (atmbuf[0] == '^' && !atmbuf[2]) { /* Or ^X notation? */
2217 c = atmbuf[1];
2218 if (islower((char) c)) /* Uppercase lowercase letters */
2219 c = toupper(c);
2220 if (c > 62 && c < 96) { /* Check range */
2221 if ((y = cmcfm()) < 0)
2222 return(y);
2223 *var = ctl(c); /* OK */
2224 return(1);
2225 } else {
2226 printf("?Not a control character - %s\n", atmbuf);
2227 return(-9);
2228 }
2229 } else { /* Something illegal was typed */
2230 printf("?Not valid here - '%s'\n", atmbuf);
2231 return(-9);
2232 }
2233 }
2234 if (((x > 31) && (x < 127)) || (x > 255)) { /* They typed a number */
2235 printf("\n?%d: Out of range - must be 0-31 or 127-255\n",x);
2236 return(-9);
2237 }
2238 if ((y = cmcfm()) < 0) /* In range, confirm */
2239 return(y);
2240 *var = x; /* Set variable */
2241 return(1);
2242 }
2243
2244 #ifndef NOSPL /* The SORT command... */
2245
2246 static struct keytab srtswtab[] = { /* SORT command switches */
2247 { "/case", SRT_CAS, CM_ARG },
2248 { "/key", SRT_KEY, CM_ARG },
2249 { "/numeric", SRT_NUM, 0 },
2250 { "/range", SRT_RNG, CM_ARG },
2251 { "/reverse", SRT_REV, 0 }
2252 };
2253 static int nsrtswtab = sizeof(srtswtab)/sizeof(struct keytab);
2254
2255 extern char **a_ptr[]; /* Array pointers */
2256 extern int a_dim[]; /* Array dimensions */
2257
2258 int
dosort()2259 dosort() { /* Do the SORT command */
2260 char c, *p = NULL, ** ap, ** xp = NULL;
2261 struct FDB sw, fl, cm;
2262 int hi, lo;
2263 int xn = 0, xr = -1, xk = -1, xc = -1, xs = 0;
2264 int getval = 0, range[2], confirmed = 0;
2265
2266 cmfdbi(&sw, /* First FDB - command switches */
2267 _CMKEY, /* fcode */
2268 "Array name or switch",
2269 "", /* default */
2270 "", /* addtl string data */
2271 nsrtswtab, /* addtl numeric data 1: tbl size */
2272 4, /* addtl numeric data 2: 4 = cmswi */
2273 NULL, /* Processing function */
2274 srtswtab, /* Keyword table */
2275 &fl /* Pointer to next FDB */
2276 );
2277 cmfdbi(&fl, /* Anything that doesn't match */
2278 _CMFLD, /* fcode */
2279 "Array name", /* hlpmsg */
2280 "", /* default */
2281 "", /* addtl string data */
2282 0, /* addtl numeric data 1 */
2283 0, /* addtl numeric data 2 */
2284 NULL,
2285 NULL,
2286 &cm
2287 );
2288 cmfdbi(&cm, /* Or premature confirmation */
2289 _CMCFM, /* fcode */
2290 "", /* hlpmsg */
2291 "", /* default */
2292 "", /* addtl string data */
2293 0, /* addtl numeric data 1 */
2294 0, /* addtl numeric data 2 */
2295 NULL,
2296 NULL,
2297 NULL
2298 );
2299
2300 range[0] = -1;
2301 range[1] = -1;
2302
2303 while (1) { /* Parse 0 or more switches */
2304 x = cmfdb(&sw);
2305 if (x < 0)
2306 return(x);
2307 if (cmresult.fcode != _CMKEY) /* Break out if not a switch */
2308 break;
2309 c = cmgbrk();
2310 getval = (c == ':' || c == '=');
2311 if (getval && !(cmresult.kflags & CM_ARG)) {
2312 printf("?This switch does not take arguments\n");
2313 return(-9);
2314 }
2315 switch (cmresult.nresult) {
2316 case SRT_REV:
2317 xr = 1;
2318 break;
2319 case SRT_KEY:
2320 if (getval) {
2321 if ((y = cmnum("Column for comparison (1-based)",
2322 "1",10,&x,xxstring)) < 0)
2323 return(y);
2324 xk = x - 1;
2325 } else
2326 xk = 0;
2327 break;
2328 case SRT_CAS:
2329 if (getval) {
2330 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0)
2331 return(y);
2332 xc = y;
2333 } else
2334 xc = 1;
2335 break;
2336 case SRT_RNG: /* /RANGE */
2337 if (getval) {
2338 char buf[32];
2339 char buf2[16];
2340 int i;
2341 char * p, * q;
2342 if ((y = cmfld("low:high element","1",&s,NULL)) < 0)
2343 return(y);
2344 s = brstrip(s);
2345 ckstrncpy(buf,s,32);
2346 p = buf;
2347 for (i = 0; *p && i < 2; i++) { /* Get low and high */
2348 q = p; /* Start of this piece */
2349 while (*p) { /* Find end of this piece */
2350 if (*p == ':') {
2351 *p = NUL;
2352 p++;
2353 break;
2354 }
2355 p++;
2356 }
2357 y = 15; /* Evaluate this piece */
2358 s = buf2;
2359 zzstring(q,&s,&y);
2360 s = evalx(buf2);
2361 if (s) if (*s) ckstrncpy(buf2,s,16);
2362 if (!rdigits(buf2)) {
2363 printf("?Not numeric: %s\n",buf2);
2364 return(-9);
2365 }
2366 range[i] = atoi(buf2);
2367 }
2368 }
2369 break;
2370 case SRT_NUM: /* /NUMERIC */
2371 xn = 1;
2372 break;
2373 default:
2374 return(-2);
2375 }
2376 }
2377 switch (cmresult.fcode) {
2378 case _CMCFM:
2379 confirmed = 1;
2380 break;
2381 case _CMFLD:
2382 ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Safe copy of name */
2383 s = line;
2384 break;
2385 default:
2386 printf("?Unexpected function code: %d\n",cmresult.fcode);
2387 return(-9);
2388 }
2389 if (confirmed) {
2390 printf("?Array name required\n");
2391 return(-9);
2392 }
2393 ckmakmsg(tmpbuf,TMPBUFSIZ,
2394 "Second array to sort according to ",s,NULL,NULL);
2395 if ((x = cmfld(tmpbuf,"",&p,NULL)) < 0)
2396 if (x != -3)
2397 return(x);
2398 tmpbuf[0] = NUL;
2399 ckstrncpy(tmpbuf,p,TMPBUFSIZ);
2400 p = tmpbuf;
2401 if ((x = cmcfm()) < 0) /* Get confirmation */
2402 return(x);
2403
2404 x = arraybounds(s,&lo,&hi); /* Get array index & bounds */
2405 if (x < 0) { /* Check */
2406 printf("?Bad array name: %s\n",s);
2407 return(-9);
2408 }
2409 if (lo > -1) range[0] = lo; /* Set range */
2410 if (hi > -1) range[1] = hi;
2411 ap = a_ptr[x]; /* Get pointer to array element list */
2412 if (!ap) { /* Check */
2413 printf("?Array not declared: %s\n", s);
2414 return(-9);
2415 }
2416 if (range[0] < 0) /* Starting element */
2417 range[0] = 1;
2418 if (range[1] < 0) /* Final element */
2419 range[1] = a_dim[x];
2420 if (range[1] > a_dim[x]) {
2421 printf("?range %d:%d exceeds array dimension %d\n",
2422 range[0],range[1],a_dim[x]
2423 );
2424 return(-9);
2425 }
2426 ap += range[0];
2427 xs = range[1] - range[0] + 1; /* Number of elements to sort */
2428 if (xs < 1) { /* Check */
2429 printf("?Bad range: %d:%d\n",range[0],range[1]);
2430 return(-9);
2431 }
2432 if (xk < 0) xk = 0; /* Key position */
2433 if (xr < 0) xr = 0; /* Reverse flag */
2434 if (xn) /* Numeric flag */
2435 xc = 2;
2436 else if (xc < 0) /* Not numeric */
2437 xc = inpcas[cmdlvl]; /* so alpha case option */
2438
2439 if (*p) { /* Parallel array given? */
2440 y = xarray(p); /* Yes, get its index. */
2441 if (y < 0) {
2442 printf("?Bad array name: %s\n", p);
2443 return(-9);
2444 }
2445 if (y != x) { /* If the 2 arrays are different */
2446 xp = a_ptr[y]; /* Pointer to 2nd array element list */
2447 if (!xp) {
2448 printf("?Array not declared: %s\n", p);
2449 return(-9);
2450 }
2451 if (a_dim[y] < range[1]) {
2452 printf("?Array %s smaller than %s\n", p, s);
2453 return(-9);
2454 }
2455 xp += range[0]; /* Set base to same as 1st array */
2456 }
2457 }
2458 sh_sort(ap,xp,xs,xk,xr,xc); /* Sort the array(s) */
2459 return(success = 1); /* Always succeeds */
2460 }
2461 #endif /* NOSPL */
2462
2463 static struct keytab purgtab[] = { /* PURGE command switches */
2464 { "/after", PU_AFT, CM_ARG },
2465 { "/ask", PU_ASK, 0 },
2466 { "/before", PU_BEF, CM_ARG },
2467 { "/delete", PU_DELE, CM_INV },
2468 #ifdef UNIXOROSK
2469 { "/dotfiles", PU_DOT, 0 },
2470 #endif /* UNIXOROSK */
2471 { "/except", PU_EXC, CM_ARG },
2472 { "/heading", PU_HDG, 0 },
2473 { "/keep", PU_KEEP, CM_ARG },
2474 { "/larger-than", PU_LAR, CM_ARG },
2475 { "/list", PU_LIST, 0 },
2476 { "/log", PU_LIST, CM_INV },
2477 { "/noask", PU_NASK, 0 },
2478 { "/nodelete", PU_NODE, CM_INV },
2479 #ifdef UNIXOROSK
2480 { "/nodotfiles", PU_NODOT,0 },
2481 #endif /* UNIXOROSK */
2482 { "/noheading", PU_NOH, 0 },
2483 { "/nol", PU_NOLI, CM_INV|CM_ABR },
2484 { "/nolist", PU_NOLI, 0 },
2485 { "/nolog", PU_NOLI, CM_INV },
2486 #ifdef CK_TTGWSIZ
2487 { "/nopage", PU_NOPA, 0 },
2488 #endif /* CK_TTGWSIZ */
2489 { "/not-after", PU_NAF, CM_ARG },
2490 { "/not-before", PU_NBF, CM_ARG },
2491 { "/not-since", PU_NAF, CM_INV|CM_ARG },
2492 #ifdef CK_TTGWSIZ
2493 { "/page", PU_PAGE, 0 },
2494 #endif /* CK_TTGWSIZ */
2495 { "/quiet", PU_QUIE, CM_INV },
2496 #ifdef RECURSIVE
2497 { "/recursive", PU_RECU, 0 },
2498 #endif /* RECURSIVE */
2499 { "/since", PU_AFT, CM_ARG|CM_INV },
2500 { "/simulate", PU_NODE, 0 },
2501 { "/smaller-than", PU_SMA, CM_ARG },
2502 { "/verbose", PU_VERB, CM_INV }
2503 };
2504 static int npurgtab = sizeof(purgtab)/sizeof(struct keytab);
2505
2506
2507
2508
2509
2510 int
bkupnum(s,i)2511 bkupnum(s,i) char * s; int *i; {
2512 int k = 0, pos = 0;
2513 char * p = NULL, *q;
2514 *i = pos;
2515 if (!s) s = "";
2516 if (!*s)
2517 return(-1);
2518 if ((k = strlen(s)) < 5)
2519 return(-1);
2520
2521 if (s[k-1] != '~')
2522 return(-1);
2523 pos = k - 2;
2524 q = s + pos;
2525 while (q >= s && isdigit(*q)) {
2526 p = q--;
2527 pos--;
2528 }
2529 if (!p)
2530 return(-1);
2531 if (q < s+2)
2532 return(-1);
2533 if (*q != '~' || *(q-1) != '.')
2534 return(-1);
2535 pos--;
2536 *i = pos;
2537 debug(F111,"bkupnum",s+pos,pos);
2538 return(atoi(p));
2539 }
2540
2541 #ifdef CKPURGE
2542 /* Presently only for UNIX because we need direct access to the file array. */
2543 /* Not needed for VMS anyway, because we don't make backup files there. */
2544
2545 #define MAXKEEP 32 /* Biggest /KEEP: value */
2546
2547 static int
2548 pu_keep = 0, pu_list = 0, pu_dot = 0, pu_ask = 0, pu_hdg = 0;
2549
2550 #ifdef CK_TTGWSIZ
2551 static int pu_page = -1;
2552 #else
2553 static int pu_page = 0;
2554 #endif /* CK_TTGWSIZ */
2555
2556 #ifndef NOSHOW
2557 VOID
showpurgopts()2558 showpurgopts() { /* SHOW PURGE command options */
2559 int x = 0;
2560 extern int optlines;
2561 prtopt(&optlines,"PURGE");
2562 if (pu_ask > -1) {
2563 x++;
2564 prtopt(&optlines, pu_ask ? "/ASK" : "/NOASK");
2565 }
2566 #ifdef UNIXOROSK
2567 if (pu_dot > -1) {
2568 x++;
2569 prtopt(&optlines, pu_dot ? "/DOTFILES" : "/NODOTFILES");
2570 }
2571 #endif /* UNIXOROSK */
2572 if (pu_keep > -1) {
2573 x++;
2574 ckmakmsg(tmpbuf,TMPBUFSIZ,"/KEEP:",ckitoa(pu_keep),NULL,NULL);
2575 prtopt(&optlines,tmpbuf);
2576 }
2577 if (pu_list > -1) {
2578 x++;
2579 prtopt(&optlines, pu_list ? "/LIST" : "/NOLIST");
2580 }
2581 if (pu_hdg > -1) {
2582 x++;
2583 prtopt(&optlines, pu_hdg ? "/HEADING" : "/NOHEADING");
2584 }
2585 #ifdef CK_TTGWSIZ
2586 if (pu_page > -1) {
2587 x++;
2588 prtopt(&optlines, pu_page ? "/PAGE" : "/NOPAGE");
2589 }
2590 #endif /* CK_TTGWSIZ */
2591 if (!x) prtopt(&optlines,"(no options set)");
2592 prtopt(&optlines,"");
2593 }
2594 #endif /* NOSHOW */
2595
2596 int
setpurgopts()2597 setpurgopts() { /* Set PURGE command options */
2598 int c, z, getval = 0;
2599 int
2600 x_keep = -1, x_list = -1, x_page = -1,
2601 x_hdg = -1, x_ask = -1, x_dot = -1;
2602
2603 while (1) {
2604 if ((y = cmswi(purgtab,npurgtab,"Switch","",xxstring)) < 0) {
2605 if (y == -3)
2606 break;
2607 else
2608 return(y);
2609 }
2610 c = cmgbrk();
2611 if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
2612 printf("?This switch does not take an argument\n");
2613 return(-9);
2614 }
2615 if (!getval && (cmgkwflgs() & CM_ARG)) {
2616 printf("?This switch requires an argument\n");
2617 return(-9);
2618 }
2619 switch (y) {
2620 case PU_KEEP:
2621 z = 1;
2622 if (c == ':' || c == '=')
2623 if ((y = cmnum("How many backup files to keep",
2624 "1",10,&z,xxstring)) < 0)
2625 return(y);
2626 if (z < 0 || z > MAXKEEP) {
2627 printf("?Please specify a number between 0 and %d\n",
2628 MAXKEEP
2629 );
2630 return(-9);
2631 }
2632 x_keep = z;
2633 break;
2634 case PU_LIST:
2635 case PU_VERB:
2636 x_list = 1;
2637 break;
2638 case PU_QUIE:
2639 case PU_NOLI:
2640 x_list = 0;
2641 break;
2642 #ifdef CK_TTGWSIZ
2643 case PU_PAGE:
2644 x_page = 1;
2645 break;
2646 case PU_NOPA:
2647 x_page = 0;
2648 break;
2649 #endif /* CK_TTGWSIZ */
2650 case PU_HDG:
2651 x_hdg = 1;
2652 break;
2653 case PU_NOH:
2654 x_hdg = 0;
2655 break;
2656 case PU_ASK:
2657 x_ask = 1;
2658 break;
2659 case PU_NASK:
2660 x_ask = 0;
2661 break;
2662 #ifdef UNIXOROSK
2663 case PU_DOT:
2664 x_dot = 1;
2665 break;
2666 case PU_NODOT:
2667 x_dot = 0;
2668 break;
2669 #endif /* UNIXOROSK */
2670 default:
2671 printf("?This option can not be set\n");
2672 return(-9);
2673 }
2674 }
2675 if ((x = cmcfm()) < 0) /* Get confirmation */
2676 return(x);
2677 if (x_keep > -1) /* Set PURGE defaults. */
2678 pu_keep = x_keep;
2679 if (x_list > -1)
2680 pu_list = x_list;
2681 #ifdef CK_TTGWSIZ
2682 if (x_page > -1)
2683 pu_page = x_page;
2684 #endif /* CK_TTGWSIZ */
2685 if (x_hdg > -1)
2686 pu_hdg = x_hdg;
2687 if (x_ask > -1)
2688 pu_ask = x_ask;
2689 if (x_dot > -1)
2690 pu_dot = x_dot;
2691 return(success = 1);
2692 }
2693
2694 int
dopurge()2695 dopurge() { /* Do the PURGE command */
2696 extern char ** mtchs;
2697 extern int xaskmore, cmd_rows, recursive;
2698 int simulate = 0, asking = 0;
2699 int listing = 0, paging = -1, lines = 0, deleting = 1, errors = 0;
2700 struct FDB sw, sf, cm;
2701 int g, i, j, k, m = 0, n, x, y, z, done = 0, count = 0, flags = 0;
2702 int tokeep = 0, getval = 0, havename = 0, confirmed = 0;
2703 int xx[MAXKEEP+1]; /* Array of numbers to keep */
2704 int min = -1;
2705 int x_hdg = 0, fs = 0, rc = 0;
2706 CK_OFF_T minsize = -1L, maxsize = -1L;
2707 char namebuf[CKMAXPATH+4];
2708 char basebuf[CKMAXPATH+4];
2709 char
2710 * pu_aft = NULL,
2711 * pu_bef = NULL,
2712 * pu_naf = NULL,
2713 * pu_nbf = NULL,
2714 * pu_exc = NULL;
2715 char * pxlist[8]; /* Exception list */
2716
2717 if (pu_keep > -1) /* Set PURGE defaults. */
2718 tokeep = pu_keep;
2719 if (pu_list > -1)
2720 listing = pu_list;
2721 #ifdef CK_TTGWSIZ
2722 if (pu_page > -1)
2723 paging = pu_page;
2724 #endif /* CK_TTGWSIZ */
2725
2726 for (i = 0; i <= MAXKEEP; i++) /* Clear this number buffer */
2727 xx[i] = 0;
2728 for (i = 0; i < 8; i++) /* Initialize these... */
2729 pxlist[i] = NULL;
2730
2731 g_matchdot = matchdot; /* Save these... */
2732
2733 cmfdbi(&sw, /* 1st FDB - PURGE switches */
2734 _CMKEY, /* fcode */
2735 "Filename or switch", /* hlpmsg */
2736 "", /* default */
2737 "", /* addtl string data */
2738 npurgtab, /* addtl numeric data 1: tbl size */
2739 4, /* addtl numeric data 2: 4 = cmswi */
2740 xxstring, /* Processing function */
2741 purgtab, /* Keyword table */
2742 &sf /* Pointer to next FDB */
2743 );
2744 cmfdbi(&sf, /* 2nd FDB - filespec to purge */
2745 _CMIFI, /* fcode */
2746 "",
2747 "", /* default */
2748 "", /* addtl string data */
2749 0, /* addtl numeric data 1 */
2750 0, /* addtl numeric data 2 */
2751 xxstring,
2752 NULL,
2753 &cm
2754 );
2755 cmfdbi(&cm, /* Or premature confirmation */
2756 _CMCFM, /* fcode */
2757 "", /* hlpmsg */
2758 "", /* default */
2759 "", /* addtl string data */
2760 0, /* addtl numeric data 1 */
2761 0, /* addtl numeric data 2 */
2762 NULL,
2763 NULL,
2764 NULL
2765 );
2766
2767 while (!havename && !confirmed) {
2768 x = cmfdb(&sw); /* Parse something */
2769 if (x < 0) { /* Error */
2770 rc = x;
2771 goto xpurge;
2772 } else if (cmresult.fcode == _CMKEY) {
2773 char c;
2774 c = cmgbrk();
2775 if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
2776 printf("?This switch does not take an argument\n");
2777 rc = -9;
2778 goto xpurge;
2779 }
2780 if (!getval && (cmgkwflgs() & CM_ARG)) {
2781 printf("?This switch requires an argument\n");
2782 rc = -9;
2783 goto xpurge;
2784 }
2785 switch (k = cmresult.nresult) {
2786 case PU_KEEP:
2787 z = 1;
2788 if (c == ':' || c == '=') {
2789 if ((y = cmnum("How many backup files to keep",
2790 "1",10,&z,xxstring)) < 0) {
2791 rc = y;
2792 goto xpurge;
2793 }
2794 }
2795 if (z < 0 || z > MAXKEEP) {
2796 printf("?Please specify a number between 0 and %d\n",
2797 MAXKEEP
2798 );
2799 rc = -9;
2800 goto xpurge;
2801 }
2802 tokeep = z;
2803 break;
2804 case PU_LIST:
2805 listing = 1;
2806 break;
2807 case PU_NOLI:
2808 listing = 0;
2809 break;
2810 #ifdef CK_TTGWSIZ
2811 case PU_PAGE:
2812 paging = 1;
2813 break;
2814 case PU_NOPA:
2815 paging = 0;
2816 break;
2817 #endif /* CK_TTGWSIZ */
2818 case PU_DELE:
2819 deleting = 1;
2820 break;
2821 case PU_NODE:
2822 deleting = 0;
2823 simulate = 1;
2824 listing = 1;
2825 break;
2826 case PU_ASK:
2827 asking = 1;
2828 break;
2829 case PU_NASK:
2830 asking = 0;
2831 break;
2832 case PU_AFT:
2833 case PU_BEF:
2834 case PU_NAF:
2835 case PU_NBF:
2836 if ((x = cmdate("File-time","",&s,0,xxstring)) < 0) {
2837 if (x == -3) {
2838 printf("?Date-time required\n");
2839 rc = -9;
2840 } else
2841 rc = x;
2842 goto xpurge;
2843 }
2844 fs++;
2845 switch (k) {
2846 case PU_AFT: makestr(&pu_aft,s); break;
2847 case PU_BEF: makestr(&pu_bef,s); break;
2848 case PU_NAF: makestr(&pu_naf,s); break;
2849 case PU_NBF: makestr(&pu_nbf,s); break;
2850 }
2851 break;
2852 case PU_SMA:
2853 case PU_LAR:
2854 if ((x = cmnum("File size in bytes","0",10,&y,xxstring)) < 0) {
2855 rc = x;
2856 goto xpurge;
2857 }
2858 fs++;
2859 switch (cmresult.nresult) {
2860 case PU_SMA: minsize = y; break;
2861 case PU_LAR: maxsize = y; break;
2862 }
2863 break;
2864 case PU_DOT:
2865 matchdot = 1;
2866 break;
2867 case PU_NODOT:
2868 matchdot = 0;
2869 break;
2870 case PU_EXC:
2871 if ((x = cmfld("Pattern","",&s,xxstring)) < 0) {
2872 if (x == -3) {
2873 printf("?Pattern required\n");
2874 rc = -9;
2875 } else
2876 rc = x;
2877 goto xpurge;
2878 }
2879 fs++;
2880 makestr(&pu_exc,s);
2881 break;
2882 case PU_HDG:
2883 x_hdg = 1;
2884 break;
2885 #ifdef RECURSIVE
2886 case PU_RECU: /* /RECURSIVE */
2887 recursive = 2;
2888 break;
2889 #endif /* RECURSIVE */
2890 default:
2891 printf("?Not implemented yet - \"%s\"\n",atmbuf);
2892 rc = -9;
2893 goto xpurge;
2894 }
2895 } else if (cmresult.fcode == _CMIFI) {
2896 havename = 1;
2897 } else if (cmresult.fcode == _CMCFM) {
2898 confirmed = 1;
2899 } else {
2900 rc = -2;
2901 goto xpurge;
2902 }
2903 }
2904 if (havename) {
2905 #ifdef CKREGEX
2906 ckmakmsg(line,LINBUFSIZ,cmresult.sresult,".~[1-9]*~",NULL,NULL);
2907 #else
2908 ckmakmsg(line,LINBUFSIZ,cmresult.sresult,".~*~",NULL,NULL);
2909 #endif /* CKREGEX */
2910 } else {
2911 #ifdef CKREGEX
2912 ckstrncpy(line,"*.~[1-9]*~",LINBUFSIZ);
2913 #else
2914 ckstrncpy(line,"*.~*~",LINBUFSIZ);
2915 #endif /* CKREGEX */
2916 }
2917 if (!confirmed) {
2918 if ((x = cmcfm()) < 0) {
2919 rc = x;
2920 goto xpurge;
2921 }
2922 }
2923 /* Parse finished - now action */
2924
2925 #ifdef CK_LOGIN
2926 if (isguest) {
2927 printf("?File deletion by guests not permitted.\n");
2928 rc = -9;
2929 goto xpurge;
2930 }
2931 #endif /* CK_LOGIN */
2932
2933 #ifdef CK_TTGWSIZ
2934 if (paging < 0) /* /[NO]PAGE not given */
2935 paging = xaskmore; /* so use prevailing */
2936 #endif /* CK_TTGWSIZ */
2937
2938 lines = 0;
2939 if (x_hdg > 0) {
2940 printf("Purging %s, keeping %d...%s\n",
2941 s,
2942 tokeep,
2943 simulate ? " (SIMULATION)" : "");
2944 lines += 2;
2945 }
2946 flags = ZX_FILONLY;
2947 if (recursive) flags |= ZX_RECURSE;
2948 n = nzxpand(line,flags); /* Get list of backup files */
2949 if (tokeep < 1) { /* Deleting all of them... */
2950 for (i = 0; i < n; i++) {
2951 if (fs) if (fileselect(mtchs[i],
2952 pu_aft,pu_bef,pu_naf,pu_nbf,
2953 minsize,maxsize,0,8,pxlist) < 1) {
2954 if (listing > 0) {
2955 printf(" %s (SKIPPED)\n",mtchs[i]);
2956 #ifdef CK_TTGWSIZ
2957 if (paging)
2958 if (++lines > cmd_rows - 3) {
2959 if (!askmore()) goto xpurge; else lines = 0;
2960 }
2961 #endif /* CK_TTGWSIZ */
2962 }
2963 continue;
2964 }
2965 if (asking) {
2966 int x;
2967 ckmakmsg(tmpbuf,TMPBUFSIZ," Delete ",mtchs[i],"?",NULL);
2968 x = getyesno(tmpbuf,1);
2969 switch (x) {
2970 case 0: continue;
2971 case 1: break;
2972 case 2: goto xpurge;
2973 }
2974 }
2975 x = deleting ? zdelet(mtchs[i]) : 0;
2976 if (x > -1) {
2977 if (listing)
2978 printf(" %s (%s)\n", mtchs[i],deleting ? "OK" : "SELECTED");
2979 count++;
2980 } else {
2981 errors++;
2982 if (listing)
2983 printf(" %s (FAILED)\n", mtchs[i]);
2984 }
2985 #ifdef CK_TTGWSIZ
2986 if (listing && paging)
2987 if (++lines > cmd_rows - 3) {
2988 if (!askmore()) goto xpurge; else lines = 0;
2989 }
2990 #endif /* CK_TTGWSIZ */
2991 }
2992 goto xpurge;
2993 }
2994 if (n < tokeep) { /* Not deleting any */
2995 count = 0;
2996 if (listing)
2997 printf(" Matches = %d: Not enough to purge.\n",n);
2998 goto xpurge;
2999 }
3000
3001 /* General case - delete some but not others */
3002
3003 sh_sort(mtchs,NULL,n,0,0,filecase); /* Alphabetize the list (ESSENTIAL) */
3004
3005 g = 0; /* Start of current group */
3006 for (i = 0; i < n; i++) { /* Go thru sorted file list */
3007 x = znext(namebuf); /* Get next file */
3008 if (x < 1 || !namebuf[0] || i == n - 1) /* No more? */
3009 done = 1; /* NOTE: 'done' must be 0 or 1 only */
3010 if (fs) if (fileselect(namebuf,
3011 pu_aft,pu_bef,pu_naf,pu_nbf,
3012 minsize,maxsize,0,8,pxlist) < 1) {
3013 if (listing > 0) {
3014 printf(" %s (SKIPPED)\n",namebuf);
3015 if (++lines > cmd_rows - 3)
3016 if (!askmore()) goto xpurge; else lines = 0;
3017 }
3018 continue;
3019 }
3020 if (x > 0)
3021 if ((m = bkupnum(namebuf,&z)) < 0) /* This file's backup number. */
3022 continue;
3023 for (j = 0; j < tokeep; j++) { /* Insert in list. */
3024 if (m > xx[j]) {
3025 for (k = tokeep - 1; k > j; k--)
3026 xx[k] = xx[k-1];
3027 xx[j] = m;
3028 break;
3029 }
3030 }
3031 /* New group? */
3032 if (done || (i > 0 && ckstrcmp(namebuf,basebuf,z,1))) {
3033 if (i + done - g > tokeep) { /* Do we have enough to purge? */
3034 min = xx[tokeep-1]; /* Yes, lowest backup number to keep */
3035 debug(F111,"dopurge group",basebuf,min);
3036 for (j = g; j < i + done; j++) { /* Go through this group */
3037 x = bkupnum(mtchs[j],&z); /* Get file backup number */
3038 if (x > 0 && x < min) { /* Below minimum? */
3039 x = deleting ? zdelet(mtchs[j]) : 0;
3040 if (x < 0) errors++;
3041 if (listing)
3042 printf(" %s (%s)\n",
3043 mtchs[j],
3044 ((x < 0) ? "ERROR" :
3045 (deleting ? "DELETED" : "SELECTED"))
3046 );
3047 count++;
3048 } else if (listing) /* Not below minimum - keep this one */
3049 printf(" %s (KEPT)\n",mtchs[j]);
3050 #ifdef CK_TTGWSIZ
3051 if (listing && paging)
3052 if (++lines > cmd_rows - 3) {
3053 if (!askmore()) goto xpurge; else lines = 0;
3054 }
3055 #endif /* CK_TTGWSIZ */
3056 }
3057 } else if (listing && paging) { /* Not enough to purge */
3058 printf(" %s.~*~ (KEPT)\n",basebuf);
3059 #ifdef CK_TTGWSIZ
3060 if (++lines > cmd_rows - 3) {
3061 if (!askmore()) goto xpurge; else lines = 0;
3062 }
3063 #endif /* CK_TTGWSIZ */
3064 }
3065 for (j = 0; j < tokeep; j++) /* Clear the backup number list */
3066 xx[j] = 0;
3067 g = i; /* Reset the group pointer */
3068 }
3069 if (done) /* No more files, done. */
3070 break;
3071 strncpy(basebuf,namebuf,z); /* Set basename of this file */
3072 basebuf[z] = NUL;
3073 }
3074 xpurge: /* Common exit point */
3075 if (g_matchdot > -1) {
3076 matchdot = g_matchdot; /* Restore these... */
3077 g_matchdot = -1;
3078 }
3079 if (rc < 0) return(rc); /* Parse error */
3080 if (x_hdg)
3081 printf("Files purged: %d%s\n",
3082 count,
3083 deleting ? "" : " (not really)"
3084 );
3085 return(success = count > 0 ? 1 : (errors > 0) ? 0 : 1);
3086 }
3087 #endif /* CKPURGE */
3088
3089 #ifndef NOXFER
3090 #ifndef NOLOCAL
3091 int
doxdis(which)3092 doxdis(which) int which; { /* 1 = Kermit, 2 = FTP */
3093 extern int nolocal;
3094 int x, y = 0, z;
3095 #ifdef NEWFTP
3096 extern int ftp_dis;
3097 #endif /* NEWFTP */
3098
3099 #ifdef COMMENT
3100 char *s;
3101 #endif /* COMMENT */
3102
3103 if ((x = cmkey(fdtab,nfdtab,"file transfer display style","",
3104 xxstring)) < 0)
3105 return(x);
3106 #ifdef CK_PCT_BAR
3107 if ((y = cmkey(fdftab,2,"","thermometer",xxstring)) < 0)
3108 return(y);
3109 #endif /* CK_PCT_BAR */
3110 if ((z = cmcfm()) < 0) return(z);
3111 #ifdef CK_CURSES
3112 if (x == XYFD_C) { /* FULLSCREEN */
3113 #ifdef COMMENT
3114 #ifndef MYCURSES
3115 extern char * trmbuf; /* Real curses */
3116 int z;
3117 #endif /* MYCURSES */
3118 #endif /* COMMENT */
3119
3120 if (nolocal) /* Nothing to do in this case */
3121 return(success = 1);
3122
3123 #ifdef COMMENT
3124 #ifndef MYCURSES
3125 #ifndef VMS
3126 s = getenv("TERM");
3127 debug(F110,"doxdis TERM",s,0);
3128 if (!s) s = "";
3129 fxdinit(x);
3130 if (*s && trmbuf) { /* Don't call tgetent */
3131 z = tgetent(trmbuf,s); /* if trmbuf not allocated */
3132 debug(F111,"doxdis tgetent",s,z);
3133 } else {
3134 z = 0;
3135 debug(F110,"doxdis tgetent skipped",s,0);
3136 }
3137 if (z < 1) {
3138 printf("Sorry, terminal type unknown: \"%s\"\n",s);
3139 return(success = 0);
3140 }
3141 #endif /* VMS */
3142 #endif /* MYCURSES */
3143 #else
3144 fxdinit(x);
3145 #endif /* COMMENT */
3146
3147 #ifdef CK_PCT_BAR
3148 thermometer = y;
3149 #endif /* CK_PCT_BAR */
3150
3151 line[0] = '\0'; /* (What's this for?) */
3152 }
3153 #endif /* CK_CURSES */
3154 if (which == 1) /* It's OK. */
3155 fdispla = x;
3156 #ifdef NEWFTP
3157 else if (which == 2)
3158 ftp_dis = x;
3159 #endif /* NEWFTP */
3160 return(success = 1);
3161 }
3162 #endif /* NOLOCAL */
3163 #endif /* NOXFER */
3164
3165 int
setfil(rmsflg)3166 setfil(rmsflg) int rmsflg; {
3167 #ifdef COMMENT
3168 extern int en_del;
3169 #endif /* COMMENT */
3170 #ifndef NOXFER
3171 if (rmsflg) {
3172 if ((y = cmkey(rfiltab,nrfilp,"Remote file parameter","",
3173 xxstring)) < 0) {
3174 if (y == -3) {
3175 printf("?Remote file parameter required\n");
3176 return(-9);
3177 } else return(y);
3178 }
3179 } else {
3180 #endif /* NOXFER */
3181 if ((y = cmkey(filtab,nfilp,"File parameter","",xxstring)) < 0)
3182 return(y);
3183 #ifndef NOXFER
3184 }
3185 #endif /* NOXFER */
3186 switch (y) {
3187 #ifdef COMMENT /* Not needed */
3188 case XYFILB: /* Blocksize */
3189 if ((y = cmnum("file block size",ckitoa(DBLKSIZ),10,&z,xxstring)) < 0)
3190 return(y);
3191 if ((x = cmcfm()) < 0) return(x);
3192 if (rmsflg) {
3193 sstate = setgen('S', "311", ckitoa(z), "");
3194 return((int) sstate);
3195 } else {
3196 fblksiz = z;
3197 return(success = 1);
3198 }
3199 #endif /* COMMENT */
3200
3201 #ifndef NOXFER
3202 case XYFILS: /* Byte size */
3203 if ((y = cmnum("file byte size (7 or 8)","8",10,&z,xxstring)) < 0)
3204 return(y);
3205 if (z != 7 && z != 8) {
3206 printf("\n?The choices are 7 and 8\n");
3207 return(0);
3208 }
3209 if ((y = cmcfm()) < 0) return(y);
3210 if (z == 7) fmask = 0177;
3211 else if (z == 8) fmask = 0377;
3212 return(success = 1);
3213
3214 #ifndef NOCSETS
3215 case XYFILC: { /* Character set */
3216 char * csetname = NULL;
3217 extern int
3218 r_cset, s_cset, afcset[]; /* SEND CHARACTER-SET AUTO or MANUAL */
3219
3220 struct FDB kw, fl;
3221 cmfdbi(&kw, /* First FDB - command switches */
3222 _CMKEY, /* fcode */
3223 rmsflg ? "server character-set name" : "", /* help */
3224 "", /* default */
3225 "", /* addtl string data */
3226 nfilc, /* addtl numeric data 1: tbl size */
3227 0, /* addtl numeric data 2: 0 = keyword */
3228 xxstring, /* Processing function */
3229 fcstab, /* Keyword table */
3230 rmsflg ? &fl : NULL /* Pointer to next FDB */
3231 );
3232 cmfdbi(&fl, /* Anything that doesn't match */
3233 _CMFLD, /* fcode */
3234 "", /* hlpmsg */
3235 "", /* default */
3236 "", /* addtl string data */
3237 0, /* addtl numeric data 1 */
3238 0, /* addtl numeric data 2 */
3239 xxstring,
3240 NULL,
3241 NULL
3242 );
3243 if ((x = cmfdb(&kw)) < 0)
3244 return(x);
3245 if (cmresult.fcode == _CMKEY) {
3246 x = cmresult.nresult;
3247 csetname = fcsinfo[x].keyword;
3248 } else {
3249 ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
3250 csetname = line;
3251 }
3252 if ((z = cmcfm()) < 0) return(z);
3253 if (rmsflg) {
3254 sstate = setgen('S', "320", csetname, "");
3255 return((int) sstate);
3256 }
3257 fcharset = x;
3258 if (s_cset == XMODE_A) /* If SEND CHARACTER-SET is AUTO */
3259 if (x > -1 && x <= MAXFCSETS)
3260 if (afcset[x] > -1 && afcset[x] <= MAXTCSETS)
3261 tcharset = afcset[x]; /* Pick corresponding xfer charset */
3262 setxlatype(tcharset,fcharset); /* Translation type */
3263 /* If I say SET FILE CHARACTER-SET blah, I want to be blah! */
3264 r_cset = XMODE_M; /* Don't switch incoming set! */
3265 x = fcsinfo[fcharset].size; /* Also set default x-bit charset */
3266 if (x == 128) /* 7-bit... */
3267 dcset7 = fcharset;
3268 else if (x == 256) /* 8-bit... */
3269 dcset8 = fcharset;
3270 return(success = 1);
3271 }
3272 #endif /* NOCSETS */
3273
3274 #ifndef NOLOCAL
3275 case XYFILD: /* Display */
3276 return(doxdis(1)); /* 1 == kermit */
3277 #endif /* NOLOCAL */
3278 #endif /* NOXFER */
3279
3280 case XYFILA: /* End-of-line */
3281 #ifdef NLCHAR
3282 s = "";
3283 if (NLCHAR == 015)
3284 s = "cr";
3285 else if (NLCHAR == 012)
3286 s = "lf";
3287 if ((x = cmkey(eoltab, neoltab,
3288 "local text-file line terminator",s,xxstring)) < 0)
3289 return(x);
3290 #else
3291 if ((x = cmkey(eoltab, neoltab,
3292 "local text-file line terminator","crlf",xxstring)) < 0)
3293 return(x);
3294 #endif /* NLCHAR */
3295 if ((z = cmcfm()) < 0) return(z);
3296 feol = (CHAR) x;
3297 return(success = 1);
3298
3299 #ifndef NOXFER
3300 case XYFILN: /* Names */
3301 if ((x = cmkey(fntab,nfntab,"how to handle filenames","converted",
3302 xxstring)) < 0)
3303 return(x);
3304 if ((z = cmcfm()) < 0) return(z);
3305 if (rmsflg) {
3306 sstate = setgen('S', "301", ckitoa(1 - x), "");
3307 return((int) sstate);
3308 } else {
3309 ptab[protocol].fncn = x; /* Set structure */
3310 fncnv = x; /* Set variable */
3311 f_save = x; /* And set "permanent" variable */
3312 return(success = 1);
3313 }
3314
3315 case XYFILR: /* Record length */
3316 if ((y = cmnum("file record length",
3317 ckitoa(DLRECL),10,&z,xxstring)) < 0)
3318 return(y);
3319 if ((x = cmcfm()) < 0) return(x);
3320 if (rmsflg) {
3321 sstate = setgen('S', "312", ckitoa(z), "");
3322 return((int) sstate);
3323 } else {
3324 frecl = z;
3325 return(success = 1);
3326 }
3327
3328 #ifdef COMMENT
3329 case XYFILO: /* Organization */
3330 if ((x = cmkey(forgtab,nforg,"file organization","sequential",
3331 xxstring)) < 0)
3332 return(x);
3333 if ((y = cmcfm()) < 0) return(y);
3334 if (rmsflg) {
3335 sstate = setgen('S', "314", ckitoa(x), "");
3336 return((int) sstate);
3337 } else {
3338 forg = x;
3339 return(success = 1);
3340 }
3341 #endif /* COMMENT */
3342
3343 #ifdef COMMENT /* Not needed */
3344 case XYFILF: /* Format */
3345 if ((x = cmkey(frectab,nfrec,"file record format","stream",
3346 xxstring)) < 0)
3347 return(x);
3348 if ((y = cmcfm()) < 0) return(y);
3349 if (rmsflg) {
3350 sstate = setgen('S', "313", ckitoa(x), "");
3351 return((int) sstate);
3352 } else {
3353 frecfm = x;
3354 return(success = 1);
3355 }
3356 #endif /* COMMENT */
3357
3358 #ifdef COMMENT
3359 case XYFILP: /* Printer carriage control */
3360 if ((x = cmkey(fcctab,nfcc,"file carriage control","newline",
3361 xxstring)) < 0)
3362 return(x);
3363 if ((y = cmcfm()) < 0) return(y);
3364 if (rmsflg) {
3365 sstate = setgen('S', "315", ckitoa(x), "");
3366 return((int) sstate);
3367 } else {
3368 fcctrl = x;
3369 return(success = 1);
3370 }
3371 #endif /* COMMENT */
3372 #endif /* NOXFER */
3373
3374 case XYFILT: /* Type */
3375 if ((x = cmkey(rmsflg ? rfttab : fttab,
3376 rmsflg ? nrfttyp : nfttyp,
3377 "type of file transfer","text",xxstring)) < 0)
3378 return(x);
3379
3380 #ifdef VMS
3381 /* Allow VMS users to choose record format for binary files */
3382 if ((x == XYFT_B) && (rmsflg == 0)) {
3383 if ((x = cmkey(fbtab,nfbtyp,"VMS record format","fixed",
3384 xxstring)) < 0)
3385 return(x);
3386 }
3387 #endif /* VMS */
3388 if ((y = cmcfm()) < 0) return(y);
3389 binary = x;
3390 b_save = x;
3391 #ifdef MAC
3392 (void) mac_setfildflg(binary);
3393 #endif /* MAC */
3394 #ifndef NOXFER
3395 if (rmsflg) {
3396 /* Allow for LABELED in VMS & OS/2 */
3397 sstate = setgen('S', "300", ckitoa(x), "");
3398 return((int) sstate);
3399 } else {
3400 #endif /* NOXFER */
3401 return(success = 1);
3402 #ifndef NOXFER
3403 }
3404 #endif /* NOXFER */
3405
3406 #ifndef NOXFER
3407 case XYFILX: /* Collision Action */
3408 if ((x = cmkey(colxtab,ncolx,"Filename collision action","backup",
3409 xxstring)) < 0)
3410 return(x);
3411 if ((y = cmcfm()) < 0) return(y);
3412 #ifdef CK_LOGIN
3413 if (isguest) {
3414 /* Don't let guests change existing files */
3415 printf("?This command not valid for guests\n");
3416 return(-9);
3417 }
3418 #endif /* CK_LOGIN */
3419 #ifdef COMMENT
3420 /* Not appropriate - DISABLE DELETE only refers to server */
3421 if ((x == XYFX_X || x == XYFX_B || x == XYFX_U || x == XYFX_A) &&
3422 (!ENABLED(en_del))) {
3423 printf("?Sorry, file deletion is disabled.\n");
3424 return(-9);
3425 }
3426 #endif /* COMMENT */
3427 fncact = x;
3428 ptab[protocol].fnca = x;
3429 if (rmsflg) {
3430 sstate = setgen('S', "302", ckitoa(fncact), "");
3431 return((int) sstate);
3432 } else {
3433 if (fncact == XYFX_R) ckwarn = 1; /* FILE WARNING implications */
3434 if (fncact == XYFX_X) ckwarn = 0; /* ... */
3435 return(success = 1);
3436 }
3437
3438 case XYFILW: /* Warning/Write-Protect */
3439 if ((x = seton(&ckwarn)) < 0) return(x);
3440 if (ckwarn)
3441 fncact = XYFX_R;
3442 else
3443 fncact = XYFX_X;
3444 return(success = 1);
3445
3446 #ifdef CK_LABELED
3447 case XYFILL: /* LABELED FILE parameters */
3448 if ((x = cmkey(lbltab,nlblp,"Labeled file feature","",
3449 xxstring)) < 0)
3450 return(x);
3451 if ((success = seton(&y)) < 0)
3452 return(success);
3453 if (y) /* Set or reset the selected bit */
3454 lf_opts |= x; /* in the options bitmask. */
3455 else
3456 lf_opts &= ~x;
3457 return(success);
3458 #endif /* CK_LABELED */
3459
3460 case XYFILI: { /* INCOMPLETE */
3461 extern struct keytab ifdatab[];
3462 extern int keep;
3463 if ((y = cmkey(ifdatab,3,"","auto",xxstring)) < 0) return(y);
3464 if ((x = cmcfm()) < 0) return(x);
3465 if (rmsflg) {
3466 sstate = setgen('S',
3467 "310",
3468 y == 0 ? "0" : (y == 1 ? "1" : "2"),
3469 ""
3470 );
3471 return((int) sstate);
3472 } else {
3473 keep = y;
3474 return(success = 1);
3475 }
3476 }
3477
3478 #ifdef CK_TMPDIR
3479 case XYFILG: { /* Download directory */
3480 int x;
3481 char *s;
3482 #ifdef ZFNQFP
3483 struct zfnfp * fnp;
3484 #endif /* ZFNQFP */
3485 #ifdef MAC
3486 char temp[34];
3487 #endif /* MAC */
3488
3489 #ifdef GEMDOS
3490 if ((x = cmdir("Name of local directory, or carriage return",
3491 "",&s,
3492 NULL)) < 0 ) {
3493 if (x != -3)
3494 return(x);
3495 }
3496 #else
3497 #ifdef OS2
3498 if ((x = cmdir("Name of PC disk and/or directory,\n\
3499 or press the Enter key to use current directory",
3500 "",&s,xxstring)) < 0 ) {
3501 if (x != -3)
3502 return(x);
3503 }
3504 #else
3505 #ifdef MAC
3506 x = ckstrncpy(temp,zhome(),32);
3507 if (x > 0) if (temp[x-1] != ':') { temp[x] = ':'; temp[x+1] = NUL; }
3508 if ((x = cmtxt("Name of Macintosh volume and/or folder,\n\
3509 or press the Return key for the desktop on the boot disk",
3510 temp,&s, xxstring)) < 0 )
3511 return(x);
3512 #else
3513 if ((x = cmdir("Name of local directory, or carriage return",
3514 "", &s, xxstring)) < 0 ) {
3515 if (x != -3)
3516 return(x);
3517 }
3518 #endif /* MAC */
3519 #endif /* OS2 */
3520 #endif /* GEMDOS */
3521 debug(F110,"download dir",s,0);
3522
3523 #ifndef MAC
3524 if (x == 2) {
3525 printf("?Wildcards not allowed in directory name\n");
3526 return(-9);
3527 }
3528 #endif /* MAC */
3529
3530 #ifdef ZFNQFP
3531 if ((fnp = zfnqfp(s,TMPBUFSIZ - 1,tmpbuf))) {
3532 if (fnp->fpath)
3533 if ((int) strlen(fnp->fpath) > 0)
3534 s = fnp->fpath;
3535 }
3536 debug(F110,"download zfnqfp",s,0);
3537 #endif /* ZFNQFP */
3538
3539 ckstrncpy(line,s,LINBUFSIZ); /* Make a safe copy */
3540 #ifndef MAC
3541 if ((x = cmcfm()) < 0) /* Get confirmation */
3542 return(x);
3543 #endif /* MAC */
3544
3545 #ifdef CK_LOGIN
3546 if (isguest) {
3547 /* Don't let guests change existing files */
3548 printf("?This command not valid for guests\n");
3549 return(-9);
3550 }
3551 #endif /* CK_LOGIN */
3552 x = strlen(s);
3553
3554 if (x) {
3555 #ifdef datageneral /* AOS/VS */
3556 if (s[x-1] == ':') /* homdir ends in colon, */
3557 s[x-1] = NUL; /* and "dir" doesn't like that... */
3558 #else
3559 #ifdef OS2ORUNIX /* Unix or K-95... */
3560 if ((x < (LINBUFSIZ - 2)) && /* Add trailing dirsep */
3561 (s[x-1] != '/')) { /* if none present. */
3562 s[x] = '/'; /* Note that Windows path has */
3563 s[x+1] = NUL; /* been canonicalized to forward */
3564 } /* slashes at this point. */
3565 #endif /* OS2ORUNIX */
3566 #endif /* datageneral */
3567 makestr(&dldir,s);
3568 } else
3569 makestr(&dldir,NULL); /* dldir is NULL when not assigned */
3570
3571 return(success = 1);
3572 }
3573 #endif /* CK_TMPDIR */
3574 case XYFILY:
3575 return(setdest());
3576 #endif /* NOXFER */
3577
3578 #ifdef CK_CTRLZ
3579 case XYFILV: { /* EOF */
3580 extern int eofmethod;
3581 if ((x = cmkey(eoftab,3,"end-of-file detection method","",
3582 xxstring)) < 0)
3583 return(x);
3584 if ((y = cmcfm()) < 0)
3585 return(y);
3586 eofmethod = x;
3587 return(success = 1);
3588 }
3589 #endif /* CK_CTRLZ */
3590
3591 #ifndef NOXFER
3592 #ifdef UNIX
3593 case XYFILH: { /* OUTPUT */
3594 extern int zofbuffer, zobufsize, zofblock;
3595 #ifdef DYNAMIC
3596 extern char * zoutbuffer;
3597 #endif /* DYNAMIC */
3598
3599 if ((x = cmkey(zoftab,nzoftab,"output file writing method","",
3600 xxstring)) < 0)
3601 return(x);
3602 if (x == ZOF_BUF || x == ZOF_NBUF) {
3603 if ((y = cmnum("output buffer size","32768",10,&z,xxstring)) < 0)
3604 return(y);
3605 if (z < 1) {
3606 printf("?Bad size - %d\n", z);
3607 return(-9);
3608 }
3609 }
3610 if ((y = cmcfm()) < 0) return(y);
3611 switch (x) {
3612 case ZOF_BUF:
3613 case ZOF_NBUF:
3614 zofbuffer = (x == ZOF_BUF);
3615 zobufsize = z;
3616 break;
3617 case ZOF_BLK:
3618 case ZOF_NBLK:
3619 zofblock = (x == ZOF_BLK);
3620 break;
3621 }
3622 #ifdef DYNAMIC
3623 if (zoutbuffer) free(zoutbuffer);
3624 if (!(zoutbuffer = (char *)malloc(z))) {
3625 printf("MEMORY ALLOCATION ERROR - FATAL\n");
3626 doexit(BAD_EXIT,-1);
3627 } else
3628 zobufsize = z;
3629 #else
3630 if (z <= OBUFSIZE) {
3631 zobufsize = z;
3632 } else {
3633 printf("?Sorry, %d is too big - %d is the maximum\n",z,OBUFSIZE);
3634 return(-9);
3635 }
3636 #endif /* DYNAMIC */
3637 return(success = 1);
3638 }
3639 #endif /* UNIX */
3640
3641 #ifdef PATTERNS
3642 case XYFIBP: /* BINARY-PATTERN */
3643 case XYFITP: { /* TEXT-PATTERN */
3644 char * tmp[FTPATTERNS];
3645 int i, n = 0;
3646 while (n < FTPATTERNS) {
3647 tmp[n] = NULL;
3648 if ((x = cmfld("Pattern","",&s,xxstring)) < 0)
3649 break;
3650 ckstrncpy(line,s,LINBUFSIZ);
3651 s = brstrip(line);
3652 makestr(&(tmp[n++]),s);
3653 }
3654 if (x == -3) x = cmcfm();
3655 for (i = 0; i <= n; i++) {
3656 if (x > -1) {
3657 if (y == XYFIBP)
3658 makestr(&(binpatterns[i]),tmp[i]);
3659 else
3660 makestr(&(txtpatterns[i]),tmp[i]);
3661 }
3662 free(tmp[i]);
3663 }
3664 if (y == XYFIBP) /* Null-terminate the list */
3665 makestr(&(binpatterns[i]),NULL);
3666 else
3667 makestr(&(txtpatterns[i]),NULL);
3668 return(x);
3669 }
3670
3671 case XYFIPA: /* PATTERNS */
3672 if ((x = setonaut(&patterns)) < 0)
3673 return(x);
3674 return(success = 1);
3675 #endif /* PATTERNS */
3676 #endif /* NOXFER */
3677
3678 #ifdef UNICODE
3679 case XYFILU: { /* UCS */
3680 extern int ucsorder, ucsbom, byteorder;
3681 if ((x = cmkey(ucstab,nucstab,"","",xxstring)) < 0)
3682 return(x);
3683 switch (x) {
3684 case UCS_BYT:
3685 if ((y = cmkey(botab,nbotab,
3686 "Byte order",
3687 byteorder ? "little-endian" : "big-endian",
3688 xxstring
3689 )
3690 ) < 0)
3691 return(y);
3692 if ((x = cmcfm()) < 0)
3693 return(x);
3694 ucsorder = y;
3695 return(success = 1);
3696 case UCS_BOM:
3697 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0)
3698 return(y);
3699 if ((x = cmcfm()) < 0)
3700 return(x);
3701 ucsbom = y;
3702 return(success = 1);
3703 default:
3704 return(-2);
3705 }
3706 }
3707 #endif /* UNICODE */
3708
3709 #ifndef datageneral
3710 case XYF_INSP: { /* SCAN (INSPECTION) */
3711 extern int filepeek, nscanfile;
3712 if ((x = cmkey(onoff,2,"","on",xxstring)) < 0)
3713 return(x);
3714 if (y) {
3715 if ((y = cmnum("How much to scan",ckitoa(SCANFILEBUF),
3716 10,&z,xxstring)) < 0)
3717 return(y);
3718 }
3719 if ((y = cmcfm()) < 0)
3720 return(y);
3721 #ifdef VMS
3722 filepeek = 0;
3723 nscanfile = 0;
3724 return(success = 0);
3725 #else
3726 filepeek = x;
3727 nscanfile = z;
3728 return(success = 1);
3729 #endif /* VMS */
3730 }
3731 #endif /* datageneral */
3732
3733 case XYF_DFLT:
3734 y = 0;
3735 #ifndef NOCSETS
3736 if ((y = cmkey(fdfltab,nfdflt,"","",xxstring)) < 0)
3737 return(y);
3738 if (y == 7 || y == 8) {
3739 if (y == 7)
3740 s = fcsinfo[dcset7].keyword;
3741 else
3742 s = fcsinfo[dcset8].keyword;
3743 if ((x = cmkey(fcstab,nfilc,"character-set",s,xxstring)) < 0)
3744 return(x);
3745 }
3746 ckstrncpy(line,fcsinfo[x].keyword,LINBUFSIZ);
3747 s = line;
3748 #endif /* NOCSETS */
3749 if ((z = cmcfm()) < 0)
3750 return(z);
3751 switch (y) {
3752 #ifndef NOCSETS
3753 case 7:
3754 if (fcsinfo[x].size != 128) {
3755 printf("%s - Not a 7-bit set\n",s);
3756 return(-9);
3757 }
3758 dcset7 = x;
3759 break;
3760 case 8:
3761 if (fcsinfo[x].size != 256) {
3762 printf("%s - Not an 8-bit set\n",s);
3763 return(-9);
3764 }
3765 dcset8 = x;
3766 break;
3767 #endif /* NOCSETS */
3768 default:
3769 return(-2);
3770 }
3771 return(success = 1);
3772
3773 #ifndef NOXFER
3774 case 9997: /* FASTLOOKUPS */
3775 return(success = seton(&stathack));
3776 #endif /* NOXFER */
3777
3778 #ifdef UNIX
3779 #ifdef DYNAMIC
3780 case XYF_LSIZ: { /* LISTSIZE */
3781 int zz;
3782 y = cmnum("Maximum number of filenames","",10,&x,xxstring);
3783 if ((x = setnum(&zz,x,y,-1)) < 0)
3784 return(x);
3785 if (zsetfil(zz,3) < 0) {
3786 printf("?Memory allocation failure\n");
3787 return(-9);
3788 }
3789 return(success = 1);
3790 }
3791 case XYF_SSPA: { /* STRINGSPACE */
3792 int zz;
3793 y = cmnum("Number of characters for filename list",
3794 "",10,&x,xxstring);
3795 if ((x = setnum(&zz,x,y,-1)) < 0)
3796 return(x);
3797 if (zsetfil(zz,1) < 0) {
3798 printf("?Memory allocation failure\n");
3799 return(-9);
3800 }
3801 return(success = 1);
3802 }
3803
3804 #endif /* DYNAMIC */
3805 #endif /* UNIX */
3806
3807 default:
3808 printf("?unexpected file parameter\n");
3809 return(-2);
3810 }
3811 }
3812
3813 #ifdef UNIX
3814 #ifndef NOPUTENV
3815 #ifdef BIGBUFOK
3816 #define NPUTENVS 4096
3817 #else
3818 #define NPUTENVS 128
3819 #endif /* BIGBUFOK */
3820 /* environment variables must be static, not automatic */
3821
3822 static char * putenvs[NPUTENVS]; /* Array of environment var strings */
3823 static int nputenvs = -1; /* Pointer into array */
3824 /*
3825 If anyone ever notices the limitation on the number of PUTENVs, the list
3826 can be made dynamic, we can recycle entries with the same name, etc.
3827 */
3828 int
doputenv(s1,s2)3829 doputenv(s1, s2) char * s1; char * s2; {
3830 char * s, * t = tmpbuf; /* Create or alter environment var */
3831
3832 if (nputenvs == -1) { /* Table not used yet */
3833 int i; /* Initialize the pointers */
3834 for (i = 0; i < NPUTENVS; i++)
3835 putenvs[i] = NULL;
3836 nputenvs = 0;
3837 }
3838 if (!s1) return(1); /* Nothing to do */
3839 if (!*s1) return(1); /* ditto */
3840
3841 if (ckindex("=",s1,0,0,0)) { /* Does the name contain an '='? */
3842 printf( /* putenv() does not allow this. */
3843 /* This also catches the 'putenv name=value' case */
3844 "?PUTENV - Equal sign in variable name - 'help putenv' for info.\n");
3845 return(-9);
3846 }
3847 nputenvs++; /* Point to next free string */
3848
3849 debug(F111,"doputenv s1",s1,nputenvs);
3850 debug(F111,"doputenv s2",s2,nputenvs);
3851
3852 if (nputenvs > NPUTENVS - 1) { /* Notice the end */
3853 printf("?PUTENV - static buffer space exhausted\n");
3854 return(-9);
3855 }
3856 /* Quotes are not needed but we allow them for familiarity */
3857 /* but then we strip them, so syntax is same as for Unix shell */
3858
3859 if (s2) {
3860 s2 = brstrip(s2);
3861 } else {
3862 s2 = (char *)"";
3863 }
3864 ckmakmsg(t,TMPBUFSIZ,s1,"=",s2,NULL);
3865 debug(F111,"doputenv",t,nputenvs);
3866 (VOID) makestr(&(putenvs[nputenvs]),t); /* Make a safe permananent copy */
3867 if (!putenvs[nputenvs]) {
3868 printf("?PUTENV - memory allocation failure\n");
3869 return(-9);
3870 }
3871 if (putenv(putenvs[nputenvs])) {
3872 printf("?PUTENV - %s\n",ck_errstr());
3873 return(-9);
3874 } else return(success = 1);
3875 }
3876 #endif /* NOPUTENV */
3877 #endif /* UNIX */
3878
3879 int
settrmtyp()3880 settrmtyp() {
3881 #ifdef OS2
3882 #ifdef TNCODE
3883 extern int ttnum; /* Last Telnet Terminal Type sent */
3884 extern int ttnumend; /* Has end of list been found */
3885 #endif /* TNCODE */
3886 if ((x = cmkey(ttyptab,nttyp,"","vt220",xxstring)) < 0)
3887 return(x);
3888 if ((y = cmcfm()) < 0)
3889 return(y);
3890 settermtype(x,1);
3891 #ifdef TNCODE
3892 /* So we send the correct terminal name to the host if it asks for it */
3893 ttnum = -1; /* Last Telnet Terminal Type sent */
3894 ttnumend = 0; /* end of list not found */
3895 #endif /* TNCODE */
3896 return(success = 1);
3897 #else /* Not OS2 */
3898 #ifdef UNIX
3899 extern int fxd_inited;
3900 x = cmtxt("Terminal type name, case sensitive","",&s,NULL);
3901 #ifdef NOPUTENV
3902 success = 1;
3903 #else
3904 success = doputenv("TERM",s); /* Set the TERM variable */
3905 #ifdef CK_CURSES
3906 fxd_inited = 0; /* Force reinitialization of curses database */
3907 (void)doxdis(0); /* Re-initialize file transfer display */
3908 concb((char)escape); /* Fix command terminal */
3909 #endif /* CK_CURSES */
3910 #endif /* NOPUTENV */
3911 return(success);
3912 #else
3913 printf(
3914 "\n Sorry, this version of C-Kermit does not support the SET TERMINAL TYPE\n");
3915 printf(
3916 " command. Type \"help set terminal\" for further information.\n");
3917 return(success = 0);
3918 #endif /* UNIX */
3919 #endif /* OS2 */
3920 }
3921
3922 #ifndef NOLOCAL
3923 #ifdef OS2
3924 /* MS-DOS KERMIT compatibility modes */
3925 int
setmsk()3926 setmsk() {
3927 if ((y = cmkey(msktab,nmsk,"MS-DOS Kermit compatibility mode",
3928 "keycodes",xxstring)) < 0) return(y);
3929
3930 switch ( y ) {
3931 #ifdef COMMENT
3932 case MSK_COLOR:
3933 return(seton(&mskcolors));
3934 #endif /* COMMENT */
3935 case MSK_KEYS:
3936 return(seton(&mskkeys));
3937 case MSK_REN:
3938 return(seton(&mskrename));
3939 default: /* Shouldn't get here. */
3940 return(-2);
3941 }
3942 }
3943 #endif /* OS2 */
3944
3945 #ifdef CKTIDLE
3946 static char iactbuf[132];
3947
3948 char *
getiact()3949 getiact() {
3950 switch (tt_idleact) {
3951 case IDLE_RET: return("return");
3952 case IDLE_EXIT: return("exit");
3953 case IDLE_HANG: return("hangup");
3954 #ifdef TNCODE
3955 case IDLE_TNOP: return("Telnet NOP");
3956 case IDLE_TAYT: return("Telnet AYT");
3957 #endif /* TNCODE */
3958
3959 case IDLE_OUT: {
3960 int c, k, n;
3961 char * p, * q, * t;
3962 k = ckstrncpy(iactbuf,"output ",132);
3963 n = k;
3964 q = &iactbuf[k];
3965 p = tt_idlestr;
3966 if (!p) p = "";
3967 if (!*p) return("output NUL");
3968 while ((c = *p++) && n < 131) {
3969 c &= 0xff;
3970 if (c == '\\') {
3971 if (n > 130) break;
3972 *q++ = '\\';
3973 *q++ = '\\';
3974 *q = NUL;
3975 n += 2;
3976 } else if ((c > 32 && c < 127) || c > 159) {
3977 *q++ = c;
3978 *q = NUL;
3979 n++;
3980 } else {
3981 if (n > (131 - 6))
3982 break;
3983 sprintf(q,"\\{%d}",c);
3984 k = strlen(q);
3985 q += k;
3986 n += k;
3987 *q = NUL;
3988 }
3989 }
3990 *q = NUL;
3991 #ifdef OS2
3992 k = tt_cols[VTERM];
3993 #else
3994 k = tt_cols;
3995 #endif /* OS2 */
3996 if (n > k - 52) {
3997 n = k - 52;
3998 iactbuf[n-2] = '.';
3999 iactbuf[n-1] = '.';
4000 iactbuf[n] = NUL;
4001 }
4002 return(iactbuf);
4003 }
4004 default: return("unknown");
4005 }
4006 }
4007 #endif /* CKTIDLE */
4008
4009 #ifndef NOCSETS
4010 VOID
setlclcharset(x)4011 setlclcharset(x) int x; {
4012 int i;
4013 tcsl = y; /* Local character set */
4014 #ifdef OS2
4015 for (i = 0; i < 4; i++) {
4016 G[i].init = TRUE;
4017 x = G[i].designation;
4018 G[i].c1 = (x != tcsl) && cs_is_std(x);
4019 x = G[i].def_designation;
4020 G[i].def_c1 = (x != tcsl) && cs_is_std(x);
4021 }
4022 #endif /* OS2 */
4023 }
4024
4025 VOID
setremcharset(x,z)4026 setremcharset(x, z) int x, z; {
4027 int i;
4028
4029 #ifdef KUI
4030 KuiSetProperty( KUI_TERM_REMCHARSET, (long) x, (long) z ) ;
4031 #endif /* KUI */
4032 #ifdef UNICODE
4033 if (x == TX_TRANSP)
4034 #else /* UNICODE */
4035 if (x == FC_TRANSP)
4036 #endif /* UNICODE */
4037 { /* TRANSPARENT? */
4038 #ifndef OS2
4039 tcsr = tcsl; /* Make both sets the same */
4040 #else /* OS2 */
4041 #ifdef CKOUNI
4042 tt_utf8 = 0; /* Turn off UTF8 flag */
4043 tcsr = tcsl = dec_kbd = TX_TRANSP; /* No translation */
4044 tcs_transp = 1;
4045
4046 if (!cs_is_nrc(tcsl)) {
4047 G[0].def_designation = G[0].designation = TX_ASCII;
4048 G[0].init = TRUE;
4049 G[0].def_c1 = G[0].c1 = FALSE;
4050 G[0].size = cs94;
4051 G[0].national = FALSE;
4052 }
4053 for (i = cs_is_nrc(tcsl) ? 0 : 1; i < 4; i++) {
4054 G[i].def_designation = G[i].designation = tcsl;
4055 G[i].init = TRUE;
4056 G[i].def_c1 = G[i].c1 = FALSE;
4057 switch (cs_size(G[i].designation)) { /* 94, 96, or 128 */
4058 case 128:
4059 case 96:
4060 G[i].size = G[i].def_size = cs96;
4061 break;
4062 case 94:
4063 G[i].size = G[i].def_size = cs94;
4064 break;
4065 default:
4066 G[i].size = G[i].def_size = csmb;
4067 break;
4068 }
4069 G[i].national = cs_is_nrc(x);
4070 }
4071 #else /* CKOUNI */
4072 tcsr = tcsl; /* Make both sets the same */
4073 for (i = 0; i < 4; i++) {
4074 G[i].def_designation = G[i].designation = FC_TRANSP;
4075 G[i].init = FALSE;
4076 G[i].size = G[i].def_size = cs96;
4077 G[i].c1 = G[i].def_c1 = FALSE;
4078 G[i].rtoi = NULL;
4079 G[i].itol = NULL;
4080 G[i].ltoi = NULL;
4081 G[i].itor = NULL;
4082 G[i].national = FALSE;
4083 }
4084 #endif /* CKOUNI */
4085 #endif /* OS2 */
4086 return;
4087 }
4088 #ifdef OS2
4089 #ifdef CKOUNI
4090 else if (x == TX_UTF8) {
4091 tcs_transp = 0;
4092 tt_utf8 = 1; /* Turn it on if we are UTF8 */
4093 return;
4094 }
4095 #endif /* CKOUNI */
4096 else {
4097 tcs_transp = 0;
4098 tcsr = x; /* Remote character set */
4099 #ifdef CKOUNI
4100 tt_utf8 = 0; /* Turn off UTF8 flag */
4101 #endif /* CKOUNI */
4102
4103 if (z == TT_GR_ALL) {
4104 int i;
4105 #ifdef UNICODE
4106 dec_kbd = x;
4107 #endif /* UNICODE */
4108 for (i = 0; i < 4; i++) {
4109 G[i].init = TRUE;
4110 if ( i == 0 && !cs_is_nrc(x) ) {
4111 G[0].designation = G[0].def_designation = FC_USASCII;
4112 G[0].size = G[0].def_size = cs94;
4113 G[0].national = 1;
4114 } else {
4115 G[i].def_designation = G[i].designation = x;
4116 switch (cs_size(x)) { /* 94, 96, or 128 */
4117 case 128:
4118 case 96:
4119 G[i].size = G[i].def_size = cs96;
4120 break;
4121 case 94:
4122 G[i].size = G[i].def_size = cs94;
4123 break;
4124 default:
4125 G[i].size = G[i].def_size = csmb;
4126 break;
4127 }
4128 G[i].national = cs_is_nrc(x);
4129 }
4130 G[i].c1 = G[i].def_c1 = x != tcsl && cs_is_std(x);
4131 }
4132 #ifdef UNICODE
4133 } else if (z == TT_GR_KBD) { /* Keyboard only */
4134 dec_kbd = x;
4135 #endif /* UNICODE */
4136 } else { /* Specific Gn */
4137 G[z].def_designation = G[z].designation = x;
4138 G[z].init = TRUE;
4139 switch (cs_size(x)) { /* 94, 96, or 128 */
4140 case 128:
4141 case 96:
4142 G[z].size = G[z].def_size = cs96;
4143 break;
4144 case 94:
4145 G[z].size = G[z].def_size = cs94;
4146 break;
4147 default:
4148 G[z].size = G[z].def_size = csmb;
4149 break;
4150 }
4151 G[z].c1 = G[z].def_c1 = x != tcsl && cs_is_std(x);
4152 G[z].national = cs_is_nrc(x);
4153 }
4154 }
4155 #else /* not OS2 */
4156 tcsr = x; /* Remote character set */
4157 #endif /* OS2 */
4158 }
4159 #endif /* NOCSETS */
4160
4161 VOID
setcmask(x)4162 setcmask(x) int x; {
4163 if (x == 7) {
4164 cmask = 0177;
4165 } else if (x == 8) {
4166 cmask = 0377;
4167 parity = 0;
4168 }
4169 #ifdef KUI
4170 KuiSetProperty(KUI_TERM_CMASK,x,0);
4171 #endif /* KUI */
4172 }
4173
4174 #ifdef CK_AUTODL
4175 VOID
setautodl(x,y)4176 setautodl(x,y) int x,y; {
4177 autodl = x;
4178 adl_ask = y;
4179 #ifdef KUI
4180 KuiSetProperty(KUI_TERM_AUTODOWNLOAD,x?(y?2:1):0,0);
4181 #endif /* KUI */
4182 }
4183 #endif /* CK_AUTODL */
4184
4185 #ifdef OS2
4186 VOID
seturlhl(int x)4187 seturlhl(int x) {
4188 tt_url_hilite = x;
4189 #ifdef KUI
4190 KuiSetProperty(KUI_TERM_URL_HIGHLIGHT,x,0);
4191 #endif /* KUI */
4192 }
4193
4194 VOID
setaprint(int x)4195 setaprint(int x) {
4196 extern int aprint;
4197 aprint = x;
4198 #ifdef KUI
4199 KuiSetProperty(KUI_TERM_PRINTERCOPY,x,0);
4200 #endif /* KUI */
4201 }
4202 #endif /* OS2 */
4203
4204 int
settrm()4205 settrm() {
4206 int i = 0;
4207 #ifdef OS2
4208 extern int colorreset, user_erasemode;
4209 #endif /* OS2 */
4210 if ((y = cmkey(trmtab,ntrm,"", "",xxstring)) < 0) return(y);
4211 #ifdef MAC
4212 printf("\n?Sorry, not implemented yet. Please use the Settings menu.\n");
4213 return(-9);
4214 #else
4215 #ifdef IKSD
4216 if (inserver) {
4217 if ((y = cmcfm()) < 0) return(y);
4218 printf("?Sorry, command disabled.\r\n");
4219 return(success = 0);
4220 }
4221 #endif /* IKSD */
4222
4223 switch (y) {
4224 case XYTBYT: /* SET TERMINAL BYTESIZE */
4225 if ((y = cmnum("bytesize for terminal connection","8",10,&x,
4226 xxstring)) < 0)
4227 return(y);
4228 if (x != 7 && x != 8) {
4229 printf("\n?The choices are 7 and 8\n");
4230 return(success = 0);
4231 }
4232 if ((y = cmcfm()) < 0) return(y);
4233 setcmask(x);
4234 #ifdef OS2
4235 if (IS97801(tt_type_mode))
4236 SNI_bitmode(x);
4237 #endif /* OS2 */
4238 return(success = 1);
4239
4240 case XYTSO: /* SET TERMINAL LOCKING-SHIFT */
4241 return(seton(&sosi));
4242
4243 case XYTNL: /* SET TERMINAL NEWLINE-MODE */
4244 return(seton(&tnlm));
4245
4246 #ifdef OS2
4247 case XYTCOL:
4248 if ((x = cmkey(ttycoltab,ncolors,"","terminal",xxstring)) < 0)
4249 return(x);
4250 else if (x == TTCOLRES) {
4251 if ((y = cmkey(ttcolmodetab,ncolmode,
4252 "","default-color",xxstring)) < 0)
4253 return(y);
4254 if ((z = cmcfm()) < 0)
4255 return(z);
4256 colorreset = y;
4257 return(success = 1);
4258 } else if (x == TTCOLERA) {
4259 if ((y = cmkey(ttcolmodetab,ncolmode,"",
4260 "current-color",xxstring)) < 0)
4261 return(y);
4262 if ((z = cmcfm()) < 0)
4263 return(z);
4264 user_erasemode = y;
4265 return(success=1);
4266 } else { /* No parse error */
4267 int fg = 0, bg = 0;
4268 fg = cmkey(ttyclrtab, nclrs,
4269 (x == TTCOLBOR ?
4270 "color for screen border" :
4271 "foreground color and then background color"),
4272 "lgray", xxstring);
4273 if (fg < 0)
4274 return(fg);
4275 if (x != TTCOLBOR) {
4276 if ((bg = cmkey(ttyclrtab,nclrs,
4277 "background color","blue",xxstring)) < 0)
4278 return(bg);
4279 }
4280 if ((y = cmcfm()) < 0)
4281 return(y);
4282 switch (x) {
4283 case TTCOLNOR:
4284 colornormal = fg | bg << 4;
4285 fgi = fg & 0x08;
4286 bgi = bg & 0x08;
4287 break;
4288 case TTCOLREV:
4289 colorreverse = fg | bg << 4;
4290 break;
4291 case TTCOLITA:
4292 coloritalic = fg | bg << 4;
4293 break;
4294 case TTCOLUND:
4295 colorunderline = fg | bg << 4;
4296 break;
4297 case TTCOLGRP:
4298 colorgraphic = fg | bg << 4;
4299 break;
4300 case TTCOLDEB:
4301 colordebug = fg | bg << 4;
4302 break;
4303 case TTCOLSTA:
4304 colorstatus = fg | bg << 4;
4305 break;
4306 case TTCOLHLP:
4307 colorhelp = fg | bg << 4;
4308 break;
4309 case TTCOLBOR:
4310 colorborder = fg;
4311 break;
4312 case TTCOLSEL:
4313 colorselect = fg | bg << 4;
4314 break;
4315 default:
4316 printf("%s - invalid\n",cmdbuf);
4317 return(-9);
4318 break;
4319 }
4320 scrninitialized[VTERM] = 0;
4321 VscrnInit(VTERM);
4322 }
4323 return(success = 1);
4324
4325 case XYTCUR: { /* SET TERMINAL CURSOR */
4326 extern int cursorena[];
4327 extern int cursoron[] ; /* Cursor state on/off */
4328 if ((x = cmkey(ttycurtab,ncursors,"","underline",xxstring)) < 0)
4329 return(x);
4330 if ((z = cmkey(curontab,ncuron,"","on",xxstring)) < 0)
4331 return(z);
4332 if ((y = cmcfm()) < 0) return(y);
4333 tt_cursor = tt_cursor_usr = x;
4334 if ( z == 2 ) {
4335 cursorena[VTERM] = tt_cursorena_usr = 1;
4336 tt_cursor_blink = 0;
4337 } else {
4338 cursorena[VTERM] = tt_cursorena_usr = z;/* turn cursor on/off */
4339 tt_cursor_blink = 1;
4340 }
4341 cursoron[VTERM] = FALSE; /* Force newcursor to restore the cursor */
4342 return(success = 1);
4343 }
4344 #endif /* OS2 */
4345
4346 case XYTTYP: /* SET TERMINAL TYPE */
4347 return(settrmtyp());
4348
4349 #ifdef OS2
4350 case XYTARR: /* SET TERMINAL ARROW-KEYS */
4351 if ((x = cmkey(akmtab,2,"","",xxstring)) < 0) return(x);
4352 if ((y = cmcfm()) < 0) return(y);
4353 tt_arrow = x; /* TTK_NORM / TTK_APPL; see ckuusr.h */
4354 return(success = 1);
4355
4356 case XYTKPD: /* SET TERMINAL KEYPAD-MODE */
4357 if ((x = cmkey(kpmtab,2,"","",xxstring)) < 0) return(x);
4358 if ((y = cmcfm()) < 0) return(y);
4359 tt_keypad = x; /* TTK_NORM / TTK_APPL; see ckuusr.h */
4360 return(success = 1);
4361
4362 case XYTUNX: { /* SET TERM UNIX-MODE (DG) */
4363 extern int dgunix,dgunix_usr;
4364 x = seton(&dgunix);
4365 dgunix_usr = dgunix;
4366 return(x);
4367 }
4368 case XYTKBMOD: { /* SET TERM KEYBOARD MODE */
4369 extern int tt_kb_mode;
4370 if ((x = cmkey(kbmodtab,
4371 nkbmodtab,
4372 "normal",
4373 "special keyboard mode for terminal emulation",
4374 xxstring)
4375 ) < 0)
4376 return(x);
4377 if ((y = cmcfm()) < 0) return(y);
4378 tt_kb_mode = x;
4379 return(success = 1);
4380 }
4381
4382 case XYTWRP: /* SET TERMINAL WRAP */
4383 return(seton(&tt_wrap));
4384
4385 case XYSCRS:
4386 if ((y = cmnum("CONNECT scrollback buffer size, lines","2000",10,&x,
4387 xxstring)) < 0)
4388 return(y);
4389 /* The max number of lines is the RAM */
4390 /* we can actually dedicate to a */
4391 /* scrollback buffer given the maximum */
4392 /* process memory space of 512MB */
4393 if (x < 256 || x > 2000000L) {
4394 printf("\n?The size must be between 256 and 2,000,000.\n");
4395 return(success = 0);
4396 }
4397 if ((y = cmcfm()) < 0) return(y);
4398 tt_scrsize[VTERM] = x;
4399 VscrnInit(VTERM);
4400 return(success = 1);
4401 #endif /* OS2 */
4402
4403 #ifndef NOCSETS
4404 case XYTCS: { /* SET TERMINAL CHARACTER-SET */
4405 int eol;
4406 /* set terminal character-set <remote> <local> */
4407 if ((x = cmkey(
4408 #ifdef CKOUNI
4409 txrtab,ntxrtab,
4410 #else /* CKOUNI */
4411 ttcstab,ntermc,
4412 #endif /* CKOUNI */
4413 "remote terminal character-set","",xxstring)) < 0)
4414 return(x);
4415
4416 #ifdef UNICODE
4417 if (x == TX_TRANSP
4418 #ifdef CKOUNI
4419 || x == TX_UTF8
4420 #endif /* CKOUNI */
4421 ) {
4422 if ((y = cmcfm()) < 0) /* Confirm the command */
4423 return(y);
4424 #ifdef OS2
4425 if ( isunicode() && x == TX_TRANSP ) {
4426 /* If we are in unicode display mode then transparent
4427 * only affects the output direction. We need to know
4428 * the actual remote character set in order to perform
4429 * the tcsr -> ucs2 translation for display.
4430 */
4431 x = y = tcsl;
4432 } else
4433 #endif /* OS2 */
4434 y = x;
4435 }
4436 #else /* UNICODE */
4437 if (x == FC_TRANSP) {
4438 if ((y = cmcfm()) < 0) /* Confirm the command */
4439 return(y);
4440 y = x;
4441 }
4442 #endif /* UNICODE */
4443
4444 /* Not transparent or UTF8, so get local set to translate it into */
4445 s = "";
4446 #ifdef OS2
4447 y = os2getcp(); /* Default is current code page */
4448 switch (y) {
4449 case 437: s = "cp437"; break;
4450 case 850: s = "cp850"; break;
4451 case 852: s = "cp852"; break;
4452 case 857: s = "cp857"; break;
4453 case 858: s = "cp858"; break;
4454 case 862: s = "cp862"; break;
4455 case 866: s = "cp866"; break;
4456 case 869: s = "cp869"; break;
4457 case 1250: s = "cp1250"; break;
4458 case 1251: s = "cp1251"; break;
4459 case 1252: s = "cp1252"; break;
4460 case 1253: s = "cp1253"; break;
4461 case 1254: s = "cp1254"; break;
4462 case 1255: s = "cp1255"; break;
4463 case 1256: s = "cp1256"; break;
4464 case 1257: s = "cp1257"; break;
4465 case 1258: s = "cp1258"; break;
4466 }
4467 #ifdef PCFONTS
4468 /*
4469 If the user has loaded a font with SET TERMINAL FONT then we want
4470 to change the default code page to the font that was loaded.
4471 */
4472 if (tt_font != TTF_ROM) {
4473 for (y = 0; y < ntermfont; y++ ) {
4474 if (term_font[y].kwval == tt_font) {
4475 s = term_font[y].kwd;
4476 break;
4477 }
4478 }
4479 }
4480 #endif /* PCFONTS */
4481 #else /* Not K95... */
4482 s = fcsinfo[fcharset].keyword;
4483 #endif /* OS2 */
4484
4485 if ((y = cmkey(
4486 #ifdef CKOUNI
4487 txrtab,ntxrtab,
4488 #else /* CKOUNI */
4489 ttcstab,ntermc,
4490 #endif /* CKOUNI */
4491 "local character-set",s,xxstring)) < 0)
4492 return(y);
4493
4494 #ifdef UNICODE
4495 if (y == TX_UTF8) {
4496 printf("?UTF8 may not be used as a local character set.\r\n");
4497 return(-9);
4498 }
4499 #endif /* UNICODE */
4500 #ifdef OS2
4501 if ((z = cmkey(graphsettab,ngraphset,
4502 "DEC VT intermediate graphic set","all",xxstring)) < 0)
4503 return(z);
4504 #endif /* OS2 */
4505 if ((eol = cmcfm()) < 0)
4506 return(eol); /* Confirm the command */
4507
4508 /* End of command parsing - actions begin */
4509 setlclcharset(y);
4510 setremcharset(x,z);
4511 return(success = 1);
4512 }
4513 #endif /* NOCSETS */
4514
4515 #ifndef NOCSETS
4516 case XYTLCS: /* SET TERMINAL LOCAL-CHARACTER-SET */
4517 /* set terminal character-set <local> */
4518 s = getdcset(); /* Get display character-set name */
4519 if ((y = cmkey(
4520 #ifdef CKOUNI
4521 txrtab,ntxrtab,
4522 #else /* CKOUNI */
4523 fcstab,nfilc,
4524 #endif /* CKOUNI */
4525 "local character-set",s,xxstring)) < 0)
4526 return(y);
4527
4528 #ifdef UNICODE
4529 if (y == TX_UTF8) {
4530 printf("?UTF8 may not be used as a local character set.\r\n");
4531 return(-9);
4532 }
4533 #endif /* UNICODE */
4534 if ((z = cmcfm()) < 0) return(z); /* Confirm the command */
4535
4536 /* End of command parsing - action begins */
4537
4538 setlclcharset(y);
4539 return(success = 1);
4540 #endif /* NOCSETS */
4541
4542 #ifndef NOCSETS
4543 #ifdef UNICODE
4544 case XYTUNI: /* SET TERMINAL UNICODE */
4545 return(seton(&tt_unicode));
4546 #endif /* UNICODE */
4547
4548 case XYTRCS: /* SET TERMINAL REMOTE-CHARACTER-SET */
4549 /* set terminal character-set <remote> <Graphic-set> */
4550 if ((x = cmkey(
4551 #ifdef CKOUNI
4552 txrtab, ntxrtab,
4553 #else /* CKOUNI */
4554 ttcstab,ntermc,
4555 #endif /* CKOUNI */
4556 "remote terminal character-set","",xxstring)) < 0)
4557 return(x);
4558
4559 #ifdef UNICODE
4560 if (x == TX_TRANSP
4561 #ifdef CKOUNI
4562 || x == TX_UTF8
4563 #endif /* CKOUNI */
4564 ) {
4565 if ((y = cmcfm()) < 0) /* Confirm the command */
4566 return(y);
4567 #ifdef OS2
4568 if ( isunicode() && x == TX_TRANSP ) {
4569 /* If we are in unicode display mode then transparent
4570 * only affects the output direction. We need to know
4571 * the actual remote character set in order to perform
4572 * the tcsr -> ucs2 translation for display.
4573 */
4574 x = tcsl;
4575 }
4576 #endif /* OS2 */
4577 }
4578 #else /* UNICODE */
4579 if (x == FC_TRANSP) {
4580 if ((y = cmcfm()) < 0) /* Confirm the command */
4581 return(y);
4582 }
4583 #endif /* UNICODE */
4584 else {
4585 #ifdef OS2
4586 if ((z = cmkey(graphsettab,ngraphset,
4587 "DEC VT intermediate graphic set","all",xxstring)) < 0)
4588 return(z);
4589 #endif /* OS2 */
4590 if ((y = cmcfm()) < 0) /* Confirm the command */
4591 return(y);
4592 }
4593 /* Command parsing ends here */
4594
4595 setremcharset(x,z);
4596 return(success = 1);
4597 #endif /* NOCSETS */
4598
4599 case XYTEC: /* SET TERMINAL ECHO */
4600 if ((x = cmkey(rltab,nrlt,"which side echos during CONNECT",
4601 "remote", xxstring)) < 0) return(x);
4602 if ((y = cmcfm()) < 0) return(y);
4603 #ifdef NETCONN
4604 oldplex = x;
4605 #endif /* NETCONN */
4606 duplex = x;
4607 return(success = 1);
4608
4609 case XYTESC: /* SET TERM ESC */
4610 if ((x = cmkey(nabltab,nnabltab,"","enabled",xxstring)) < 0)
4611 return(x);
4612 if ((y = cmcfm()) < 0) return(y);
4613 tt_escape = x;
4614 return(1);
4615
4616 case XYTCRD: /* SET TERMINAL CR-DISPLAY */
4617 if ((x = cmkey(crdtab,2,"", "normal", xxstring)) < 0) return(x);
4618 if ((y = cmcfm()) < 0) return(y);
4619 tt_crd = x;
4620 return(success = 1);
4621
4622 case XYTLFD: /* SET TERMINAL LF-DISPLAY */
4623 if ((x = cmkey(crdtab,2,"", "normal", xxstring)) < 0) return(x);
4624 if ((y = cmcfm()) < 0) return(y);
4625 tt_lfd = x;
4626 return(success = 1);
4627
4628 #ifdef OS2
4629 case XYTANS: { /* SET TERMINAL ANSWERBACK */
4630 /*
4631 NOTE: We let them enable and disable the answerback sequence, but we
4632 do NOT let them change it, and we definitely do not let the host set it.
4633 This is a security feature.
4634
4635 As of 1.1.8 we allow the SET TERM ANSWERBACK MESSAGE <string> to be
4636 used just as MS-DOS Kermit does. C0 and C1 controls as well as DEL
4637 are not allowed to be used as characters. They are translated to
4638 underscore. This may not be set by APC.
4639 */
4640 if ((x = cmkey(anbktab,nansbk,"", "off", xxstring)) < 0)
4641 return(x);
4642 if (x < 2) {
4643 if ((y = cmcfm()) < 0)
4644 return(y);
4645 tt_answer = x;
4646 return(success = 1);
4647 } else if ( x == 2 || x == 3) {
4648 int len = 0;
4649 extern int safeanswerbk;
4650 extern char useranswerbk[];
4651 if ((y = cmtxt("Answerback extension","",&s,xxstring)) < 0)
4652 return(y);
4653 if (apcactive == APC_LOCAL ||
4654 (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH)))
4655 return(success = 0);
4656 len = strlen(s);
4657 if (x == 2) {
4658 /* Safe Answerback's don't have C0/C1 chars */
4659 for (z = 0; z < len; z++) {
4660 if ((s[z] & 0x7F) <= SP || (s[z] & 0x7F) == DEL)
4661 useranswerbk[z] = '_';
4662 else
4663 useranswerbk[z] = s[z];
4664 }
4665 useranswerbk[z] = '\0';
4666 safeanswerbk = 1 ; /* TRUE */
4667 } else {
4668 ckstrncpy(useranswerbk,s,60); /* (see ckocon.c) */
4669 safeanswerbk = 0; /* FALSE */
4670 }
4671 updanswerbk();
4672 return(success = 1);
4673 } else
4674 return(success = 0);
4675 }
4676 #endif /* OS2 */
4677
4678 #ifdef CK_APC
4679 case XYTAPC:
4680 if ((y = cmkey(apctab,napctab,
4681 "application program command execution","",
4682 xxstring)) < 0)
4683 return(y);
4684 if ((x = cmcfm()) < 0)
4685 return(x);
4686 if (apcactive == APC_LOCAL ||
4687 (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH)))
4688 return(success = 0);
4689 apcstatus = y;
4690 return(success = 1);
4691
4692 #ifdef CK_AUTODL
4693 case XYTAUTODL: /* AUTODOWNLOAD */
4694 if ((y = cmkey(adltab,nadltab,"Auto-download options","",
4695 xxstring)) < 0)
4696 return(y);
4697 switch (y) {
4698 case TAD_ON:
4699 case TAD_OFF:
4700 if ((x = cmcfm()) < 0)
4701 return(x);
4702 setautodl(y,0);
4703 break;
4704 case TAD_ASK:
4705 if ((x = cmcfm()) < 0)
4706 return(x);
4707 setautodl(TAD_ON,1);
4708 break;
4709 case TAD_ERR:
4710 if ((y = cmkey(adlerrtab,nadlerrtab,"","", xxstring)) < 0)
4711 return(y);
4712 if ((x = cmcfm()) < 0)
4713 return(x);
4714 adl_err = y;
4715 break;
4716 #ifdef OS2
4717 case TAD_K:
4718 if ((y = cmkey(adlxtab,nadlxtab,"","", xxstring)) < 0)
4719 return(y);
4720 switch (y) {
4721 case TAD_X_C0:
4722 if ((y = cmkey(adlc0tab,nadlc0tab,"",
4723 "processed-by-emulator",xxstring)) < 0)
4724 return(y);
4725 if ((x = cmcfm()) < 0)
4726 return(x);
4727 adl_kc0 = y;
4728 break;
4729 case TAD_X_DETECT:
4730 if ((y = cmkey(adldtab,nadldtab,"","packet",xxstring)) < 0)
4731 return(y);
4732 if ((x = cmcfm()) < 0)
4733 return(x);
4734 adl_kmode = y;
4735 break;
4736 case TAD_X_STR:
4737 if ((y = cmtxt("Kermit start string","KERMIT READY TO SEND...",
4738 &s,xxstring)) < 0)
4739 return(y);
4740 free(adl_kstr);
4741 adl_kstr = strdup(s);
4742 break;
4743 }
4744 break;
4745
4746 case TAD_Z:
4747 if ((y = cmkey(adlxtab,nadlxtab,"","",xxstring)) < 0)
4748 return(y);
4749 switch (y) {
4750 case TAD_X_C0:
4751 if ((y = cmkey(adlc0tab,nadlc0tab,"",
4752 "processed-by-emulator",xxstring)) < 0)
4753 return(y);
4754 if ((x = cmcfm()) < 0)
4755 return(x);
4756 adl_zc0 = y;
4757 break;
4758 case TAD_X_DETECT:
4759 if ((y = cmkey(adldtab,nadldtab,"","packet",xxstring)) < 0)
4760 return(y);
4761 if ((x = cmcfm()) < 0)
4762 return(x);
4763 adl_zmode = y;
4764 break;
4765 case TAD_X_STR:
4766 if ((y = cmtxt("","rz\\{13}",&s,xxstring)) < 0)
4767 return(y);
4768 free(adl_zstr);
4769 adl_zstr = strdup(s);
4770 break;
4771 }
4772 break;
4773 #endif /* OS2 */
4774 }
4775 return(success = 1);
4776
4777 #endif /* CK_AUTODL */
4778 #endif /* CK_APC */
4779
4780 #ifdef OS2
4781 case XYTBEL:
4782 return(success = setbell());
4783
4784 case XYTMBEL: /* MARGIN-BELL */
4785 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
4786 if (y) { /* ON */
4787 if ((z = cmnum("Column at which to set margin bell",
4788 "72",10,&x,xxstring)) < 0)
4789 return(z);
4790 }
4791 if ((z = cmcfm()) < 0) return(z);
4792 marginbell = y;
4793 marginbellcol = x;
4794 return(success = 1);
4795 #endif /* OS2 */
4796
4797 #ifdef CKTIDLE
4798 case XYTIDLE: /* IDLE-SEND */
4799 case XYTITMO: /* IDLE-TIMEOUT */
4800 if ((z = cmnum("seconds of idle time to wait, or 0 to disable",
4801 "0",10,&x,xxstring)) < 0)
4802 return(z);
4803 if (y == XYTIDLE) {
4804 if ((y = cmtxt("string to send, may contain kverbs and variables",
4805 "\\v(newline)",&s,xxstring)) < 0)
4806 return(y);
4807 tt_idlesnd_tmo = x; /* (old) */
4808 tt_idlelimit = x; /* (new) */
4809 makestr(&tt_idlestr,brstrip(s)); /* (new) */
4810 tt_idlesnd_str = tt_idlestr; /* (old) */
4811 tt_idleact = IDLE_OUT; /* (new) */
4812 } else {
4813 if ((y = cmcfm()) < 0)
4814 return(y);
4815 tt_idlelimit = x;
4816 }
4817 #ifdef OS2
4818 puterror(VTERM);
4819 #endif /* OS2 */
4820 return(success = 1);
4821
4822 case XYTIACT: { /* SET TERM IDLE-ACTION */
4823 if ((y = cmkey(idlacts,nidlacts,"","",xxstring)) < 0)
4824 return(y);
4825 if (y == IDLE_OUT) {
4826 if ((x = cmtxt("string to send, may contain kverbs and variables"
4827 , "",&s,xxstring)) < 0)
4828 return(x);
4829 makestr(&tt_idlestr,brstrip(s)); /* (new) */
4830 tt_idlesnd_str = tt_idlestr; /* (old) */
4831 } else {
4832 if ((x = cmcfm()) < 0)
4833 return(x);
4834 }
4835 tt_idleact = y;
4836 return(success = 1);
4837 }
4838 #endif /* CKTIDLE */
4839
4840 case XYTDEB: /* TERMINAL DEBUG */
4841 y = seton(&x); /* Go parse ON or OFF */
4842 if (y > 0) /* Command succeeded? */
4843 setdebses(x);
4844 return(y);
4845
4846 #ifdef OS2
4847 case XYTASCRL: /* SET TERMINAL AUTOSCROLL */
4848 y = seton(&autoscroll);
4849 return(y);
4850
4851 case XYTAPAGE: /* SET TERMINAL AUTOPAGE */
4852 y = seton(&wy_autopage);
4853 return(y);
4854
4855 case XYTROL: /* SET TERMINAL ROLL */
4856 if ((y = cmkey(rolltab,nroll,"scrollback mode","insert",xxstring))<0)
4857 return(y);
4858 if (y == TTR_KEYS) {
4859 if ((x = cmkey(rollkeytab,nrollkey,"","send",xxstring))<0)
4860 return(x);
4861 if ((z = cmcfm()) < 0) return(z);
4862 tt_rkeys[VTERM] = x;
4863 } else {
4864 if ((x = cmcfm()) < 0) return(x);
4865 tt_roll[VTERM] = y;
4866 }
4867 return(success = 1);
4868
4869 case XYTCTS: /* SET TERMINAL TRANSMIT-TIMEOUT */
4870 y = cmnum("Maximum seconds to allow CTS off during CONNECT",
4871 "5",10,&x,xxstring);
4872 return(setnum(&tt_ctstmo,x,y,10000));
4873
4874 case XYTCPG: { /* SET TERMINAL CODE-PAGE */
4875 int i;
4876 int cp = -1;
4877 y = cmnum("PC code page to use during terminal emulation",
4878 ckitoa(os2getcp()),10,&x,xxstring);
4879 if ((x = setnum(&cp,x,y,11000)) < 0) return(x);
4880 if (os2setcp(cp) != 1) {
4881 #ifdef NT
4882 if (isWin95())
4883 printf(
4884 "Sorry, Windows 95 does not support code page switching\n");
4885 else
4886 #endif /* NT */
4887 printf(
4888 "Sorry, %d is not a valid code page for this system.\n",cp);
4889 return(-9);
4890 }
4891 /* Force the terminal character-sets conversions to be updated */
4892 for ( i = 0; i < 4; i++ )
4893 G[i].init = TRUE;
4894 return(1);
4895 }
4896
4897 case XYTPAC: /* SET TERMINAL OUTPUT-PACING */
4898 y = cmnum(
4899 "Pause between sending each character during CONNECT, milliseconds",
4900 "-1",10,&x,xxstring);
4901 return(setnum(&tt_pacing,x,y,10000));
4902
4903 #ifdef OS2MOUSE
4904 case XYTMOU: { /* SET TERMINAL MOUSE */
4905 int old_mou = tt_mouse;
4906 if ((x = seton(&tt_mouse)) < 0)
4907 return(x);
4908 if (tt_mouse != old_mou)
4909 if (tt_mouse)
4910 os2_mouseon();
4911 else
4912 os2_mouseoff();
4913 return(1);
4914 }
4915 #endif /* OS2MOUSE */
4916 #endif /* OS2 */
4917
4918 case XYTWID: {
4919 if ((y = cmnum(
4920 #ifdef OS2
4921 "number of columns in display window during CONNECT",
4922 #else
4923 "number of columns on your screen",
4924 #endif /* OS2 */
4925 "80",10,&x,xxstring)) < 0)
4926 return(y);
4927 if ((y = cmcfm()) < 0) return(y);
4928 #ifdef OS2
4929 return(success = os2_settermwidth(x));
4930 #else /* Not OS/2 */
4931 tt_cols = x;
4932 return(success = 1);
4933 #endif /* OS2 */
4934 }
4935
4936 case XYTHIG:
4937 if ((y = cmnum(
4938 #ifdef OS2
4939 "number of rows in display window during CONNECT, not including status line",
4940 tt_status[VTERM]?"24":"25",
4941 #else
4942 "24","number of rows on your screen",
4943 #endif /* OS2 */
4944 10,&x,xxstring)) < 0)
4945 return(y);
4946 if ((y = cmcfm()) < 0) return(y);
4947
4948 #ifdef OS2
4949 return (success = os2_settermheight(x));
4950 #else /* Not OS/2 */
4951 tt_rows = x;
4952 return(success = 1);
4953 #endif /* OS2 */
4954
4955 #ifdef OS2
4956 case XYTPRN: { /* Print Mode */
4957 extern bool xprint, aprint, cprint, uprint;
4958 if ((y = cmkey(prnmtab,nprnmtab,"","off", xxstring)) < 0) return(y);
4959 if ((x = cmcfm()) < 0) return(x);
4960 switch (y) {
4961 case 0:
4962 if (cprint || uprint || aprint || xprint)
4963 printeroff();
4964 cprint = xprint = uprint = 0;
4965 setaprint(0);
4966 break;
4967 case 1:
4968 if (!(cprint || uprint || aprint || xprint))
4969 printeron();
4970 setaprint(1);
4971 cprint = xprint = uprint = 0;
4972 break;
4973 case 2:
4974 if (!(cprint || uprint || aprint || xprint))
4975 printeron();
4976 cprint = 1;
4977 setaprint(0);
4978 xprint = uprint = 0;
4979 break;
4980 case 3:
4981 if (!(cprint || uprint || aprint || xprint))
4982 printeron();
4983 uprint = 1;
4984 setaprint(0);
4985 xprint = cprint = 0;
4986 break;
4987 }
4988 return(1);
4989 }
4990 #else
4991 #ifdef XPRINT
4992 case XYTPRN: {
4993 extern int tt_print;
4994 if ((x = seton(&tt_print)) < 0)
4995 return(x);
4996 return(success = 1);
4997 }
4998 #endif /* XPRINT */
4999 #endif /* OS2 */
5000
5001 #ifdef OS2
5002 case XYTSCNM: {
5003 extern int decscnm, decscnm_usr;
5004 if ((y = cmkey(normrev,4,"",
5005 decscnm_usr?"reverse":"normal",
5006 xxstring)
5007 ) < 0)
5008 return(y);
5009 if ((x = cmcfm()) < 0) return(x);
5010 decscnm_usr = y;
5011 if (decscnm != decscnm_usr)
5012 flipscreen(VTERM);
5013 return(1);
5014 }
5015 case XYTOPTI:
5016 if ((y = cmkey(onoff,2,"",tt_diff_upd?"on":"off",
5017 xxstring)) < 0) return(y);
5018 if ((x = cmcfm()) < 0) return(x);
5019 tt_diff_upd = y;
5020 return(1);
5021 case XYTUPD: {
5022 int mode, delay;
5023 if ((mode = cmkey(scrnupd,nscrnupd,"","fast",xxstring)) < 0) {
5024 return(mode);
5025 } else {
5026 y = cmnum(
5027 "Pause between FAST screen updates in CONNECT mode, milliseconds",
5028 "100",10,&x,xxstring
5029 );
5030 if (x < 0 || x > 1000 ) {
5031 printf(
5032 "\n?The update rate must be between 0 and 1000 milliseconds.\n"
5033 );
5034 return(success = 0);
5035 }
5036 if ((y = cmcfm()) < 0) return(y);
5037
5038 updmode = tt_updmode = mode;
5039 return(setnum(&tt_update,x,y,10000));
5040 }
5041 }
5042 case XYTCTRL:
5043 if ((x = cmkey(termctrl,ntermctrl,"","7",xxstring)) < 0) {
5044 return(x);
5045 } else {
5046 if ((y = cmcfm()) < 0)
5047 return(y);
5048 switch ( x ) {
5049 case 8:
5050 send_c1 = send_c1_usr = TRUE;
5051 break;
5052 case 7:
5053 default:
5054 send_c1 = send_c1_usr = FALSE;
5055 break;
5056 }
5057 }
5058 return(success = TRUE);
5059 break;
5060
5061 #ifdef PCFONTS
5062 case XYTFON:
5063 if ( !IsOS2FullScreen() ) {
5064 printf(
5065 "\n?SET TERMINAL FONT is only supported in Full Screen sessions.\n");
5066 return(success = FALSE);
5067 }
5068
5069 if ((x = cmkey(term_font,ntermfont,"","default",xxstring)) < 0) {
5070 return(x);
5071 } else {
5072 if ((y = cmcfm()) < 0) return(y);
5073 if ( !os2LoadPCFonts() ) {
5074 tt_font = x;
5075 return(success = TRUE);
5076 } else {
5077 printf(
5078 "\n?PCFONTS.DLL is not available in CKERMIT executable directory.\n");
5079 return(success = FALSE);
5080 }
5081 }
5082 break;
5083 #else /* PCFONTS */
5084 #ifdef NT
5085 #ifdef KUI
5086 case XYTFON:
5087 return(setguifont()); /* ckuus3.c */
5088 #endif /* KUI */
5089 #endif /* NT */
5090 #endif /* PCFONTS */
5091
5092 case XYTVCH: {
5093 extern int pheight, marginbot, cmd_rows, cmd_cols;
5094 if ((x = cmkey(tvctab,ntvctab,"",isWin95()?"win95-safe":"enabled",
5095 xxstring)) < 0)
5096 return(x);
5097 if ((y = cmcfm()) < 0) return(y);
5098 #ifndef KUI
5099 if (x != tt_modechg) {
5100 switch (x) {
5101 case TVC_DIS:
5102 /* When disabled the heights of all of the virtual screens */
5103 /* must be equal to the physical height of the console */
5104 /* window and may not be changed. */
5105 /* The width of the window may not be altered. */
5106 tt_modechg = TVC_ENA; /* Temporary */
5107 if (marginbot > pheight-(tt_status[VTERM]?1:0))
5108 marginbot = pheight-(tt_status[VTERM]?1:0);
5109 tt_szchng[VCMD] = 1 ;
5110 tt_rows[VCMD] = pheight;
5111 VscrnInit(VCMD);
5112 SetCols(VCMD);
5113 cmd_rows = y;
5114
5115 tt_szchng[VTERM] = 2 ;
5116 tt_rows[VTERM] = pheight - (tt_status[VTERM]?1:0);
5117 VscrnInit(VTERM);
5118
5119 break;
5120
5121 case TVC_ENA:
5122 /* When enabled the physical height of the console windows */
5123 /* should be adjusted to the height of the virtual screen */
5124 /* The width may be set to anything. */
5125 /* nothing to do */
5126 break;
5127
5128 case TVC_W95:
5129 /* Win95-safe mode allows the physical height to change */
5130 /* but restricts it to a width of 80 and a height equal to */
5131 /* 25, 43, or 50. Must be adjusted now. */
5132 /* The virtual heights must be equal to the above. */
5133 if (pheight != 25 && pheight != 43 && pheight != 50) {
5134 if (pheight < 25)
5135 y = 25;
5136 else if (pheight < 43)
5137 y = 43;
5138 else
5139 y = 50;
5140 } else
5141 y = pheight;
5142
5143 tt_modechg = TVC_ENA; /* Temporary */
5144
5145 tt_szchng[VCMD] = 1;
5146 tt_rows[VCMD] = y;
5147 tt_cols[VCMD] = 80;
5148 VscrnInit(VCMD);
5149 SetCols(VCMD);
5150 cmd_rows = y;
5151 cmd_cols = 80;
5152
5153 marginbot = y-(tt_status[VTERM]?1:0);
5154 tt_szchng[VTERM] = 2;
5155 tt_rows[VTERM] = y - (tt_status[VTERM]?1:0);
5156 tt_cols[VTERM] = 80;
5157 VscrnInit(VTERM);
5158 break;
5159 }
5160 tt_modechg = x;
5161 }
5162 return(success = 1);
5163 #else
5164 return(success = 0);
5165 #endif /* KUI */
5166 }
5167 case XYTSTAT: {
5168 extern int marginbot;
5169 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5170 if ((x = cmcfm()) < 0) return(x);
5171 if (y != tt_status[VTERM] || y != tt_status_usr[VTERM]) {
5172 /* Might need to fixup the margins */
5173 if ( marginbot == VscrnGetHeight(VTERM)-(tt_status[VTERM]?1:0) )
5174 if (y) {
5175 marginbot--;
5176 } else {
5177 marginbot++;
5178 }
5179 tt_status_usr[VTERM] = tt_status[VTERM] = y;
5180 if (y) {
5181 tt_szchng[VTERM] = 2;
5182 tt_rows[VTERM]--;
5183 VscrnInit(VTERM); /* Height set here */
5184 #ifdef TNCODE
5185 if (TELOPT_ME(TELOPT_NAWS))
5186 tn_snaws();
5187 #endif /* TNCODE */
5188 #ifdef RLOGCODE
5189 if (TELOPT_ME(TELOPT_NAWS))
5190 rlog_naws();
5191 #endif /* RLOGCODE */
5192 #ifdef SSHBUILTIN
5193 if (TELOPT_ME(TELOPT_NAWS))
5194 ssh_snaws();
5195 #endif /* SSHBUILTIN */
5196 } else {
5197 tt_szchng[VTERM] = 1;
5198 tt_rows[VTERM]++;
5199 VscrnInit(VTERM); /* Height set here */
5200 #ifdef TNCODE
5201 if (TELOPT_ME(TELOPT_NAWS))
5202 tn_snaws();
5203 #endif /* TNCODE */
5204 #ifdef RLOGCODE
5205 if (TELOPT_ME(TELOPT_NAWS))
5206 rlog_naws();
5207 #endif /* RLOGCODE */
5208 #ifdef SSHBUILTIN
5209 if (TELOPT_ME(TELOPT_NAWS))
5210 ssh_snaws();
5211 #endif /* SSHBUILTIN */
5212 }
5213 }
5214 return(1);
5215 }
5216 #endif /* OS2 */
5217
5218 #ifdef NT
5219 case XYTATTBUG:
5220 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5221 if ((x = cmcfm()) < 0) return(x);
5222 tt_attr_bug = y;
5223 return(1);
5224 #endif /* NT */
5225
5226 #ifdef OS2
5227 case XYTSGRC:
5228 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5229 if ((x = cmcfm()) < 0) return(x);
5230 sgrcolors = y;
5231 return(1);
5232
5233 case XYTSEND:
5234 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5235 if ((x = cmcfm()) < 0) return(x);
5236 tt_senddata = y;
5237 return(1);
5238
5239 case XYTSEOB:
5240 if ((y = cmkey(ttyseobtab,2,"","us_cr",xxstring)) < 0) return(y);
5241 if ((x = cmcfm()) < 0) return(x);
5242 wy_blockend = y;
5243 return(1);
5244
5245 case XYTURLHI: {
5246 int done = 0, attr = VT_CHAR_ATTR_NORMAL;
5247
5248 if ((x = cmkey(onoff,2,"","on",xxstring)) < 0)
5249 return(x);
5250 if (x) {
5251 z = 0;
5252 while (!done) {
5253 if ((y = cmkey(ttyprotab,nprotect,"",
5254 z?"done":"reverse",xxstring)) < 0)
5255 return(y);
5256 switch (y) {
5257 case TTATTDONE:
5258 done = TRUE;
5259 break;
5260 case TTATTBLI:
5261 attr |= VT_CHAR_ATTR_BLINK;
5262 break;
5263 case TTATTREV:
5264 attr |= VT_CHAR_ATTR_REVERSE;
5265 break;
5266 case TTATTITA:
5267 attr |= VT_CHAR_ATTR_ITALIC;
5268 break;
5269 case TTATTUND:
5270 attr |= VT_CHAR_ATTR_UNDERLINE;
5271 break;
5272 case TTATTBLD:
5273 attr |= VT_CHAR_ATTR_BOLD;
5274 break;
5275 case TTATTDIM:
5276 attr |= VT_CHAR_ATTR_DIM;
5277 break;
5278 case TTATTINV:
5279 attr |= VT_CHAR_ATTR_INVISIBLE;
5280 break;
5281 case TTATTNOR:
5282 break;
5283 }
5284 z = 1; /* One attribute has been chosen */
5285 }
5286 }
5287 if ((z = cmcfm()) < 0) return(z);
5288 seturlhl(x);
5289 if (x)
5290 tt_url_hilite_attr = attr;
5291 return(1);
5292 }
5293 case XYTATTR:
5294 if ((x = cmkey(ttyattrtab,nattrib,"","underline",xxstring)) < 0)
5295 return(x);
5296 switch (x) {
5297 case TTATTBLI:
5298 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5299 if ((x = cmcfm()) < 0) return(x);
5300 trueblink = y;
5301 #ifndef KUI
5302 if ( !trueblink && trueunderline ) {
5303 trueunderline = 0;
5304 printf("Warning: Underline being simulated by color.\n");
5305 }
5306
5307 #endif /* KUI */
5308 break;
5309
5310 case TTATTDIM:
5311 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5312 if ((x = cmcfm()) < 0) return(x);
5313 truedim = y;
5314 break;
5315
5316 case TTATTREV:
5317 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5318 if ((x = cmcfm()) < 0) return(x);
5319 truereverse = y;
5320 break;
5321
5322 case TTATTUND:
5323 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5324 if ((x = cmcfm()) < 0) return(x);
5325 trueunderline = y;
5326 #ifndef KUI
5327 if (!trueblink && trueunderline) {
5328 trueblink = 1;
5329 printf("Warning: True blink mode is active.\n");
5330 }
5331 #endif /* KUI */
5332 break;
5333
5334 case TTATTITA:
5335 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5336 if ((x = cmcfm()) < 0) return(x);
5337 trueitalic = y;
5338 break;
5339
5340 case TTATTPRO: { /* Set default Protected Character attribute */
5341 extern vtattrib WPattrib; /* current WP Mode Attrib */
5342 extern vtattrib defWPattrib; /* default WP Mode Attrib */
5343 vtattrib wpa = {0,0,0,0,0,1,0,0,0,0,0}; /* Protected */
5344 int done = 0;
5345
5346 x = 0;
5347 while (!done) {
5348 if ((y = cmkey(ttyprotab,nprotect,"",
5349 x?"done":"dim",xxstring)) < 0)
5350 return(y);
5351 switch (y) {
5352 case TTATTNOR:
5353 break;
5354 case TTATTBLI: /* Blinking doesn't work */
5355 wpa.blinking = TRUE;
5356 break;
5357 case TTATTREV:
5358 wpa.reversed = TRUE;
5359 break;
5360 case TTATTITA:
5361 wpa.italic = TRUE;
5362 break;
5363 case TTATTUND:
5364 wpa.underlined = TRUE;
5365 break;
5366 case TTATTBLD:
5367 wpa.bold = TRUE;
5368 break;
5369 case TTATTDIM:
5370 wpa.dim = TRUE;
5371 break;
5372 case TTATTINV:
5373 wpa.invisible = TRUE ;
5374 break;
5375 case TTATTDONE:
5376 done = TRUE;
5377 break;
5378 }
5379 x = 1; /* One attribute has been chosen */
5380 }
5381 if ((x = cmcfm()) < 0) return(x);
5382 WPattrib = defWPattrib = wpa;
5383 break;
5384 }
5385 }
5386 return(1);
5387
5388 case XYTKEY: { /* SET TERMINAL KEY */
5389 int t, x, y;
5390 int clear = 0, deflt = 0;
5391 int confirmed = 0;
5392 int flag = 0;
5393 int kc = -1; /* Key code */
5394 int litstr = 0; /* Literal String? */
5395 char *s = NULL; /* Key binding */
5396 #ifndef NOKVERBS
5397 char *p = NULL; /* Worker */
5398 #endif /* NOKVERBS */
5399 con_event defevt;
5400 extern int os2gks;
5401 extern int mskkeys;
5402 extern int initvik;
5403 struct FDB kw,sw,nu,cm;
5404
5405 defevt.type = error;
5406
5407 if ((t = cmkey(ttkeytab,nttkey,"","",xxstring)) < 0)
5408 return(t);
5409 cmfdbi(&nu, /* First FDB - command switches */
5410 _CMNUM, /* fcode */
5411 "/literal, keycode, or action",
5412 "", /* default */
5413 "", /* addtl string data */
5414 10, /* addtl numeric data 1: radix */
5415 0, /* addtl numeric data 2: 0 */
5416 xxstring, /* Processing function */
5417 NULL, /* Keyword table */
5418 &sw /* Pointer to next FDB */
5419 ); /* */
5420 cmfdbi(&sw, /* Second FDB - switches */
5421 _CMKEY, /* fcode */
5422 "",
5423 "", /* default */
5424 "", /* addtl string data */
5425 nstrmswitab, /* addtl numeric data 1: tbl size */
5426 4, /* addtl numeric data 2: 4 = cmswi */
5427 xxstring, /* Processing function */
5428 strmswitab, /* Keyword table */
5429 &kw /* Pointer to next FDB */
5430 );
5431 cmfdbi(&kw, /* Third FDB - command switches */
5432 _CMKEY, /* fcode */
5433 "/literal, keycode, or action",
5434 "", /* default */
5435 "", /* addtl string data */
5436 nstrmkeytab, /* addtl numeric data 1: tbl size */
5437 0, /* addtl numeric data 2 */
5438 xxstring, /* Processing function */
5439 strmkeytab, /* Keyword table */
5440 &cm /* Pointer to next FDB */
5441 );
5442 cmfdbi(&cm, /* Final FDB - Confirmation */
5443 _CMCFM, /* fcode */
5444 "",
5445 "", /* default */
5446 "", /* addtl string data */
5447 0, /* addtl numeric data 1: tbl size */
5448 0, /* addtl numeric data 2: 4 = cmswi */
5449 xxstring, /* Processing function */
5450 NULL, /* Keyword table */
5451 NULL /* Pointer to next FDB */
5452 );
5453 while (kc < 0) {
5454 x = cmfdb(&nu); /* Parse something */
5455 if (x < 0)
5456 return(x);
5457
5458 switch (cmresult.fcode) {
5459 case _CMCFM:
5460 printf(" Press key to be defined: ");
5461 conbin((char)escape); /* Put terminal in binary mode */
5462 os2gks = 0; /* Turn off Kverb preprocessing */
5463 kc = congks(0); /* Get character or scan code */
5464 os2gks = 1; /* Turn on Kverb preprocessing */
5465 concb((char)escape); /* Restore terminal to cbreak mode */
5466 if (kc < 0) { /* Check for error */
5467 printf("?Error reading key\n");
5468 return(0);
5469 }
5470 shokeycode(kc,t); /* Show current definition */
5471 flag = 1; /* Remember it's a multiline command */
5472 break;
5473 case _CMNUM:
5474 kc = cmresult.nresult;
5475 break;
5476 case _CMKEY:
5477 if (cmresult.fdbaddr == &sw) { /* Switch */
5478 if (cmresult.nresult == 0)
5479 litstr = 1;
5480 } else if (cmresult.fdbaddr == &kw) { /* Keyword */
5481 if (cmresult.nresult == 0)
5482 clear = 1;
5483 else
5484 deflt = 1;
5485 if ((x = cmcfm()) < 0)
5486 return(x);
5487 if (clear)
5488 clearkeymap(t);
5489 else if (deflt)
5490 defaultkeymap(t);
5491 initvik = 1;
5492 return(1);
5493 }
5494 }
5495 }
5496
5497 /* Normal SET TERMINAL KEY <terminal> <scancode> <value> command... */
5498
5499 if (mskkeys)
5500 kc = msktock(kc);
5501
5502 if (kc < 0 || kc >= KMSIZE) {
5503 printf("?key code must be between 0 and %d\n", KMSIZE - 1);
5504 return(-9);
5505 }
5506 if (kc == escape) {
5507 printf("Sorry, %d is the CONNECT-mode escape character\n",kc);
5508 return(-9);
5509 }
5510 wideresult = -1;
5511 if (flag) {
5512 cmsavp(psave,PROMPTL);
5513 cmsetp(" Enter new definition: ");
5514 cmini(ckxech);
5515 }
5516 def_again:
5517 if (flag) prompt(NULL);
5518 if ((y = cmtxt("key definition,\n\
5519 or Ctrl-C to cancel this command,\n\
5520 or Enter to restore default definition",
5521 "",&s,NULL)) < 0) {
5522 if (flag) /* Handle parse errors */
5523 goto def_again;
5524 else
5525 return(y);
5526 }
5527 s = brstrip(s);
5528 #ifndef NOKVERBS
5529 p = s; /* Save this place */
5530 #endif /* NOKVERBS */
5531 /*
5532 If the definition included any \Kverbs, quote the backslash so the \Kverb
5533 will still be in the definition when the key is pressed. We don't do this
5534 in zzstring(), because \Kverbs are valid only in this context and nowhere
5535 else.
5536
5537 We use this code active for all versions that support SET KEY, even if they
5538 don't support \Kverbs, because otherwise \K would behave differently for
5539 different versions.
5540 */
5541 for (x = 0, y = 0; s[x]; x++, y++) { /* Convert \K to \\K */
5542 if ((x > 0) &&
5543 (s[x] == 'K' || s[x] == 'k')
5544 ) { /* Have K */
5545
5546 if ((x == 1 && s[x-1] == CMDQ) ||
5547 (x > 1 && s[x-1] == CMDQ && s[x-2] != CMDQ)) {
5548 line[y++] = CMDQ; /* Make it \\K */
5549 }
5550 if (x > 1 && s[x-1] == '{' && s[x-2] == CMDQ) {
5551 line[y-1] = CMDQ; /* Have \{K */
5552 line[y++] = '{'; /* Make it \\{K */
5553 }
5554 }
5555 line[y] = s[x];
5556 }
5557 line[y++] = NUL; /* Terminate */
5558 s = line + y + 1; /* Point to after it */
5559 x = LINBUFSIZ - (int) strlen(line) - 1; /* Get remaining space */
5560 if ((x < (LINBUFSIZ / 2)) ||
5561 (zzstring(line, &s, &x) < 0)) { /* Expand variables, etc. */
5562 printf("?Key definition too long\n");
5563 if (flag) cmsetp(psave);
5564 return(-9);
5565 }
5566 s = line + y + 1; /* Point to result. */
5567
5568 #ifndef NOKVERBS
5569 /*
5570 Special case: see if the definition starts with a \Kverb.
5571 If it does, point to it with p, otherwise set p to NULL.
5572 */
5573 p = s;
5574 if (*p++ == CMDQ) {
5575 if (*p == '{') p++;
5576 p = (*p == 'k' || *p == 'K') ? p + 1 : NULL;
5577 }
5578 #endif /* NOKVERBS */
5579
5580 switch (strlen(s)) { /* Action depends on length */
5581 case 0: /* Clear individual key def */
5582 deletekeymap(t,kc);
5583 break;
5584 case 1:
5585 if (!litstr) {
5586 defevt.type = key; /* Single character */
5587 defevt.key.scancode = *s;
5588 break;
5589 }
5590 default: /* Character string */
5591 #ifndef NOKVERBS
5592 if (p) {
5593 y = xlookup(kverbs,p,nkverbs,&x); /* Look it up */
5594 /* Need exact match */
5595 debug(F101,"set key kverb lookup",0,y);
5596 if (y > -1) {
5597 defevt.type = kverb;
5598 defevt.kverb.id = y;
5599 break;
5600 }
5601 }
5602 #endif /* NOKVERBS */
5603 if (litstr) {
5604 defevt.type = literal;
5605 defevt.literal.string = (char *) malloc(strlen(s)+1);
5606 if (defevt.literal.string)
5607 strcpy(defevt.literal.string, s); /* safe */
5608 } else {
5609 defevt.type = macro;
5610 defevt.macro.string = (char *) malloc(strlen(s)+1);
5611 if (defevt.macro.string)
5612 strcpy(defevt.macro.string, s); /* safe */
5613 }
5614 break;
5615 }
5616 insertkeymap(t, kc, defevt);
5617 if (flag)
5618 cmsetp(psave);
5619 initvik = 1; /* Update VIK table */
5620 return(1);
5621 }
5622
5623 #ifdef PCTERM
5624 case XYTPCTERM: /* PCTERM Keyboard Mode */
5625 if ((x = seton(&tt_pcterm)) < 0) return(x);
5626 return(success = 1);
5627 #endif /* PCTERM */
5628 #endif /* OS2 */
5629
5630 #ifdef CK_TRIGGER
5631 case XYTRIGGER:
5632 if ((y = cmtxt("String to trigger automatic return to command mode",
5633 "",&s,xxstring)) < 0)
5634 return(y);
5635 makelist(s,tt_trigger,TRIGGERS);
5636 return(1);
5637 #endif /* CK_TRIGGER */
5638
5639 #ifdef OS2
5640 case XYTSAC:
5641 if ((y = cmnum("ASCII value to use for spacing attributes",
5642 "32",10,&x,xxstring)) < 0)
5643 return(y);
5644 if ((y = cmcfm()) < 0) return(y);
5645 tt_sac = x;
5646 return(success = 1);
5647
5648 case XYTKBDGL: { /* SET TERM KBD-FOLLOWS-GL/GR */
5649 extern int tt_kb_glgr; /* from ckoco3.c */
5650 if ((x = seton(&tt_kb_glgr)) < 0)
5651 return(x);
5652 return(success = 1);
5653 }
5654 #ifndef NOCSETS
5655 case XYTVTLNG: /* SET TERM DEC-LANGUAGE */
5656 if ((y = cmkey(vtlangtab,nvtlangtab,"VT language",
5657 IS97801(tt_type_mode)?"german":"north-american",
5658 xxstring)) < 0)
5659 return(y);
5660 if ((x = cmcfm()) < 0) return(x);
5661
5662 /* A real VT terminal would use the language to set the */
5663 /* default keyboard language for both 8-bit multinational */
5664 /* and 7-bit national modes. For 8-bit mode it would */
5665 /* set the terminal character-set to the ISO set if it */
5666 /* is not already set. */
5667 /* Latin-1 can be replaced by DEC Multinational */
5668 switch (y) {
5669 case VTL_NORTH_AM: /* North American */
5670 /* Multinational: Latin-1 */
5671 /* National: US_ASCII */
5672 dec_lang = y;
5673 dec_nrc = TX_ASCII;
5674 dec_kbd = TX_8859_1;
5675 break;
5676 case VTL_BRITISH :
5677 /* Multinational: Latin-1 */
5678 /* National: UK_ASCII */
5679 dec_lang = y;
5680 dec_nrc = TX_BRITISH;
5681 dec_kbd = TX_8859_1;
5682 break;
5683 case VTL_FRENCH :
5684 case VTL_BELGIAN :
5685 case VTL_CANADIAN:
5686 /* Multinational: Latin-1 */
5687 /* National: FR_ASCII */
5688 dec_lang = y;
5689 dec_nrc = TX_FRENCH;
5690 dec_kbd = TX_8859_1;
5691 break;
5692 case VTL_FR_CAN :
5693 /* Multinational: Latin-1 */
5694 /* National: FC_ASCII */
5695 dec_lang = y;
5696 dec_nrc = TX_CN_FRENCH;
5697 dec_kbd = TX_8859_1;
5698 break;
5699 case VTL_DANISH :
5700 case VTL_NORWEGIA:
5701 /* Multinational: Latin-1 */
5702 /* National: NO_ASCII */
5703 dec_lang = y;
5704 dec_nrc = TX_NORWEGIAN;
5705 dec_kbd = TX_8859_1;
5706 break;
5707 case VTL_FINNISH :
5708 /* Multinational: Latin-1 */
5709 /* National: FI_ASCII */
5710 dec_lang = y;
5711 dec_nrc = TX_FINNISH;
5712 dec_kbd = TX_8859_1;
5713 break;
5714 case VTL_GERMAN :
5715 /* Multinational: Latin-1 */
5716 /* National: GR_ASCII */
5717 dec_lang = y;
5718 dec_nrc = TX_GERMAN;
5719 dec_kbd = TX_8859_1;
5720 break;
5721 case VTL_DUTCH :
5722 /* Multinational: Latin-1 */
5723 /* National: DU_ASCII */
5724 dec_lang = y;
5725 dec_nrc = TX_DUTCH;
5726 dec_kbd = TX_8859_1;
5727 break;
5728 case VTL_ITALIAN :
5729 /* Multinational: Latin-1 */
5730 /* National: IT_ASCII */
5731 dec_lang = y;
5732 dec_nrc = TX_ITALIAN;
5733 dec_kbd = TX_8859_1;
5734 break;
5735 case VTL_SW_FR :
5736 case VTL_SW_GR :
5737 /* Multinational: Latin-1 */
5738 /* National: CH_ASCII */
5739 dec_lang = y;
5740 dec_nrc = TX_SWISS;
5741 dec_kbd = TX_8859_1;
5742 break;
5743 case VTL_SWEDISH :
5744 /* Multinational: Latin-1 */
5745 /* National: SW_ASCII */
5746 dec_lang = y;
5747 dec_nrc = TX_SWEDISH;
5748 dec_kbd = TX_8859_1;
5749 break;
5750 case VTL_SPANISH :
5751 /* Multinational: Latin-1 */
5752 /* National: SP_ASCII */
5753 dec_lang = y;
5754 dec_nrc = TX_SPANISH;
5755 dec_kbd = TX_8859_1;
5756 break;
5757 case VTL_PORTUGES:
5758 /* Multinational: Latin-1 */
5759 /* National: Portugese ASCII */
5760 dec_lang = y;
5761 dec_nrc = TX_PORTUGUESE;
5762 dec_kbd = TX_8859_1;
5763 break;
5764 case VTL_HEBREW :
5765 /* Multinational: Latin-Hebrew / DEC-Hebrew */
5766 /* National: DEC 7-bit Hebrew */
5767 dec_lang = y;
5768 dec_nrc = TX_HE7;
5769 dec_kbd = TX_8859_8;
5770 break;
5771 case VTL_GREEK :
5772 /* Multinational: Latin-Greek / DEC-Greek */
5773 /* National: DEC Greek NRC */
5774 /* is ELOT927 equivalent to DEC Greek???? */
5775 dec_lang = y;
5776 dec_nrc = TX_ELOT927;
5777 dec_kbd = TX_8859_7;
5778 break;
5779 #ifdef COMMENT
5780 case VTL_TURK_Q :
5781 case VTL_TURK_F :
5782 /* Multinational: Latin-Turkish / DEC-Turkish */
5783 /* National: DEC 7-bit Turkish */
5784 break;
5785 #endif /* COMMENT */
5786 case VTL_HUNGARIA:
5787 /* Multinational: Latin-2 */
5788 /* National: no national mode */
5789 dec_lang = y;
5790 dec_nrc = TX_HUNGARIAN;
5791 dec_kbd = TX_8859_2;
5792 break;
5793 case VTL_SLOVAK :
5794 case VTL_CZECH :
5795 case VTL_POLISH :
5796 case VTL_ROMANIAN:
5797 /* Multinational: Latin-2 */
5798 /* National: no national mode */
5799 dec_lang = y;
5800 dec_nrc = TX_ASCII;
5801 dec_kbd = TX_8859_2;
5802 break;
5803 case VTL_RUSSIAN :
5804 /* Multinational: Latin-Cyrillic / KOI-8 */
5805 /* National: DEC Russian NRC */
5806 dec_lang = y;
5807 dec_nrc = TX_KOI7;
5808 dec_kbd = TX_8859_5;
5809 break;
5810 case VTL_LATIN_AM:
5811 /* Multinational: not listed in table */
5812 /* National: not listed in table */
5813 dec_lang = y;
5814 dec_nrc = TX_ASCII;
5815 dec_kbd = TX_8859_1;
5816 break;
5817 #ifdef COMMENT
5818 case VTL_SCS :
5819 /* Multinational: Latin-2 */
5820 /* National: SCS NRC */
5821 break;
5822 #endif /* COMMENT */
5823 default:
5824 return(success = 0);
5825 }
5826 if (IS97801(tt_type_mode)) {
5827 SNI_bitmode(cmask == 0377 ? 8 : 7);
5828 }
5829 return(success = 1);
5830 #endif /* NOCSETS */
5831
5832 case XYTVTNRC: { /* SET TERM DEC-NRC-MODE */
5833 extern int decnrcm_usr, decnrcm; /* from ckoco3.c */
5834 if ((x = seton(&decnrcm_usr)) < 0)
5835 return(x);
5836 decnrcm = decnrcm_usr;
5837 return(success = 1);
5838 }
5839 case XYTSNIPM: { /* SET TERM SNI-PAGEMODE */
5840 extern int sni_pagemode, sni_pagemode_usr;
5841 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5842 if ((x = cmcfm()) < 0) return(x);
5843 sni_pagemode_usr = sni_pagemode = y;
5844 return(success = 1);
5845 }
5846 case XYTSNISM: { /* SET TERM SNI-SCROLLMODE */
5847 extern int sni_scroll_mode, sni_scroll_mode_usr;
5848 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5849 if ((x = cmcfm()) < 0) return(x);
5850 sni_scroll_mode_usr = sni_scroll_mode = y;
5851 return(success = 1);
5852 }
5853 case XYTSNICC: { /* SET TERM SNI-CH.CODE */
5854 extern int sni_chcode_usr;
5855 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5856 if ((x = cmcfm()) < 0) return(x);
5857 sni_chcode_usr = y;
5858 SNI_chcode(y);
5859 return(success = 1);
5860 }
5861 case XYTSNIFV: { /* SET TERM SNI-FIRMWARE-VERSIONS */
5862 extern CHAR sni_kbd_firmware[], sni_term_firmware[];
5863 CHAR kbd[7],term[7];
5864
5865 if ((x = cmfld("Keyboard Firmware Version",sni_kbd_firmware,
5866 &s, xxstring)) < 0)
5867 return(x);
5868 if ((int)strlen(s) != 6) {
5869 printf("?Sorry - the firmware version must be 6 digits long\n");
5870 return(-9);
5871 }
5872 for (i = 0; i < 6; i++) {
5873 if (!isdigit(s[i])) {
5874 printf("?Sorry - the firmware version can only contain digits [0-9]\n");
5875 return(-9);
5876 }
5877 }
5878 ckstrncpy(kbd,s,7);
5879
5880 if ((x = cmfld("Terminal Firmware Version",sni_term_firmware,
5881 &s, xxstring)) < 0)
5882 return(x);
5883 if ((int)strlen(s) != 6) {
5884 printf("?Sorry - the firmware version must be 6 digits long\n");
5885 return(-9);
5886 }
5887 for (i = 0; i < 6; i++) {
5888 if (!isdigit(s[i])) {
5889 printf("?Sorry - the firmware version can only contain digits [0-9]\n");
5890 return(-9);
5891 }
5892 }
5893 ckstrncpy(term,s,7);
5894 if ((x = cmcfm()) < 0) return(x);
5895
5896 ckstrncpy(sni_kbd_firmware,kbd,7);
5897 ckstrncpy(sni_term_firmware,term,7);
5898 return(success = 1);
5899 }
5900
5901 case XYTLSP: { /* SET TERM LINE-SPACING */
5902 if ((x = cmfld("Line Spacing","1",&s, xxstring)) < 0)
5903 return(x);
5904 if (isfloat(s,0) < 1) { /* (sets floatval) */
5905 printf("?Integer or floating-point number required\n");
5906 return(-9);
5907 }
5908 if (floatval < 1.0 || floatval > 3.0) {
5909 printf("?Value must within the range 1.0 and 3.0 (inclusive)\n");
5910 return(-9);
5911 }
5912 if ((x = cmcfm()) < 0) return(x);
5913 #ifdef KUI
5914 tt_linespacing[VCMD] = tt_linespacing[VTERM] = floatval;
5915 return(success = 1);
5916 #else /* KUI */
5917 printf("?Sorry, Line-spacing is only supported in K95G.EXE.\n");
5918 return(success = 0);
5919 #endif /* KUI */
5920 }
5921 #endif /* OS2 */
5922
5923 default: /* Shouldn't get here. */
5924 return(-2);
5925 }
5926 #endif /* MAC */
5927 #ifdef COMMENT
5928 /*
5929 This was supposed to shut up picky compilers but instead it makes
5930 most compilers complain about "statement not reached".
5931 */
5932 return(-2);
5933 #endif /* COMMENT */
5934 #ifdef OS2
5935 return(-2);
5936 #endif /* OS2 */
5937 }
5938
5939 #ifdef OS2
5940 int
settitle(void)5941 settitle(void) {
5942 extern char usertitle[];
5943 if ((y = cmtxt("title text","",&s,xxstring)) < 0)
5944 return(y);
5945 #ifdef IKSD
5946 if (inserver) {
5947 printf("?Sorry, command disabled.\r\n");
5948 return(success = 0);
5949 }
5950 #endif /* IKSD */
5951 s = brstrip(s);
5952 ckstrncpy(usertitle,s,64);
5953 os2settitle("",1);
5954 return(1);
5955 }
5956
5957 static struct keytab dialertab[] = { /* K95 Dialer types */
5958 "backspace", 0, 0,
5959 "enter", 1, 0
5960 };
5961 static int ndialer = 2;
5962
5963 int
setdialer(void)5964 setdialer(void) {
5965 int t, x, y;
5966 int clear = 0, deflt = 0;
5967 int kc; /* Key code */
5968 char *s = NULL; /* Key binding */
5969 #ifndef NOKVERBS
5970 char *p = NULL; /* Worker */
5971 #endif /* NOKVERBS */
5972 con_event defevt;
5973 extern int os2gks;
5974 extern int mskkeys;
5975 extern int initvik;
5976
5977 defevt.type = error;
5978
5979 if (( x = cmkey(dialertab, ndialer,
5980 "Kermit-95 dialer work-arounds",
5981 "", xxstring)) < 0 )
5982 return(x);
5983 switch (x) {
5984 case 0: /* Backspace */
5985 kc = 264;
5986 break;
5987 case 1: /* Enter */
5988 kc = 269;
5989 break;
5990 default:
5991 printf("Illegal value in setdialer()\n");
5992 return(-9);
5993 }
5994 if ((y = cmtxt("Key definition","",&s,xxstring)) < 0)
5995 return(y);
5996
5997 #ifdef IKSD
5998 if (inserver) {
5999 printf("?Sorry, command disabled.\r\n");
6000 return(success = 0);
6001 }
6002 #endif /* IKSD */
6003 s = brstrip(s);
6004 #ifndef NOKVERBS
6005 p = s; /* Save this place */
6006 #endif /* NOKVERBS */
6007 /*
6008 If the definition included any \Kverbs, quote the backslash so the \Kverb
6009 will still be in the definition when the key is pressed. We don't do this
6010 in zzstring(), because \Kverbs are valid only in this context and nowhere
6011 else.
6012
6013 We use this code active for all versions that support SET KEY, even if they
6014 don't support \Kverbs, because otherwise \K would behave differently for
6015 different versions.
6016 */
6017 for (x = 0, y = 0; s[x]; x++, y++) { /* Convert \K to \\K */
6018 if ((x > 0) &&
6019 (s[x] == 'K' || s[x] == 'k')
6020 ) { /* Have K */
6021
6022 if ((x == 1 && s[x-1] == CMDQ) ||
6023 (x > 1 && s[x-1] == CMDQ && s[x-2] != CMDQ)) {
6024 line[y++] = CMDQ; /* Make it \\K */
6025 }
6026 if (x > 1 && s[x-1] == '{' && s[x-2] == CMDQ) {
6027 line[y-1] = CMDQ; /* Have \{K */
6028 line[y++] = '{'; /* Make it \\{K */
6029 }
6030 }
6031 line[y] = s[x];
6032 }
6033 line[y++] = NUL; /* Terminate */
6034 s = line + y + 1; /* Point to after it */
6035 x = LINBUFSIZ - (int) strlen(line) - 1; /* Calculate remaining space */
6036 if ((x < (LINBUFSIZ / 2)) ||
6037 (zzstring(line, &s, &x) < 0)) { /* Expand variables, etc. */
6038 printf("?Key definition too long\n");
6039 return(-9);
6040 }
6041 s = line + y + 1; /* Point to result. */
6042
6043 #ifndef NOKVERBS
6044 /*
6045 Special case: see if the definition starts with a \Kverb.
6046 If it does, point to it with p, otherwise set p to NULL.
6047 */
6048 p = s;
6049 if (*p++ == CMDQ) {
6050 if (*p == '{') p++;
6051 p = (*p == 'k' || *p == 'K') ? p + 1 : NULL;
6052 }
6053 #endif /* NOKVERBS */
6054
6055 /* Clear the definition for SET KEY */
6056 if (macrotab[kc]) { /* Possibly free old macro from key. */
6057 free((char *)macrotab[kc]);
6058 macrotab[kc] = NULL;
6059 }
6060 keymap[kc] = (KEY) kc;
6061
6062 /* Now reprogram the default value for all terminal types */
6063 /* remember to treat Wyse and Televideo terminals special */
6064 /* because of their use of Kverbs for Backspace and Enter */
6065 for (t = 0; t <= TT_MAX; t++) {
6066 if ( ISDG200(t) && kc == 264) {
6067 extern char * udkfkeys[] ;
6068 if (kc == 264) { /* \Kdgbs */
6069 if (udkfkeys[83])
6070 free(udkfkeys[83]);
6071 udkfkeys[83] = strdup(s);
6072 }
6073 } else if (ISWYSE(t) || ISTVI(t)) {
6074 extern char * udkfkeys[] ;
6075 if (kc == 264) { /* \Kwybs or \Ktvibs */
6076 if (udkfkeys[32])
6077 free(udkfkeys[32]);
6078 udkfkeys[32] = strdup(s);
6079 }
6080 if (kc == 269) { /* \Kwyenter and \Kwyreturn */
6081 if (udkfkeys[39]) /* \Ktvienter and \Ktvireturn */
6082 free(udkfkeys[39]);
6083 udkfkeys[39] = strdup(s);
6084 if (udkfkeys[49])
6085 free(udkfkeys[49]);
6086 udkfkeys[49] = strdup(s);
6087 }
6088 } else {
6089 switch (strlen(s)) { /* Action depends on length */
6090 case 0: /* Clear individual key def */
6091 deletekeymap(t,kc);
6092 break;
6093 case 1:
6094 defevt.type = key; /* Single character */
6095 defevt.key.scancode = *s;
6096 break;
6097 default: /* Character string */
6098 #ifndef NOKVERBS
6099 if (p) {
6100 y = xlookup(kverbs,p,nkverbs,&x); /* Look it up */
6101 /* Exact match req'd */
6102 debug(F101,"set key kverb lookup",0,y);
6103 if (y > -1) {
6104 defevt.type = kverb;
6105 defevt.kverb.id = y;
6106 break;
6107 }
6108 }
6109 #endif /* NOKVERBS */
6110 defevt.type = macro;
6111 defevt.macro.string = (char *) malloc(strlen(s)+1);
6112 if (defevt.macro.string)
6113 strcpy(defevt.macro.string, s); /* safe */
6114 break;
6115 }
6116 insertkeymap( t, kc, defevt ) ;
6117 initvik = 1; /* Update VIK table */
6118 }
6119 }
6120 return(1);
6121 }
6122 #endif /* OS2 */
6123
6124 #ifdef NT
6125 int
setwin95(void)6126 setwin95( void ) {
6127 int x, y, z;
6128
6129 if (( y = cmkey(win95tab, nwin95,
6130 "Windows 95 specific work-arounds",
6131 "keyboard-translation",
6132 xxstring)) < 0 )
6133 return (y);
6134 switch (y) {
6135 case XYWPOPUP:
6136 if ((y = cmkey(onoff,2,"popups are used to prompt the user for data",
6137 "on",xxstring)) < 0)
6138 return(y);
6139 if ((x = cmcfm()) < 0) return(x);
6140 win95_popup = y;
6141 return(1);
6142
6143 case XYW8_3:
6144 if ((y = cmkey(onoff,2,"8.3 FAT file names","off",xxstring)) < 0)
6145 return(y);
6146 if ((x = cmcfm()) < 0) return(x);
6147 win95_8_3 = y;
6148 return(1);
6149
6150 case XYWSELECT:
6151 if ((y = cmkey(onoff,2,"\"select()\" fails on write","off",
6152 xxstring)) < 0)
6153 return(y);
6154 if ((x = cmcfm()) < 0) return(x);
6155 win95selectbug = y;
6156 return(1);
6157
6158 case XYWAGR:
6159 if ((y = cmkey(onoff,2,"Right-Alt is Alt-Gr","off",xxstring)) < 0)
6160 return(y);
6161 if ((x = cmcfm()) < 0) return(x);
6162 win95altgr = y;
6163 return(1);
6164
6165 case XYWOIO:
6166 if ((y = cmkey(onoff,2,"Use Overlapped I/O","on",xxstring)) < 0)
6167 return(y);
6168 if (y) {
6169 if ((x = cmnum("Maximum number of outstanding I/O requests",
6170 "10",10,&z,xxstring)) < 0)
6171 return(x);
6172 if (z < 1 || z > 7) {
6173 printf(
6174 "?Maximum outstanding I/O requests must be between 1 and 7.\n");
6175 return(-9);
6176 }
6177 } else
6178 z = 1;
6179 if ((x = cmcfm()) < 0) return(x);
6180 owwait = !y;
6181 maxow = maxow_usr = z;
6182 return(1);
6183
6184 case XYWKEY:
6185 #ifndef COMMENT
6186 printf("\n?\"Keyboard-Translation\" is no longer required.\n");
6187 return(-9);
6188 #else /* COMMENT */
6189 if (( z = cmkey(tcstab, ntcs,
6190 "Keyboard Character Set",
6191 "latin1-iso",
6192 xxstring)) < 0)
6193 return (z);
6194 if ((x = cmcfm()) < 0)
6195 return(x);
6196
6197 win95kcsi = z;
6198 win95kl2 = (win95kcsi == TC_2LATIN);
6199
6200 if (win95kcsi == TC_TRANSP) {
6201 win95kcs = NULL;
6202 } else {
6203 #ifdef UNICODE
6204 win95kcs = xlr[win95kcsi][tx2fc(tcsl)];
6205 #else /* UNICODE */
6206 win95kcs = xlr[win95kcsi][tcsl];
6207 #endif /* UNICODE */
6208 }
6209 return(1);
6210 #endif /* COMMENT */
6211
6212 case XYWLUC:
6213 if ((y = cmkey(onoff,2,"Unicode-to-Lucida-Console substitutions",
6214 "on",xxstring)) < 0)
6215 return(y);
6216 if ((x = cmcfm()) < 0) return(x);
6217 win95lucida = y;
6218 return(1);
6219
6220 case XYWHSL:
6221 if ((y = cmkey(onoff,2,"Horizontal Scan Line substitutions",
6222 "on",xxstring)) < 0)
6223 return(y);
6224 if ((x = cmcfm()) < 0) return(x);
6225 win95hsl = y;
6226 return(1);
6227
6228 default:
6229 printf("Illegal value in setwin95()\n");
6230 return(-9);
6231 }
6232 }
6233 #endif /* NT */
6234
6235 #ifdef OS2
6236 int
setprty(void)6237 setprty (
6238 #ifdef CK_ANSIC
6239 void
6240 #endif /* CK_ANSIC */
6241 /* setprty */ ) {
6242 int x, y, z;
6243
6244 if (( y = cmkey(prtytab, nprty,
6245 "priority level of terminal and communication threads",
6246 "foreground-server",
6247 xxstring)) < 0 )
6248 return (y);
6249
6250 if ((x = cmcfm()) < 0)
6251 return (x);
6252 #ifdef IKSD
6253 if (inserver &&
6254 #ifdef IKSDCONF
6255 iksdcf
6256 #else
6257 1
6258 #endif /* IKSDCONF */
6259 ) {
6260 if ((y = cmcfm()) < 0) return(y);
6261 printf("?Sorry, command disabled.\r\n");
6262 return(success = 0);
6263 }
6264 #endif /* IKSD */
6265 priority = y;
6266 return(TRUE);
6267 }
6268 #endif /* OS2 */
6269
6270 int
setbell()6271 setbell() {
6272 int y, x;
6273 #ifdef OS2
6274 int z;
6275 #endif /* OS2 */
6276
6277 if ((y = cmkey(beltab,nbeltab,
6278 #ifdef OS2
6279 "how console and terminal bells should\nbe generated", "audible",
6280 #else
6281 "Whether Kermit should ring the terminal bell (beep)", "on",
6282 #endif /* OS2 */
6283 xxstring)) < 0)
6284 return(y);
6285
6286 #ifdef IKSD
6287 if (inserver) {
6288 if ((y = cmcfm()) < 0) return(y);
6289 printf("?Sorry, command disabled.\r\n");
6290 return(success = 0);
6291 }
6292 #endif /* IKSD */
6293
6294 switch (y) { /* SET BELL */
6295 case XYB_NONE:
6296 #ifdef OS2
6297 case XYB_VIS:
6298 #endif /* OS2 */
6299 if ((x = cmcfm()) < 0)
6300 return(x);
6301 #ifdef OS2
6302 tt_bell = y;
6303 #else
6304 tt_bell = 0;
6305 #endif /* OS2 */
6306 break;
6307
6308 case XYB_AUD:
6309 #ifdef OS2
6310 if ((x = cmkey(audibletab, naudibletab,
6311 "how audible console and terminal\nbells should be generated",
6312 "beep",xxstring))<0)
6313 return(x);
6314 if ((z = cmcfm()) < 0)
6315 return(z);
6316 tt_bell = y | x;
6317 #else
6318 /* This lets C-Kermit accept but ignore trailing K95 keywords */
6319 if ((x = cmtxt("Confirm with carriage return","",&s,xxstring)) < 0)
6320 return(x);
6321 tt_bell = 1;
6322 #endif /* OS2 */
6323 break;
6324 }
6325 return(1);
6326 }
6327
6328 #ifdef OS2MOUSE
6329 int
setmou(void)6330 setmou(
6331 #ifdef CK_ANSIC
6332 void
6333 #endif /* CK_ANSIC */
6334 /* setmou */ ) {
6335 extern int initvik;
6336 int button = 0, event = 0;
6337 char * p;
6338
6339 if ((y = cmkey(mousetab,nmtab,"","",xxstring)) < 0)
6340 return(y);
6341
6342 #ifdef IKSD
6343 if (inserver) {
6344 if ((y = cmcfm()) < 0) return(y);
6345 printf("?Sorry, command disabled.\r\n");
6346 return(success = 0);
6347 }
6348 #endif /* IKSD */
6349
6350 if (y == XYM_ON) { /* MOUSE ACTIVATION */
6351 int old_mou = tt_mouse;
6352 if ((x = seton(&tt_mouse)) < 0)
6353 return(x);
6354 if (tt_mouse != old_mou)
6355 if (tt_mouse)
6356 os2_mouseon();
6357 else
6358 os2_mouseoff();
6359 return(1);
6360 }
6361
6362 if (y == XYM_DEBUG) { /* MOUSE DEBUG */
6363 extern int MouseDebug;
6364 if ((x = seton(&MouseDebug)) < 0)
6365 return(x);
6366 return(1);
6367 }
6368
6369 if (y == XYM_CLEAR) { /* Reset Mouse Defaults */
6370 if ((x = cmcfm()) < 0) return(x);
6371 mousemapinit(-1,-1);
6372 initvik = 1; /* Update VIK Table */
6373 return 1;
6374 }
6375 if (y != XYM_BUTTON) { /* Shouldn't happen. */
6376 printf("Internal parsing error\n");
6377 return(-9);
6378 }
6379
6380 /* MOUSE EVENT ... */
6381
6382 if ((button = cmkey(mousebuttontab,nmbtab,
6383 "Button number","1",
6384 xxstring)) < 0)
6385 return(button);
6386
6387 if ((y = cmkey(mousemodtab,nmmtab,
6388 "Keyboard modifier","none",
6389 xxstring)) < 0)
6390 return(y);
6391
6392 event |= y; /* OR in the bits */
6393
6394 if ((y = cmkey(mclicktab,nmctab,"","click",xxstring)) < 0)
6395 return(y);
6396
6397 /* Two bits are assigned, if neither are set then it is button one */
6398
6399 event |= y; /* OR in the bit */
6400
6401 wideresult = -1;
6402
6403 if ((y = cmtxt("definition,\n\
6404 or Ctrl-C to cancel this command,\n\
6405 or Enter to restore default definition",
6406 "",&s,NULL)) < 0) {
6407 return(y);
6408 }
6409 s = brstrip(s);
6410 p = s; /* Save this place */
6411 /*
6412 If the definition included any \Kverbs, quote the backslash so the \Kverb
6413 will still be in the definition when the key is pressed. We don't do this
6414 in zzstring(), because \Kverbs are valid only in this context and nowhere
6415 else. This code copied from SET KEY, q.v. for addt'l commentary.
6416 */
6417 for (x = 0, y = 0; s[x]; x++, y++) { /* Convert \K to \\K */
6418 if ((x > 0) &&
6419 (s[x] == 'K' || s[x] == 'k')
6420 ) { /* Have K */
6421
6422 if ((x == 1 && s[x-1] == CMDQ) ||
6423 (x > 1 && s[x-1] == CMDQ && s[x-2] != CMDQ)) {
6424 line[y++] = CMDQ; /* Make it \\K */
6425 }
6426 if (x > 1 && s[x-1] == '{' && s[x-2] == CMDQ) {
6427 line[y-1] = CMDQ; /* Have \{K */
6428 line[y++] = '{'; /* Make it \\{K */
6429 }
6430 }
6431 line[y] = s[x];
6432 }
6433 line[y++] = NUL; /* Terminate */
6434 s = line + y + 1; /* Point to after it */
6435 x = LINBUFSIZ - (int) strlen(line) - 1; /* Calculate remaining space */
6436 if ((x < (LINBUFSIZ / 2)) ||
6437 (zzstring(line, &s, &x) < 0)) { /* Expand variables, etc. */
6438 printf("?Key definition too long\n");
6439 return(-9);
6440 }
6441 s = line + y + 1; /* Point to result. */
6442
6443 #ifndef NOKVERBS
6444 /*
6445 Special case: see if the definition starts with a \Kverb.
6446 If it does, point to it with p, otherwise set p to NULL.
6447 */
6448 p = s;
6449 if (*p++ == CMDQ) {
6450 if (*p == '{') p++;
6451 p = (*p == 'k' || *p == 'K') ? p + 1 : NULL;
6452 }
6453 #else
6454 p = NULL;
6455 #endif /* NOKVERBS */
6456
6457 /* free the old definition if necessary */
6458 if (mousemap[button][event].type == macro) {
6459 free( mousemap[button][event].macro.string);
6460 mousemap[button][event].macro.string = NULL;
6461 }
6462 switch (strlen(s)) { /* Action depends on length */
6463 case 0: /* Reset to default binding */
6464 mousemapinit( button, event );
6465 break;
6466 case 1: /* Single character */
6467 mousemap[button][event].type = key;
6468 mousemap[button][event].key.scancode = *s;
6469 break;
6470 default: /* Character string */
6471 #ifndef NOKVERBS
6472 if (p) {
6473 y = xlookup(kverbs,p,nkverbs,&x); /* Look it up */
6474 debug(F101,"set mouse kverb lookup",0,y); /* need exact match */
6475 if (y > -1) {
6476 /* Assign the kverb to the event */
6477 mousemap[button][event].type = kverb;
6478 mousemap[button][event].kverb.id = F_KVERB | y;
6479 break;
6480 }
6481 }
6482 #endif /* NOKVERBS */
6483
6484 /* Otherwise, it's a macro, so assign the macro to the event */
6485 mousemap[button][event].type = macro;
6486 mousemap[button][event].macro.string = (MACRO) malloc(strlen(s)+1);
6487 if (mousemap[button][event].macro.string)
6488 strcpy((char *) mousemap[button][event].macro.string, s); /* safe */
6489 break;
6490 }
6491 initvik = 1; /* Update VIK Table */
6492 if ( (button == XYM_B3) && (mousebuttoncount() < 3) && !quiet )
6493 {
6494 printf("?Warning: this machine does not have a three button mouse.\n");
6495 return(0);
6496 }
6497 return(1);
6498 }
6499 #endif /* OS2MOUSE */
6500 #endif /* NOLOCAL */
6501
6502 #ifndef NOXFER
6503 int /* SET SEND/RECEIVE */
setsr(xx,rmsflg)6504 setsr(xx, rmsflg) int xx; int rmsflg; {
6505 if (xx == XYRECV)
6506 ckstrncpy(line,"Parameter for inbound packets",LINBUFSIZ);
6507 else
6508 ckstrncpy(line,"Parameter for outbound packets",LINBUFSIZ);
6509
6510 if (rmsflg) {
6511 if ((y = cmkey(rsrtab,nrsrtab,line,"",xxstring)) < 0) {
6512 if (y == -3) {
6513 printf("?Remote receive parameter required\n");
6514 return(-9);
6515 } else return(y);
6516 }
6517 } else {
6518 if ((y = cmkey(srtab,nsrtab,line,"",xxstring)) < 0) return(y);
6519 }
6520 switch (y) {
6521 case XYQCTL: /* CONTROL-PREFIX */
6522 if ((x = cmnum("ASCII value of control prefix","",10,&y,xxstring)) < 0)
6523 return(x);
6524 if ((x = cmcfm()) < 0) return(x);
6525 if ((y > 32 && y < 63) || (y > 95 && y < 127)) {
6526 if (xx == XYRECV)
6527 ctlq = (CHAR) y; /* RECEIVE prefix, use with caution! */
6528 else
6529 myctlq = (CHAR) y; /* SEND prefix, OK to change */
6530 return(success = 1);
6531 } else {
6532 printf("?Illegal value for prefix character\n");
6533 return(-9);
6534 }
6535
6536 case XYEOL:
6537 if ((y = setcc("13",&z)) < 0)
6538 return(y);
6539 if (z > 31) {
6540 printf("Sorry, the legal values are 0-31\n");
6541 return(-9);
6542 }
6543 if (xx == XYRECV)
6544 eol = (CHAR) z;
6545 else
6546 seol = (CHAR) z;
6547 return(success = y);
6548
6549 case XYLEN:
6550 y = cmnum("Maximum number of characters in a packet","90",10,&x,
6551 xxstring);
6552 if (xx == XYRECV) { /* Receive... */
6553 if ((y = setnum(&z,x,y,maxrps)) < 0)
6554 return(y);
6555 if (protocol != PROTO_K) {
6556 printf("?Sorry, this command does not apply to %s protocol.\n",
6557 ptab[protocol].p_name
6558 );
6559 printf("Use SET SEND PACKET-LENGTH for XYZMODEM\n");
6560 return(-9);
6561 }
6562 if (z < 10) {
6563 printf("Sorry, 10 is the minimum\n");
6564 return(-9);
6565 }
6566 if (rmsflg) {
6567 sstate = setgen('S', "401", ckitoa(z), "");
6568 return((int) sstate);
6569 } else {
6570 if (protocol == PROTO_K) {
6571 if (z > MAXRP) z = MAXRP;
6572 y = adjpkl(z,wslotr,bigrbsiz);
6573 if (y != z) {
6574 urpsiz = y;
6575 if (!xcmdsrc)
6576 if (msgflg) printf(
6577 " Adjusting receive packet-length to %d for %d window slots\n",
6578 y, wslotr);
6579 }
6580 urpsiz = y;
6581 ptab[protocol].rpktlen = urpsiz;
6582 rpsiz = (y > 94) ? 94 : y;
6583 } else {
6584 #ifdef CK_XYZ
6585 if ((protocol == PROTO_X || protocol == PROTO_XC) &&
6586 z != 128 && z != 1024) {
6587 printf("Sorry, bad packet length for XMODEM.\n");
6588 printf("Please use 128 or 1024.\n");
6589 return(-9);
6590 }
6591 #endif /* CK_XYZ */
6592 urpsiz = rpsiz = z;
6593 }
6594 }
6595 } else { /* Send... */
6596 if ((y = setnum(&z,x,y,maxsps)) < 0)
6597 return(y);
6598 if (z < 10) {
6599 printf("Sorry, 10 is the minimum\n");
6600 return(-9);
6601 }
6602 if (protocol == PROTO_K) {
6603 if (z > MAXSP) z = MAXSP;
6604 spsiz = z; /* Set it */
6605 y = adjpkl(spsiz,wslotr,bigsbsiz);
6606 if (y != spsiz && !xcmdsrc)
6607 if (msgflg)
6608 printf("Adjusting packet size to %d for %d window slots\n",
6609 y,wslotr);
6610 } else
6611 y = z;
6612 #ifdef CK_XYZ
6613 if ((protocol == PROTO_X || protocol == PROTO_XC) &&
6614 z != 128 && z != 1024) {
6615 printf("Sorry, bad packet length for XMODEM.\n");
6616 printf("Please use 128 or 1024.\n");
6617 return(-9);
6618 }
6619 #endif /* CK_XYZ */
6620 spsiz = spmax = spsizr = y; /* Set it and flag that it was set */
6621 spsizf = 1; /* to allow overriding Send-Init. */
6622 ptab[protocol].spktflg = spsizf;
6623 ptab[protocol].spktlen = spsiz;
6624 }
6625 if (pflag && protocol == PROTO_K && !xcmdsrc) {
6626 if (z > 94 && !reliable && msgflg) {
6627 /* printf("Extended-length packets requested.\n"); */
6628 if (bctr < 2 && z > 200) printf("\
6629 Remember to SET BLOCK 2 or 3 for long packets.\n");
6630 }
6631 if (speed <= 0L) speed = ttgspd();
6632 #ifdef COMMENT
6633 /*
6634 Kermit does this now itself.
6635 */
6636 if (speed <= 0L && z > 200 && msgflg) {
6637 printf("\
6638 Make sure your timeout interval is long enough for %d-byte packets.\n",z);
6639 }
6640 #endif /* COMMENT */
6641 }
6642 return(success = y);
6643
6644 case XYMARK:
6645 #ifdef DOOMSDAY
6646 /*
6647 Printable start-of-packet works for UNIX and VMS only!
6648 */
6649 x_ifnum = 1;
6650 y = cmnum("Code for packet-start character","1",10,&x,xxstring);
6651 x_ifnum = 0;
6652 if ((y = setnum(&z,x,y,126)) < 0) return(y);
6653 #else
6654 if ((y = setcc("1",&z)) < 0)
6655 return(y);
6656 #endif /* DOOMSDAY */
6657 if (xx == XYRECV)
6658 stchr = (CHAR) z;
6659 else {
6660 mystch = (CHAR) z;
6661 #ifdef IKS_OPTION
6662 /* If IKS negotiation in use */
6663 if (TELOPT_U(TELOPT_KERMIT) || TELOPT_ME(TELOPT_KERMIT))
6664 tn_siks(KERMIT_SOP); /* Report change to other side */
6665 #endif /* IKS_OPTION */
6666 }
6667 return(success = y);
6668
6669 case XYNPAD: /* PADDING */
6670 y = cmnum("How many padding characters for inbound packets","0",10,&x,
6671 xxstring);
6672 if ((y = setnum(&z,x,y,94)) < 0) return(y);
6673 if (xx == XYRECV)
6674 mypadn = (CHAR) z;
6675 else
6676 npad = (CHAR) z;
6677 return(success = y);
6678
6679 case XYPADC: /* PAD-CHARACTER */
6680 if ((y = setcc("0",&z)) < 0) return(y);
6681 if (xx == XYRECV) mypadc = z; else padch = z;
6682 return(success = y);
6683
6684 case XYTIMO: /* TIMEOUT */
6685 if (xx == XYRECV) {
6686 y = cmnum("Packet timeout interval",ckitoa(URTIME),10,&x,xxstring);
6687 if ((y = setnum(&z,x,y,94)) < 0) return(y);
6688
6689 if (rmsflg) { /* REMOTE SET RECEIVE TIMEOUT */
6690 sstate = setgen('S', "402", ckitoa(z), "");
6691 return((int) sstate);
6692 } else { /* SET RECEIVE TIMEOUT */
6693 pkttim = z; /* Value to put in my negotiation */
6694 } /* packet for other Kermit to use */
6695
6696 } else { /* SET SEND TIMEOUT */
6697 #ifdef CK_TIMERS
6698 extern int rttflg, mintime, maxtime;
6699 int tmin = 0, tmax = 0;
6700 #endif /* CK_TIMERS */
6701 y = cmnum("Packet timeout interval",ckitoa(DMYTIM),10,&x,xxstring);
6702 if (y == -3) { /* They cancelled a previous */
6703 x = DMYTIM; /* SET SEND command, so restore */
6704 timef = 0; /* and turn off the override flag */
6705 y = cmcfm();
6706 }
6707 #ifdef CK_TIMERS
6708 if (y < 0) return(y);
6709 if (x < 0) {
6710 printf("?Out of range - %d\n",x);
6711 return(-9);
6712 }
6713 if ((z = cmkey(timotab,2,"","dynamic",xxstring)) < 0) return(z);
6714 if (z) {
6715 if ((y = cmnum("Minimum timeout to allow",
6716 "1",10,&tmin,xxstring)) < 0)
6717 return(y);
6718 if (tmin < 1) {
6719 printf("?Out of range - %d\n",tmin);
6720 return(-9);
6721 }
6722 if ((y = cmnum("Maximum timeout to allow",
6723 "0",10,&tmax,xxstring)) < 0)
6724 return(y);
6725 /* 0 means let Kermit choose, < 0 means no maximum */
6726 }
6727 if ((y = cmcfm()) < 0)
6728 return(y);
6729 rttflg = z; /* Round-trip timer flag */
6730 z = x;
6731 #else
6732 if ((y = setnum(&z,x,y,94)) < 0)
6733 return(y);
6734 #endif /* CK_TIMERS */
6735 timef = 1; /* Turn on the override flag */
6736 timint = rtimo = z; /* Override value for me to use */
6737 #ifdef CK_TIMERS
6738 if (rttflg) { /* Lower and upper bounds */
6739 mintime = tmin;
6740 maxtime = tmax;
6741 }
6742 #endif /* CK_TIMERS */
6743 }
6744 return(success = 1);
6745
6746 case XYFPATH: /* PATHNAMES */
6747 if (xx == XYRECV) {
6748 y = cmkey(rpathtab,nrpathtab,"","auto",xxstring);
6749 } else {
6750 y = cmkey(pathtab,npathtab,"","off",xxstring);
6751 }
6752 if (y < 0) return(y);
6753
6754 if ((x = cmcfm()) < 0) return(x);
6755 if (xx == XYRECV) { /* SET RECEIVE PATHNAMES */
6756 fnrpath = y;
6757 ptab[protocol].fnrp = fnrpath;
6758 } else { /* SET SEND PATHNAMES */
6759 fnspath = y;
6760 ptab[protocol].fnsp = fnspath;
6761 }
6762 return(success = 1); /* Note: 0 = ON, 1 = OFF */
6763 /* In other words, ON = leave pathnames ON, OFF = take them off. */
6764
6765 case XYPAUS: /* SET SEND/RECEIVE PAUSE */
6766 y = cmnum("Milliseconds to pause between packets","0",10,&x,xxstring);
6767 if ((y = setnum(&z,x,y,15000)) < 0)
6768 return(y);
6769 pktpaus = z;
6770 return(success = 1);
6771
6772 #ifdef CKXXCHAR /* SET SEND/RECEIVE IGNORE/DOUBLE */
6773 case XYIGN:
6774 case XYDBL: {
6775 int i, zz;
6776 short *p;
6777 extern short dblt[];
6778 extern int dblflag, ignflag;
6779
6780 /* Make space for a temporary copy of the ignore/double table */
6781
6782 zz = y;
6783 #ifdef COMMENT
6784 if (zz == XYIGN && xx == XYSEND) {
6785 blah blah who cares
6786 }
6787 if (zz == XYDBL && xx == XYRECV) {
6788 blah blah
6789 }
6790 #endif /* COMMENT */
6791 p = (short *)malloc(256 * sizeof(short));
6792 if (!p) {
6793 printf("?Internal error - malloc failure\n");
6794 return(-9);
6795 }
6796 for (i = 0; i < 256; i++) p[i] = dblt[i]; /* Copy current table */
6797
6798 while (1) { /* Collect a list of numbers */
6799 #ifndef NOSPL
6800 x_ifnum = 1; /* Turn off complaints from eval() */
6801 #endif /* NOSPL */
6802 if ((x = cmnum(zz == XYDBL ?
6803 "Character to double" :
6804 "Character to ignore",
6805 "",10,&y,xxstring
6806 )) < 0) {
6807 #ifndef NOSPL
6808 x_ifnum = 0;
6809 #endif /* NOSPL */
6810 if (x == -3) /* Done */
6811 break;
6812 if (x == -2) {
6813 if (p) { free(p); p = NULL; }
6814 debug(F110,"SET S/R DOUBLE/IGNORE atmbuf",atmbuf,0);
6815 if (!ckstrcmp(atmbuf,"none",4,0) ||
6816 !ckstrcmp(atmbuf,"non",3,0) ||
6817 !ckstrcmp(atmbuf,"no",2,0) ||
6818 !ckstrcmp(atmbuf,"n",1,0)) {
6819 if ((x = cmcfm()) < 0) /* Get confirmation */
6820 return(x);
6821 for (y = 0; y < 256; y++)
6822 dblt[y] &= (zz == XYDBL) ? 1 : 2;
6823 if (zz == XYDBL) dblflag = 0;
6824 if (zz == XYIGN) ignflag = 0;
6825 return(success = 1);
6826 } else {
6827 printf(
6828 "?Please specify a number or the word NONE\n");
6829 return(-9);
6830 }
6831 } else {
6832 free(p);
6833 p = NULL;
6834 return(x);
6835 }
6836 }
6837 #ifndef NOSPL
6838 x_ifnum = 0;
6839 #endif /* NOSPL */
6840 if (y < 0 || y > 255) {
6841 printf("?Please enter a character code in range 0-255\n");
6842 free(p);
6843 p = NULL;
6844 return(-9);
6845 }
6846 p[y] |= (zz == XYDBL) ? 2 : 1;
6847 if (zz == XYDBL) dblflag = 1;
6848 if (zz == XYIGN) ignflag = 1;
6849 } /* End of while loop */
6850
6851 if ((x = cmcfm()) < 0) return(x);
6852 /*
6853 Get here only if they have made no mistakes. Copy temporary table back to
6854 permanent one, then free temporary table and return successfully.
6855 */
6856 if (p) {
6857 for (i = 0; i < 256; i++) dblt[i] = p[i];
6858 free(p);
6859 p = NULL;
6860 }
6861 return(success = 1);
6862 }
6863 #endif /* CKXXCHAR */
6864
6865 #ifdef PIPESEND
6866 case XYFLTR: { /* SET { SEND, RECEIVE } FILTER */
6867 if ((y = cmtxt((xx == XYSEND) ?
6868 "Filter program for sending files -\n\
6869 use \\v(filename) to substitute filename" :
6870 "Filter program for receiving files -\n\
6871 use \\v(filename) to substitute filename",
6872 "",&s,NULL)) < 0)
6873 return(y);
6874 if (!*s) { /* Removing a filter... */
6875 if (xx == XYSEND && sndfilter) {
6876 makestr(&g_sfilter,NULL);
6877 makestr(&sndfilter,NULL);
6878 } else if (rcvfilter) {
6879 makestr(&g_rfilter,NULL);
6880 makestr(&rcvfilter,NULL);
6881 }
6882 return(success = 1);
6883 } /* Adding a filter... */
6884 s = brstrip(s); /* Strip any braces */
6885 y = strlen(s);
6886 if (xx == XYSEND) { /* For SEND filter... */
6887 for (x = 0; x < y; x++) { /* make sure they included "\v(...)" */
6888 if (s[x] != '\\') continue;
6889 if (s[x+1] == 'v') break;
6890 }
6891 if (x == y) {
6892 printf(
6893 "?Filter must contain a replacement variable for filename.\n"
6894 );
6895 return(-9);
6896 }
6897 }
6898 if (xx == XYSEND) {
6899 makestr(&sndfilter,s);
6900 makestr(&g_sfilter,s);
6901 } else {
6902 makestr(&rcvfilter,s);
6903 makestr(&g_rfilter,s);
6904 }
6905 return(success = 1);
6906 }
6907 #endif /* PIPESEND */
6908
6909 case XYINIL:
6910 y = cmnum("Max length for protocol init string","-1",10,&x,xxstring);
6911 if ((y = setnum(&z,x,y,-1)) < 0)
6912 return(y);
6913 if (xx == XYSEND)
6914 sprmlen = z;
6915 else
6916 rprmlen = z;
6917 return(success = 1);
6918
6919 case 993: {
6920 extern int sendipkts;
6921 if (xx == XYSEND) {
6922 if ((x = seton(&sendipkts)) < 0)
6923 return(x);
6924 }
6925 return(1);
6926 }
6927 #ifdef CK_PERMS
6928 case 994:
6929 switch(xx) {
6930 case XYSEND:
6931 if ((x = seton(&atlpro)) < 0) return(x);
6932 atgpro = atlpro;
6933 return(1);
6934 case XYRECV:
6935 if ((x = seton(&atlpri)) < 0) return(x);
6936 atgpri = atlpri;
6937 return(1);
6938 default:
6939 return(-2);
6940 }
6941 #endif /* CK_PERMS */
6942
6943 #ifndef NOCSETS
6944 case XYCSET: { /* CHARACTER-SET-SELECTION */
6945 extern struct keytab xfrmtab[];
6946 extern int r_cset, s_cset;
6947 if ((y = cmkey(xfrmtab,2,"","automatic",xxstring)) < 0)
6948 return(y);
6949 if ((x = cmcfm()) < 0)
6950 return(x);
6951 if (xx == XYSEND)
6952 s_cset = y;
6953 else
6954 r_cset = y;
6955 return(success = 1);
6956 }
6957 #endif /* NOCSETS */
6958
6959 case XYBUP:
6960 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0)
6961 return(y);
6962 if ((x = cmcfm()) < 0) return(x);
6963 if (xx == XYSEND) {
6964 extern int skipbup;
6965 skipbup = (y == 0) ? 1 : 0;
6966 return(success = 1);
6967 } else {
6968 printf(
6969 "?Please use SET FILE COLLISION to choose the desired action\n");
6970 return(-9);
6971 }
6972
6973 case XYMOVE:
6974 #ifdef COMMENT
6975 y = cmdir("Directory to move file(s) to after successful transfer",
6976 "",&s,xxstring);
6977 #else
6978 y = cmtxt("Directory to move file(s) to after successful transfer",
6979 "",&s,xxstring);
6980 #endif /* COMMENT */
6981
6982 if (y < 0 && y != -3)
6983 return(y);
6984 ckstrncpy(line,s,LINBUFSIZ);
6985 s = brstrip(line);
6986
6987 #ifdef COMMENT
6988 /* Only needed for cmdir() */
6989 if ((x = cmcfm()) < 0)
6990 return(x);
6991 #endif /* COMMENT */
6992
6993 /* Check directory existence if absolute */
6994 /* THIS MEANS IT CAN'T INCLUDE ANY DEFERRED VARIABLES! */
6995 if (s) if (*s) {
6996 if (isabsolute(s) && !isdir(s)) {
6997 printf("?Directory does not exist - %s\n",s);
6998 return(-9);
6999 }
7000 }
7001 if (xx == XYSEND) {
7002 if (*s) {
7003 #ifdef COMMENT
7004 /* Allow it to be relative */
7005 zfnqfp(s,LINBUFSIZ,line);
7006 #endif /* COMMENT */
7007 makestr(&snd_move,line);
7008 makestr(&g_snd_move,line);
7009 } else {
7010 makestr(&snd_move,NULL);
7011 makestr(&g_snd_move,NULL);
7012 }
7013 } else {
7014 if (*s) {
7015 #ifdef COMMENT
7016 /* Allow it to be relative */
7017 zfnqfp(s,LINBUFSIZ,line);
7018 #endif /* COMMENT */
7019 makestr(&rcv_move,line);
7020 makestr(&g_rcv_move,line);
7021 } else {
7022 makestr(&rcv_move,NULL);
7023 makestr(&g_rcv_move,NULL);
7024 }
7025 }
7026 return(success = 1);
7027
7028 case XYRENAME:
7029 y = cmtxt("Template to rename file(s) to after successful transfer",
7030 "",&s,NULL); /* NOTE: no xxstring */
7031 if (y < 0 && y != -3) /* Evaluation is deferred */
7032 return(y);
7033 ckstrncpy(line,s,LINBUFSIZ);
7034 s = brstrip(line);
7035 if ((x = cmcfm()) < 0)
7036 return(x);
7037 if (xx == XYSEND) {
7038 if (*s) {
7039 makestr(&snd_rename,s);
7040 makestr(&g_snd_rename,s);
7041 } else {
7042 makestr(&snd_rename,NULL);
7043 makestr(&g_snd_rename,NULL);
7044 }
7045 } else {
7046 if (*s) {
7047 makestr(&rcv_rename,s);
7048 makestr(&g_rcv_rename,s);
7049 } else {
7050 makestr(&rcv_rename,NULL);
7051 makestr(&g_rcv_rename,NULL);
7052 }
7053 }
7054 return(success = 1);
7055
7056 #ifdef VMS
7057 case 887: /* VERSION-NUMBERS */
7058 if (xx == XYSEND) {
7059 extern int vmssversions;
7060 return(seton(&vmssversions));
7061 } else {
7062 extern int vmsrversions;
7063 return(seton(&vmsrversions));
7064 }
7065 #endif /* VMS */
7066
7067 default:
7068 return(-2);
7069 } /* End of SET SEND/RECEIVE... */
7070 }
7071 #endif /* NOXFER */
7072
7073 #ifndef NOXMIT
7074 int
setxmit()7075 setxmit() {
7076 if ((y = cmkey(xmitab,nxmit,"","",xxstring)) < 0) return(y);
7077 switch (y) {
7078 case XMITE: /* EOF */
7079 y = cmtxt("Characters to send at end of file,\n\
7080 Use backslash codes for control characters","",&s,xxstring);
7081 if (y < 0) return(y);
7082 if ((int)strlen(s) > XMBUFL) {
7083 printf("?Too many characters, %d maximum\n",XMBUFL);
7084 return(-2);
7085 }
7086 ckstrncpy(xmitbuf,s,XMBUFL);
7087 return(success = 1);
7088
7089 case XMITF: /* Fill */
7090 y = cmnum("Numeric code for blank-line fill character","0",10,&x,
7091 xxstring);
7092 if ((y = setnum(&z,x,y,127)) < 0) return(y);
7093 xmitf = z;
7094 return(success = 1);
7095 case XMITL: /* Linefeed */
7096 return(seton(&xmitl));
7097 case XMITS: /* Locking-Shift */
7098 return(seton(&xmits));
7099 case XMITP: /* Prompt */
7100 y = cmnum("Numeric code for host's prompt character, 0 for none",
7101 "10",10,&x,xxstring);
7102 if ((y = setnum(&z,x,y,127)) < 0) return(y);
7103 xmitp = z;
7104 return(success = 1);
7105 case XMITX: /* Echo */
7106 return(seton(&xmitx));
7107 case XMITW: /* Pause */
7108 y = cmnum("Number of milliseconds to pause between binary characters\n\
7109 or text lines during transmission","0",10,&x,xxstring);
7110 if ((y = setnum(&z,x,y,1000)) < 0) return(y);
7111 xmitw = z;
7112 return(success = 1);
7113 case XMITT: /* Timeout */
7114 y = cmnum("Seconds to wait for each character to echo",
7115 "1",10,&x,xxstring);
7116 if ((y = setnum(&z,x,y,1000)) < 0) return(y);
7117 xmitt = z;
7118 return(success = 1);
7119 default:
7120 return(-2);
7121 }
7122 }
7123 #endif /* NOXMIT */
7124
7125 #ifndef NOXFER
7126 /* D O R M T -- Do a remote command */
7127
7128 VOID
rmsg()7129 rmsg() {
7130 if (pflag && !quiet && fdispla != XYFD_N)
7131 printf(
7132 #ifdef CK_NEED_SIG
7133 " Type your escape character, %s, followed by X or E to cancel.\n",
7134 dbchr(escape)
7135 #else
7136 " Press the X or E key to cancel.\n"
7137 #endif /* CK_NEED_SIG */
7138 );
7139 }
7140
7141 static int xzcmd = 0; /* Global copy of REMOTE cmd index */
7142
7143 /* R E M C F M -- Confirm a REMOTE command */
7144 /*
7145 Like cmcfm(), but allows for a redirection indicator on the end,
7146 like "> filename" or "| command". Returns what cmcfm() would have
7147 returned: -1 if reparse needed, etc etc blah blah. On success,
7148 returns 1 with:
7149
7150 char * remdest containing the name of the file or command.
7151 int remfile set to 1 if there is to be any redirection.
7152 int remappd set to 1 if output file is to be appended to.
7153 int rempipe set to 1 if remdest is a command, 0 if it is a file.
7154 */
7155 static int
remcfm()7156 remcfm() {
7157 int x = 0;
7158 char *s;
7159 char *helptxt = "> filename, | command,\n\
7160 or type carriage return to confirm the command";
7161 char c;
7162
7163 remfile = 0;
7164 rempipe = 0;
7165 remappd = 0;
7166
7167 if ((x = cmtxt(helptxt,"",&s,xxstring)) < 0) {
7168 return(x);
7169 }
7170 if (remdest) {
7171 free(remdest);
7172 remdest = NULL;
7173 }
7174 debug(F101,"remcfm local","",local);
7175 debug(F110,"remcfm s",s,0);
7176 debug(F101,"remcfm cmd","",xzcmd);
7177 /*
7178 This check was added in C-Kermit 6.0 or 7.0 but it turns out to be
7179 unhelpful in the situation where the remote is running a script that sends
7180 REMOTE commands to the local workstation. What happens is, the local
7181 server executes the command and sends the result back as screen text, which
7182 is indicated by using an X packet instead of an F packet as the file
7183 header. There are two parts to this: executing the command under control
7184 of the remote Kermit, which is desirable (and in fact some big applications
7185 depend on it, and therefore never installed any new C-Kermit versions after
7186 5A), and displaying the result. Commenting out the check allows the
7187 command to be executed, but the result is still sent back to the remote in
7188 a file transfer, where it vanishes into the ether. Actually it's on the
7189 communication connection, mixed in with the packets. Pretty amazing that
7190 the file transfer still works, right?
7191 */
7192 #ifdef COMMENT
7193 if (!*s) { /* No redirection indicator */
7194 if (!local &&
7195 (xzcmd == XZDIR || xzcmd == XZTYP ||
7196 xzcmd == XZXIT || xzcmd == XZSPA ||
7197 xzcmd == XZHLP || xzcmd == XZPWD ||
7198 xzcmd == XZLGI || xzcmd == XZLGO ||
7199 xzcmd == XZWHO || xzcmd == XZHOS)) {
7200 printf("?\"%s\" has no effect in remote mode\n",cmdbuf);
7201 return(-9);
7202 } else
7203 return(1);
7204 }
7205 #endif /* COMMENT */
7206
7207 if (!s) s = ""; /* 2014-11-03 */
7208 if (!*s) return(1); /* 2014-11-03 */
7209
7210 c = *s; /* We have something */
7211 if (c != '>' && c != '|') { /* Is it > or | ? */
7212 printf("?Not confirmed\n"); /* No */
7213 return(-9);
7214 }
7215 s++; /* See what follows */
7216 if (c == '>' && *s == '>') { /* Allow for ">>" too */
7217 s++;
7218 remappd = 1; /* Append to output file */
7219 }
7220 while (*s == SP || *s == HT) s++; /* Strip intervening whitespace */
7221 if (!*s) {
7222 printf("?%s missing\n", c == '>' ? "Filename" : "Command");
7223 return(-9);
7224 }
7225 if (c == '>' && zchko(s) < 0) { /* Check accessibility */
7226 printf("?Access denied - %s\n", s);
7227 return(-9);
7228 }
7229 remfile = 1; /* Set global results */
7230 rempipe = (c == '|');
7231 if (rempipe
7232 #ifndef NOPUSH
7233 && nopush
7234 #endif /* NOPUSH */
7235 ) {
7236 printf("?Sorry, access to external commands is disabled.\n");
7237 return(-9);
7238 }
7239 makestr(&remdest,s);
7240 #ifndef NODEBUG
7241 if (deblog) {
7242 debug(F101,"remcfm remfile","",remfile);
7243 debug(F101,"remcfm remappd","",remappd);
7244 debug(F101,"remcfm rempipe","",rempipe);
7245 debug(F110,"remcfm remdest",remdest, 0);
7246 }
7247 #endif /* NODEBUG */
7248 return(1);
7249 }
7250
7251 /* R E M T X T -- Like remcfm()... */
7252 /*
7253 ... but for REMOTE commands that end with cmtxt().
7254 Here we must decipher braces to discover whether the trailing
7255 redirection indicator is intended for local use, or to be sent out
7256 to the server, as in:
7257
7258 remote host blah blah > file This end
7259 remote host { blah blah } > file This end
7260 remote host { blah blah > file } That end
7261 remote host { blah blah > file } > file Both ends
7262
7263 Pipes too:
7264
7265 remote host blah blah | cmd This end
7266 remote host { blah blah } | cmd This end
7267 remote host { blah blah | cmd } That end
7268 remote host { blah blah | cmd } | cmd Both ends
7269
7270 Or both:
7271
7272 remote host blah blah | cmd > file This end, etc etc...
7273
7274 Note: this really only makes sense for REMOTE HOST, but why be picky?
7275 Call after calling cmtxt(), with pointer to string that cmtxt() parsed,
7276 as in "remtxt(&s);".
7277
7278 Returns:
7279 1 on success with braces & redirection things removed & pointer updated,
7280 -9 on failure (bad indirection), after printing error message.
7281 */
7282 int
remtxt(p)7283 remtxt(p) char ** p; {
7284 int i, x, bpos, ppos;
7285 char c, *s, *q;
7286
7287 remfile = 0; /* Initialize global results */
7288 rempipe = 0;
7289 remappd = 0;
7290 if (remdest) {
7291 free(remdest);
7292 remdest = NULL;
7293 }
7294 s = *p;
7295 if (!s) /* No redirection indicator */
7296 s = "";
7297 #ifdef COMMENT
7298 if (!*s) { /* Ditto */
7299 if (!local &&
7300 (xzcmd == XZDIR || xzcmd == XZTYP ||
7301 xzcmd == XZXIT || xzcmd == XZSPA ||
7302 xzcmd == XZHLP || xzcmd == XZPWD ||
7303 xzcmd == XZLGI || xzcmd == XZLGO ||
7304 xzcmd == XZWHO || xzcmd == XZHOS)) {
7305 printf("?\"%s\" has no effect in remote mode\n",cmdbuf);
7306 if (hints) {
7307 printf("Hint: Try again with an output redirector.\n");
7308 }
7309 return(-9);
7310 } else
7311 return(1);
7312 }
7313 #endif /* COMMENT */
7314 bpos = -1; /* Position of > (bracket) */
7315 ppos = -1; /* Position of | (pipe) */
7316 x = strlen(s); /* Length of cmtxt() string */
7317
7318 for (i = x-1; i >= 0; i--) { /* Search right to left. */
7319 c = s[i];
7320 if (c == '}') /* Break on first right brace */
7321 break; /* Don't look at contents of braces */
7322 else if (c == '>') /* Record position of > */
7323 bpos = i;
7324 else if (c == '|') /* and of | */
7325 ppos = i;
7326 }
7327 if (bpos < 0 && ppos < 0) { /* No redirectors. */
7328 #ifdef COMMENT
7329 if (!local &&
7330 (xzcmd == XZDIR || xzcmd == XZTYP ||
7331 xzcmd == XZXIT || xzcmd == XZSPA ||
7332 xzcmd == XZHLP || xzcmd == XZPWD ||
7333 xzcmd == XZLGI || xzcmd == XZLGO ||
7334 xzcmd == XZWHO || xzcmd == XZHOS)) {
7335 printf("?\"%s\" has no effect in remote mode\n",cmdbuf);
7336 if (hints) {
7337 printf("Hint: Try again with an output redirector.\n");
7338 }
7339 return(-9);
7340 }
7341 #endif /* COMMENT */
7342 s = brstrip(s); /* Remove outer braces if any. */
7343 *p = s; /* Point to result */
7344 return(1); /* and return. */
7345 }
7346 remfile = 1; /* It's | or > */
7347 i = -1; /* Get leftmost symbol */
7348 if (bpos > -1) /* Bracket */
7349 i = bpos;
7350 if (ppos > -1 && (ppos < bpos || bpos < 0)) { /* or pipe */
7351 i = ppos;
7352 rempipe = 1;
7353 }
7354 if (rempipe
7355 #ifndef NOPUSH
7356 && nopush
7357 #endif /* NOPUSH */
7358 ) {
7359 printf("?Sorry, access to external commands is disabled.\n");
7360 return(-9);
7361 }
7362 c = s[i]; /* Copy of symbol */
7363
7364 if (c == '>' && s[i+1] == '>') /* ">>" for append? */
7365 remappd = 1; /* It's not just a flag it's a number */
7366
7367 q = s + i + 1 + remappd; /* Point past symbol in string */
7368 while (*q == SP || *q == HT) q++; /* and any intervening whitespace */
7369 if (!*q) {
7370 printf("?%s missing\n", c == '>' ? "Filename" : "Command");
7371 return(-9);
7372 }
7373 if (c == '>' && zchko(q) < 0) { /* (Doesn't work for | cmd > file) */
7374 printf("?Access denied - %s\n", q);
7375 return(-9);
7376 }
7377 makestr(&remdest,q); /* Create the destination string */
7378 q = s + i - 1; /* Point before symbol */
7379 while (q > s && (*q == SP || *q == HT)) /* Strip trailing whitespace */
7380 q--;
7381 *(q+1) = NUL; /* Terminate the string. */
7382 s = brstrip(s); /* Remove any braces */
7383 *p = s; /* Set return value */
7384
7385 #ifndef NODEBUG
7386 if (deblog) {
7387 debug(F101,"remtxt remfile","",remfile);
7388 debug(F101,"remtxt remappd","",remappd);
7389 debug(F101,"remtxt rempipe","",rempipe);
7390 debug(F110,"remtxt remdest",remdest, 0);
7391 debug(F110,"remtxt command",s,0);
7392 }
7393 #endif /* NODEBUG */
7394
7395 return(1);
7396 }
7397
7398 int
plogin(xx)7399 plogin(xx) int xx; {
7400 char *p1 = NULL, *p2 = NULL, *p3 = NULL;
7401 int psaved = 0, rc = 0;
7402 #ifdef CK_RECALL
7403 extern int on_recall; /* around Password prompting */
7404 #endif /* CK_RECALL */
7405 debug(F101,"plogin local","",local);
7406
7407 if (!local || (network && ttchk() < 0)) {
7408 printf("?No connection\n");
7409 return(-9);
7410 }
7411 if ((x = cmfld("User ID","",&s,xxstring)) < 0) { /* Get User ID */
7412 if (x != -3) return(x);
7413 }
7414 y = strlen(s);
7415 if (y > 0) {
7416 if ((p1 = malloc(y + 1)) == NULL) {
7417 printf("?Internal error: malloc\n");
7418 rc = -9;
7419 goto XZXLGI;
7420 } else
7421 strcpy(p1,s); /* safe */
7422 if ((rc = cmfld("Password","",&s,xxstring)) < 0)
7423 if (rc != -3) goto XZXLGI;
7424 y = strlen(s);
7425 if (y > 0) {
7426 if ((p2 = malloc(y + 1)) == NULL) {
7427 printf("?Internal error: malloc\n");
7428 rc = -9;
7429 goto XZXLGI;
7430 } else
7431 strcpy(p2,s); /* safe */
7432 if ((rc = cmfld("Account","",&s,xxstring)) < 0)
7433 if (rc != -3) goto XZXLGI;
7434 y = strlen(s);
7435 if (y > 0) {
7436 if ((p3 = malloc(y + 1)) == NULL) {
7437 printf("?Internal error: malloc\n");
7438 rc = -9;
7439 goto XZXLGI;
7440 } else
7441 strcpy(p3,s); /* safe */
7442 }
7443 }
7444 }
7445 if ((rc = remtxt(&s)) < 0) /* Confirm & handle redirectors */
7446 goto XZXLGI;
7447
7448 if (!p1) { /* No Userid specified... */
7449 debok = 0; /* Don't log this */
7450 /* Prompt for username, password, and account */
7451 #ifdef CK_RECALL
7452 on_recall = 0;
7453 #endif /* CK_RECALL */
7454 cmsavp(psave,PROMPTL); /* Save old prompt */
7455 psaved = 1;
7456 debug(F110,"REMOTE LOGIN saved",psave,0);
7457
7458 cmsetp("Username: "); /* Make new prompt */
7459 concb((char)escape); /* Put console in cbreak mode */
7460 cmini(1);
7461 prompt(xxstring);
7462 rc = -9;
7463 for (x = -1; x < 0; ) { /* Prompt till they answer */
7464 cmres(); /* Reset the parser */
7465 x = cmtxt("","",&s,NULL); /* Get a literal line of text */
7466 }
7467 y = strlen(s);
7468 if (y < 1) {
7469 printf("?Canceled\n");
7470 goto XZXLGI;
7471 }
7472 if ((p1 = malloc(y + 1)) == NULL) {
7473 printf("?Internal error: malloc\n");
7474 goto XZXLGI;
7475 } else
7476 strcpy(p1,s); /* safe */
7477
7478 cmsetp("Password: "); /* Make new prompt */
7479 concb((char)escape); /* Put console in cbreak mode */
7480 cmini(0); /* No echo */
7481 prompt(xxstring);
7482 debok = 0;
7483 for (x = -1; x < 0 && x != -3; ) { /* Get answer */
7484 cmres(); /* Reset the parser */
7485 x = cmtxt("","",&s,NULL); /* Get literal line of text */
7486 }
7487 if ((p2 = malloc((int)strlen(s) + 1)) == NULL) {
7488 printf("?Internal error: malloc\n");
7489 goto XZXLGI;
7490 } else
7491 strcpy(p2,s); /* safe */
7492 printf("\r\n");
7493 if ((rc = cmcfm()) < 0)
7494 goto XZXLGI;
7495 }
7496 sstate = setgen('I',p1,p2,p3); /* Get here with at least user ID */
7497 rc = 0;
7498
7499 XZXLGI: /* Common exit point */
7500 if (psaved)
7501 cmsetp(psave); /* Restore original prompt */
7502 if (p3) { free(p3); p3 = NULL; } /* Free malloc'd storage */
7503 if (p2) { free(p2); p2 = NULL; }
7504 if (p1) { free(p1); p1 = NULL; }
7505 if (rc > -1) {
7506 if (local && rc > -1) /* If local, flush tty input buffer */
7507 ttflui();
7508 }
7509 return(rc);
7510 }
7511
7512 #ifdef OS2
7513 #ifndef NOLOCAL
7514 int
dormt(xx)7515 dormt(xx) int xx; {
7516 int rc = 0;
7517 extern int term_io;
7518 int term_io_sav = term_io;
7519 #ifdef NEWFTP
7520 extern int ftpget, ftpisopen();
7521 if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
7522 return(doftprmt(xx,0));
7523 #endif /* NEWFTP */
7524 term_io = 0;
7525 rc = xxdormt(xx);
7526 term_io = term_io_sav;
7527 return rc;
7528 }
7529
7530
7531 int
xxdormt(xx)7532 xxdormt(xx) int xx;
7533 #else /* NOLOCAL */
7534 int
7535 dormt(xx) int xx;
7536 #endif /* NOLOCAL */
7537 #else /* OS2 */
7538 int
7539 dormt(xx) int xx;
7540 #endif /* OS2 */
7541 { /* REMOTE commands */
7542 int x, y, retcode;
7543 char *s, sbuf[50], *s2;
7544
7545 #ifdef NEWFTP
7546 extern int ftpget, ftpisopen();
7547 if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
7548 return(doftprmt(xx,0));
7549 #endif /* NEWFTP */
7550
7551 remfile = 0; /* Clear these */
7552 rempipe = 0;
7553 remappd = 0;
7554
7555 debug(F101,"XXX xxdormt xx","",xx);
7556
7557 if (xx < 0) return(xx); /* REMOTE what? */
7558
7559 xzcmd = xx; /* Make global copy of arg */
7560
7561 if (xx == XZSET) { /* REMOTE SET */
7562 if ((y = cmkey(rmstab,nrms,"","",xxstring)) < 0) {
7563 if (y == -3) {
7564 printf("?Parameter name required\n");
7565 return(-9);
7566 } else return(y);
7567 }
7568 return(doprm(y,1));
7569 }
7570
7571 switch (xx) { /* Others... */
7572
7573 case XZCDU:
7574 if ((x = cmcfm()) < 0) return(x);
7575 printf("?Sorry, REMOTE CDUP not supported yet\n");
7576 return(-9);
7577
7578 case XZCWD: /* CWD (CD) */
7579 if ((x = cmtxt("Remote directory name","",&s,xxstring)) < 0)
7580 return(x);
7581 if ((x = remtxt(&s)) < 0)
7582 return(x);
7583 debug(F111,"XZCWD: ",s,x);
7584 *sbuf = NUL;
7585 s2 = sbuf;
7586 /*
7587 The following is commented out because since the disappearance of the
7588 DECSYSTEM-20 from the planet, no known computer requires a password for
7589 changing directory.
7590 */
7591 #ifdef DIRPWDPR
7592 if (*s != NUL) { /* If directory name given, */
7593 /* get password on separate line. */
7594 if (tlevel > -1) { /* From take file... */
7595
7596 if (fgets(sbuf,50,tfile[tlevel]) == NULL)
7597 fatal("take file ends prematurely in 'remote cwd'");
7598 debug(F110," pswd from take file",s2,0);
7599 for (x = (int)strlen(sbuf);
7600 x > 0 && (sbuf[x-1] == NL || sbuf[x-1] == CR);
7601 x--)
7602 sbuf[x-1] = '\0';
7603
7604 } else { /* From terminal... */
7605
7606 printf(" Password: "); /* get a password */
7607 #ifdef IKSD
7608 if (!local && inserver) {
7609 x = coninc(0);
7610 } else
7611 #endif /* IKSD */
7612 #ifdef OS2
7613 x = is_a_tty(0) ? coninc(0) : /* with no echo ... */
7614 getchar();
7615 #else /* OS2 */
7616 x = getchar();
7617 #endif /* OS2 */
7618 while ((x != NL) && (x != CR)) {
7619 if ((x &= 0177) == '?') {
7620 printf("? Password of remote directory\n Password: ");
7621 s2 = sbuf;
7622 *sbuf = NUL;
7623 } else if (x == ESC) /* Mini command line editor... */
7624 bleep(BP_WARN);
7625 else if (x == BS || x == 0177)
7626 s2--;
7627 else if (x == 025) { /* Ctrl-U */
7628 s2 = sbuf;
7629 *sbuf = NUL;
7630 } else
7631 *s2++ = x;
7632
7633 /* Get the next character */
7634 #ifdef IKSD
7635 if (!local && inserver) {
7636 x = coninc(0);
7637 } else
7638 #endif /* IKSD */
7639 #ifdef OS2
7640 x = is_a_tty(0) ? coninc(0) : /* with no echo ... */
7641 getchar();
7642 #else /* OS2 */
7643 x = getchar();
7644 #endif /* OS2 */
7645 }
7646 *s2 = NUL;
7647 putchar('\n');
7648 }
7649 s2 = sbuf;
7650 } else s2 = "";
7651 #endif /* DIRPWDPR */
7652
7653 debug(F110," password",s2,0);
7654 rcdactive = 1;
7655 sstate = setgen('C',s,s2,"");
7656 retcode = 0;
7657 break;
7658
7659 case XZDEL: /* Delete */
7660 if ((x = cmtxt("Name of remote file(s) to delete",
7661 "",&s,xxstring)) < 0) {
7662 if (x == -3) {
7663 printf("?Name of remote file(s) required\n");
7664 return(-9);
7665 } else return(x);
7666 }
7667 if ((x = remtxt(&s)) < 0)
7668 return(x);
7669 if (local) ttflui(); /* If local, flush tty input buffer */
7670 retcode = sstate = rfilop(s,'E');
7671 break;
7672
7673 case XZDIR: /* Directory */
7674 if ((x = cmtxt("Remote directory or file specification","",&s,
7675 xxstring)) < 0)
7676 return(x);
7677 if ((x = remtxt(&s)) < 0)
7678 return(x);
7679 if (local) ttflui(); /* If local, flush tty input buffer */
7680 rmsg();
7681 retcode = sstate = setgen('D',s,"","");
7682 break;
7683
7684 case XZHLP: /* Help */
7685 if ((x = remcfm()) < 0) return(x);
7686 sstate = setgen('H',"","","");
7687 retcode = 0;
7688 break;
7689
7690 case XZHOS: /* Host */
7691 if ((x = cmtxt("Command for remote system","",&s,xxstring)) < 0)
7692 return(x);
7693 if ((x = remtxt(&s)) < 0)
7694 return(x);
7695 if ((y = (int)strlen(s)) < 1)
7696 return(x);
7697 ckstrncpy(line,s,LINBUFSIZ);
7698 cmarg = line;
7699 rmsg();
7700 retcode = sstate = 'c';
7701 break;
7702
7703 #ifndef NOFRILLS
7704 case XZKER:
7705 if ((x = cmtxt("Command for remote Kermit","",&s,xxstring)) < 0)
7706 return(x);
7707 if ((x = remtxt(&s)) < 0)
7708 return(x);
7709 if ((int)strlen(s) < 1) {
7710 if (x == -3) {
7711 printf("?Remote Kermit command required\n");
7712 return(-9);
7713 } else return(x);
7714 }
7715 ckstrncpy(line,s,LINBUFSIZ);
7716 cmarg = line;
7717 retcode = sstate = 'k';
7718 rmsg();
7719 break;
7720
7721 case XZLGI: /* Login */
7722 rcdactive = 1; /* Suppress "Logged in" msg if quiet */
7723 return(plogin(XXREM));
7724
7725 case XZLGO: { /* Logout */
7726 extern int bye_active;
7727 if ((x = remcfm()) < 0) return(x);
7728 sstate = setgen('I',"","","");
7729 retcode = 0;
7730 bye_active = 1; /* Close connection when done */
7731 break;
7732 }
7733
7734 case XZPRI: /* Print */
7735 if (!atdiso || !atcapr) { /* Disposition attribute off? */
7736 printf("?Disposition Attribute is Off\n");
7737 return(-2);
7738 }
7739 cmarg = "";
7740 cmarg2 = "";
7741 if ((x = cmifi("Local file(s) to print on remote printer","",&s,&y,
7742 xxstring)) < 0) {
7743 if (x == -3) {
7744 printf("?Name of local file(s) required\n");
7745 return(-9);
7746 }
7747 return(x);
7748 }
7749 ckstrncpy(line,s,LINBUFSIZ); /* Make a safe copy of filename */
7750 *optbuf = NUL; /* Wipe out any old options */
7751 if ((x = cmtxt("Options for remote print command","",&s,xxstring)) < 0)
7752 return(x);
7753 if ((x = remtxt(&s)) < 0)
7754 return(x);
7755 if ((int)strlen(optbuf) > 94) { /* Make sure this is legal */
7756 printf("?Option string too long\n");
7757 return(-9);
7758 }
7759 ckstrncpy(optbuf,s,OPTBUFLEN); /* Make a safe copy of options */
7760 nfils = -1; /* Expand file list internally */
7761 cmarg = line; /* Point to file list. */
7762 rprintf = 1; /* REMOTE PRINT modifier for SEND */
7763 sstate = 's'; /* Set start state to SEND */
7764 if (local) displa = 1;
7765 retcode = 0;
7766 break;
7767 #endif /* NOFRILLS */
7768
7769 case XZSPA: /* Space */
7770 if ((x = cmtxt("Confirm, or remote directory name",
7771 "",&s,xxstring)) < 0)
7772 return(x);
7773 if ((x = remtxt(&s)) < 0)
7774 return(x);
7775 retcode = sstate = setgen('U',s,"","");
7776 break;
7777
7778 case XZMSG: /* Message */
7779 if ((x = cmtxt("Short text message for server","",&s,xxstring)) < 0)
7780 return(x);
7781 if ((x = remtxt(&s)) < 0)
7782 return(x);
7783 retcode = sstate = setgen('M',s,"","");
7784 break;
7785
7786 #ifndef NOFRILLS
7787 case XZTYP: /* Type */
7788 if ((x = cmtxt("Remote file specification","",&s,xxstring)) < 0)
7789 return(x);
7790 if ((int)strlen(s) < 1) {
7791 printf("?Remote filename required\n");
7792 return(-9);
7793 }
7794 if ((x = remtxt(&s)) < 0)
7795 return(x);
7796 rmsg();
7797 retcode = sstate = rfilop(s,'T');
7798 break;
7799 #endif /* NOFRILLS */
7800
7801 #ifndef NOFRILLS
7802 case XZWHO:
7803 if ((x = cmtxt("Remote user name, or carriage return",
7804 "",&s,xxstring)) < 0)
7805 return(x);
7806 if ((x = remtxt(&s)) < 0)
7807 return(x);
7808 retcode = sstate = setgen('W',s,"","");
7809 break;
7810 #endif /* NOFRILLS */
7811
7812 case XZPWD: /* PWD */
7813 if ((x = remcfm()) < 0) return(x);
7814 sstate = setgen('A',"","","");
7815 retcode = 0;
7816 break;
7817
7818 #ifndef NOSPL
7819 case XZQUE: { /* Query */
7820 char buf[2];
7821 extern char querybuf[], * qbufp;
7822 extern int qbufn;
7823 if ((y = cmkey(vartyp,nvartyp,"","",xxstring)) < 0)
7824 return(y);
7825 if ((x = cmtxt(y == 'F' ? "Remote function invocation" :
7826 ('K' ? "Remote variable name or function":
7827 "Remote variable name"),
7828 "",
7829 &s,
7830 (y == 'K') ? xxstring : NULL
7831 )) < 0) /* Don't evaluate */
7832 return(x);
7833 if ((x = remtxt(&s)) < 0)
7834 return(x);
7835 query = 1; /* QUERY is active */
7836 qbufp = querybuf; /* Initialize query response buffer */
7837 qbufn = 0;
7838 querybuf[0] = NUL;
7839 buf[0] = (char) (y & 127);
7840 buf[1] = NUL;
7841 retcode = sstate = setgen('V',"Q",(char *)buf,s);
7842 break;
7843 }
7844
7845 case XZASG: { /* Assign */
7846 char buf[VNAML];
7847 if ((y = cmfld("Remote variable name","",&s,NULL)) < 0) /* No eval */
7848 return(y);
7849 if ((int)strlen(s) >= VNAML) {
7850 printf("?Too long\n");
7851 return(-9);
7852 }
7853 ckstrncpy(buf,s,VNAML);
7854 if ((x = cmtxt("Assignment for remote variable",
7855 "",&s,xxstring)) < 0) /* Evaluate this one */
7856 return(x);
7857 if ((x = remtxt(&s)) < 0)
7858 return(x);
7859 #ifdef COMMENT
7860 /*
7861 Server commands can't be long packets. In principle there's no reason
7862 why they shouldn't be, except that we don't know at this point if the
7863 server is capable of accepting long packets because we haven't started
7864 the protocol yet. In practice, allowing a long packet here breaks a lot
7865 of assumptions, causes buffer overruns and crashes, etc. To be fixed
7866 later. (But since this is commented out, evidently I fixed it later...)
7867 */
7868 if ((int)strlen(s) > 85) { /* Allow for encoding expansion */
7869 printf("?Sorry, value is too long - 85 characters max\n");
7870 return(-9);
7871 }
7872 #endif /* COMMENT */
7873 retcode = sstate = setgen('V',"S",(char *)buf,s);
7874 break;
7875 }
7876 #endif /* NOSPL */
7877
7878 case XZCPY: { /* COPY */
7879 char buf[TMPBUFSIZ];
7880 buf[TMPBUFSIZ-1] = '\0';
7881 if ((x = cmfld("Name of remote file to copy","",&s,xxstring)) < 0) {
7882 if (x == -3) {
7883 printf("?Name of remote file required\n");
7884 return(-9);
7885 }
7886 else
7887 return(x);
7888 }
7889 ckstrncpy(buf,s,TMPBUFSIZ);
7890 if ((x = cmfld("Name of remote destination file or directory",
7891 "",&s, xxstring)) < 0) {
7892 if (x == -3) {
7893 printf("?Name of remote file or directory required\n");
7894 return(-9);
7895 } else return(x);
7896 }
7897 ckstrncpy(tmpbuf,s,TMPBUFSIZ);
7898 if ((x = remcfm()) < 0)
7899 return(x);
7900 if (local) ttflui(); /* If local, flush tty input buffer */
7901 retcode = sstate = setgen('K',buf,tmpbuf,"");
7902 break;
7903 }
7904 case XZREN: { /* Rename */
7905 char buf[TMPBUFSIZ];
7906 buf[TMPBUFSIZ-1] = '\0';
7907 if ((x = cmfld("Name of remote file to rename",
7908 "",&s,xxstring)) < 0) {
7909 if (x == -3) {
7910 printf("?Name of remote file required\n");
7911 return(-9);
7912 } else return(x);
7913 }
7914 ckstrncpy(buf,s,TMPBUFSIZ);
7915 if ((x = cmfld("New name of remote file","",&s, xxstring)) < 0) {
7916 if (x == -3) {
7917 printf("?Name of remote file required\n");
7918 return(-9);
7919 } else return(x);
7920 }
7921 ckstrncpy(tmpbuf,s,TMPBUFSIZ);
7922 if ((x = remcfm()) < 0)
7923 return(x);
7924 if (local) ttflui(); /* If local, flush device buffer */
7925 retcode = sstate = setgen('R',buf,tmpbuf,"");
7926 break;
7927 }
7928 case XZMKD: /* mkdir */
7929 case XZRMD: /* rmdir */
7930 if ((x = cmtxt((xx == XZMKD) ?
7931 "Name of remote directory to create" :
7932 "Name of remote directory to delete",
7933 "",
7934 &s,
7935 xxstring
7936 )) < 0) {
7937 if (x == -3) {
7938 printf("?Name required\n");
7939 return(-9);
7940 } else return(x);
7941 }
7942 if ((x = remtxt(&s)) < 0)
7943 return(x);
7944 if (local) ttflui(); /* If local, flush tty input buffer */
7945 retcode = sstate = rfilop(s, (char)(xx == XZMKD ? 'm' : 'd'));
7946 break;
7947
7948 case XZXIT: /* Exit */
7949 if ((x = remcfm()) < 0) return(x);
7950 sstate = setgen('X',"","","");
7951 retcode = 0;
7952 break;
7953
7954 default:
7955 if ((x = remcfm()) < 0) return(x);
7956 printf("?Not implemented - %s\n",cmdbuf);
7957 return(-2);
7958 }
7959 if (local && retcode > -1) /* If local, flush tty input buffer */
7960 ttflui();
7961 return(retcode);
7962 }
7963
7964
7965 /* R F I L O P -- Remote File Operation */
7966
7967 CHAR
7968 #ifdef CK_ANSIC
rfilop(char * s,char t)7969 rfilop(char * s, char t)
7970 #else
7971 rfilop(s,t) char *s, t;
7972 #endif /* CK_ANSIC */
7973 /* rfilop */ {
7974 if (*s == NUL) {
7975 printf("?File specification required\n");
7976 return((CHAR) 0);
7977 }
7978 debug(F111,"rfilop",s,t);
7979 return(setgen(t,s,"",""));
7980 }
7981 #endif /* NOXFER */
7982
7983 #ifdef ANYX25
7984 int
setx25()7985 setx25() {
7986 if ((y = cmkey(x25tab,nx25,"X.25 call options","",xxstring)) < 0)
7987 return(y);
7988 switch (y) {
7989 case XYUDAT:
7990 if ((z = cmkey(onoff,2,"X.25 call user data","",xxstring))
7991 < 0) return(z);
7992 if (z == 0) {
7993 if ((z = cmcfm()) < 0) return(z);
7994 cudata = 0; /* disable call user data */
7995 return (success = 1);
7996 }
7997 if ((x = cmtxt("X.25 call user data string","",&s,xxstring)) < 0)
7998 return(x);
7999 if ((int)strlen(s) == 0) {
8000 return (-3);
8001 } else if ((int)strlen(s) > MAXCUDATA) {
8002 printf("?The length must be > 0 and <= %d\n",MAXCUDATA);
8003 return(-2);
8004 }
8005 if ((y = cmcfm()) < 0) return(y);
8006 ckstrncpy(udata,s,MAXCUDATA);
8007 cudata = 1; /* X.25 call user data specified */
8008 return (success = 1);
8009 case XYCLOS:
8010 if ((z = cmkey(onoff,2,"X.25 closed user group call","",xxstring))
8011 < 0) return(z);
8012 if (z == 0) {
8013 if ((z = cmcfm()) < 0) return(z);
8014 closgr = -1; /* disable closed user group */
8015 return (success = 1);
8016 }
8017 if ((y = cmnum("0 <= cug index >= 99","",10,&x,xxstring)) < 0)
8018 return(y);
8019 if (x < 0 || x > 99) {
8020 printf("?The choices are 0 <= cug index >= 99\n");
8021 return(-2);
8022 }
8023 if ((y = cmcfm()) < 0) return(y);
8024 closgr = x; /* closed user group selected */
8025 return (success = 1);
8026
8027 case XYREVC:
8028 if((z = cmkey(onoff,2,"X.25 reverse charge call","",xxstring)) < 0)
8029 return(z);
8030 if ((x = cmcfm()) < 0) return(x);
8031 revcall = z;
8032 return (success = 1);
8033 }
8034 }
8035
8036 #ifndef IBMX25
8037 int
setpadp()8038 setpadp() {
8039 if ((y = cmkey(padx3tab,npadx3,"PAD X.3 parameter name","",xxstring)) < 0)
8040 return(y);
8041 x = y;
8042 switch (x) {
8043 case PAD_BREAK_CHARACTER:
8044 if ((y = cmnum("PAD break character value","",10,&z,xxstring)) < 0)
8045 return(y);
8046 if ((y = cmcfm()) < 0) return(y);
8047 break;
8048 case PAD_ESCAPE:
8049 if ((y = cmnum("PAD escape","",10,&z,xxstring)) < 0) return(y);
8050 if (z != 0 && z != 1) {
8051 printf("?The choices are 0 or 1\n");
8052 return(-2);
8053 }
8054 if ((y = cmcfm()) < 0) return(y);
8055 break;
8056 case PAD_ECHO:
8057 if ((y = cmnum("PAD echo","",10,&z,xxstring)) < 0) return(y);
8058 if (z != 0 && z != 1) {
8059 printf("?The choices are 0 or 1\n");
8060 return(-2);
8061 }
8062 if ((y = cmcfm()) < 0) return(y);
8063 break;
8064 case PAD_DATA_FORWARD_CHAR:
8065 if ((y = cmnum("PAD data forward char","",10,&z,xxstring)) < 0)
8066 return(y);
8067 if (z != 0 && z != 2) {
8068 printf("?The choices are 0 or 2\n");
8069 return(-2);
8070 }
8071 if ((y = cmcfm()) < 0) return(y);
8072 break;
8073 case PAD_DATA_FORWARD_TIMEOUT:
8074 if ((y = cmnum("PAD data forward timeout","",10,&z,xxstring)) < 0)
8075 return(y);
8076 if (z < 0 || z > 255) {
8077 printf("?The choices are 0 or 1 <= timeout <= 255\n");
8078 return(-2);
8079 }
8080 if ((y = cmcfm()) < 0) return(y);
8081 break;
8082 case PAD_FLOW_CONTROL_BY_PAD:
8083 if ((y = cmnum("PAD pad flow control","",10,&z,xxstring)) < 0)
8084 return(y);
8085 if (z != 0 && z != 1) {
8086 printf("?The choices are 0 or 1\n");
8087 return(-2);
8088 }
8089 if ((y = cmcfm()) < 0) return(y);
8090 break;
8091 case PAD_SUPPRESSION_OF_SIGNALS:
8092 if ((y = cmnum("PAD service","",10,&z,xxstring)) < 0) return(y);
8093 if (z != 0 && z != 1) {
8094 printf("?The choices are 0 or 1\n");
8095 return(-2);
8096 }
8097 if ((y = cmcfm()) < 0) return(y);
8098 break;
8099
8100 case PAD_BREAK_ACTION:
8101 if ((y = cmnum("PAD break action","",10,&z,xxstring)) < 0) return(y);
8102 if (z != 0 && z != 1 && z != 2 && z != 5 && z != 8 && z != 21) {
8103 printf("?The choices are 0, 1, 2, 5, 8 or 21\n");
8104 return(-2);
8105 }
8106 if ((y = cmcfm()) < 0) return(y);
8107 break;
8108
8109 case PAD_SUPPRESSION_OF_DATA:
8110 if ((y = cmnum("PAD data delivery","",10,&z,xxstring)) < 0) return(y);
8111 if (z != 0 && z != 1) {
8112 printf("?The choices are 0 or 1\n");
8113 return(-2);
8114 }
8115 if ((y = cmcfm()) < 0) return(y);
8116 break;
8117
8118 case PAD_PADDING_AFTER_CR:
8119 if ((y = cmnum("PAD crpad","",10,&z,xxstring)) < 0) return(y);
8120 if (z < 0 || z > 7) {
8121 printf("?The choices are 0 or 1 <= crpad <= 7\n");
8122 return(-2);
8123 }
8124 if ((y = cmcfm()) < 0) return(y);
8125 break;
8126
8127 case PAD_LINE_FOLDING:
8128 if ((y = cmnum("PAD linefold","",10,&z,xxstring)) < 0) return(y);
8129 if (z < 0 || z > 255) {
8130 printf("?The choices are 0 or 1 <= linefold <= 255\n");
8131 return(-2);
8132 }
8133 if ((y = cmcfm()) < 0) return(y);
8134 break;
8135
8136 case PAD_LINE_SPEED:
8137 if ((y = cmnum("PAD baudrate","",10,&z,xxstring)) < 0) return(y);
8138 if (z < 0 || z > 18) {
8139 printf("?The choices are 0 <= baudrate <= 18\n");
8140 return(-2);
8141 }
8142 if ((y = cmcfm()) < 0) return(y);
8143 break;
8144
8145 case PAD_FLOW_CONTROL_BY_USER:
8146 if ((y = cmnum("PAD terminal flow control","",10,&z,xxstring)) < 0)
8147 return(y);
8148 if (z != 0 && z != 1) {
8149 printf("?The choices are 0 or 1\n");
8150 return(-2);
8151 }
8152 if ((y = cmcfm()) < 0) return(y);
8153 break;
8154
8155 case PAD_LF_AFTER_CR:
8156 if ((y = cmnum("PAD crpad","",10,&z,xxstring)) < 0) return(y);
8157 if (z < 0 || z == 3 || z > 7) {
8158 printf("?The choices are 0, 1, 2, 4, 5, 6 or 7\n");
8159 return(-2);
8160 }
8161 if ((y = cmcfm()) < 0) return(y);
8162 break;
8163
8164 case PAD_PADDING_AFTER_LF:
8165 if ((y = cmnum("PAD lfpad","",10,&z,xxstring)) < 0) return(y);
8166 if (z < 0 || z > 7) {
8167 printf("?The choices are 0 or 1 <= lfpad <= 7\n");
8168 return(-2);
8169 }
8170 if ((y = cmcfm()) < 0) return(y);
8171 break;
8172
8173 case PAD_EDITING:
8174 if ((y = cmnum("PAD edit control","",10,&z,xxstring)) < 0) return(y);
8175 if (z != 0 && z != 1) {
8176 printf("?The choices are 0 or 1\n");
8177 return(-2);
8178 }
8179 if ((y = cmcfm()) < 0) return(y);
8180 break;
8181
8182 case PAD_CHAR_DELETE_CHAR:
8183 if ((y = cmnum("PAD char delete char","",10,&z,xxstring)) < 0)
8184 return(y);
8185 if (z < 0 || z > 127) {
8186 printf("?The choices are 0 or 1 <= chardelete <= 127\n");
8187 return(-2);
8188 }
8189 if ((y = cmcfm()) < 0) return(y);
8190 break;
8191
8192 case PAD_BUFFER_DELETE_CHAR:
8193 if ((y = cmnum("PAD buffer delete char","",10,&z,xxstring)) < 0)
8194 return(y);
8195 if (z < 0 || z > 127) {
8196 printf("?The choices are 0 or 1 <= bufferdelete <= 127\n");
8197 return(-2);
8198 }
8199 if ((y = cmcfm()) < 0) return(y);
8200 break;
8201
8202 case PAD_BUFFER_DISPLAY_CHAR:
8203 if ((y = cmnum("PAD display line char","",10,&z,xxstring)) < 0)
8204 return(y);
8205 if (z < 0 || z > 127) {
8206 printf("?The choices are 0 or 1 <= displayline <= 127\n");
8207 return(-2);
8208 }
8209 if ((y = cmcfm()) < 0) return(y);
8210 break;
8211 }
8212 padparms[x] = z;
8213 return(success = 1);
8214 }
8215 #endif /* IBMX25 */
8216 #endif /* ANYX25 */
8217
8218 #ifndef NOXFER
8219 int
setat(rmsflg)8220 setat(rmsflg) int rmsflg; {
8221 int xx;
8222 if ((y = cmkey(attrtab,natr,"File Attribute packets","",xxstring)) < 0)
8223 return(y);
8224 if (y == AT_XALL) { /* ATTRIBUTES ALL ON or ALL OFF */
8225 if ((z = seton(&xx)) < 0) return(z);
8226 if (rmsflg) {
8227 printf("Sorry, command not available\n");
8228 return(-9);
8229 } else {
8230 atenci = xx; /* Encoding in */
8231 atenco = xx; /* Encoding out */
8232 atdati = xx; /* Date in */
8233 atdato = xx; /* Date out */
8234 atdisi = xx; /* Disposition in/out */
8235 atdiso = xx;
8236 atleni = xx; /* Length in/out (both kinds) */
8237 atleno = xx;
8238 atblki = xx; /* Blocksize in/out */
8239 atblko = xx;
8240 attypi = xx; /* File type in/out */
8241 attypo = xx;
8242 atsidi = xx; /* System ID in/out */
8243 atsido = xx;
8244 atsysi = xx; /* System-dependent params in/out */
8245 atsyso = xx;
8246 #ifdef CK_PERMS /* Protection */
8247 atlpri = xx; /* Local in */
8248 atlpro = xx; /* Local out */
8249 atgpri = xx; /* Generic in */
8250 atgpro = xx; /* Generic out */
8251 #endif /* CK_PERMS */
8252 #ifdef STRATUS
8253 atfrmi = xx; /* Format in/out */
8254 atfrmo = xx;
8255 atcrei = xx; /* Creator id in/out */
8256 atcreo = xx;
8257 atacti = xx; /* Account in/out */
8258 atacto = xx;
8259 #endif /* STRATUS */
8260 }
8261 return(z);
8262 } else if (y == AT_ALLY || y == AT_ALLN) { /* ATTRIBUTES ON or OFF */
8263 if ((x = cmcfm()) < 0) return(x);
8264 atcapr = (y == AT_ALLY) ? 1 : 0;
8265 if (rmsflg) {
8266 sstate = setgen('S', "132", atcapr ? "1" : "0", "");
8267 return((int) sstate);
8268 } else return(success = 1);
8269 }
8270 /* Otherwise, it's an individual attribute that wants turning off/on */
8271
8272 if ((z = cmkey(onoff,2,"","",xxstring)) < 0) return(z);
8273 if ((x = cmcfm()) < 0) return(x);
8274
8275 /* There are better ways to do this... */
8276 /* The real problem is that we're not separating the in and out cases */
8277 /* and so we have to arbitrarily pick the "in" case, i.e tell the remote */
8278 /* server to ignore incoming attributes of the specified type, rather */
8279 /* than telling it not to send them. The protocol does not (yet) define */
8280 /* codes for "in-and-out-at-the-same-time". */
8281
8282 switch (y) {
8283 #ifdef CK_PERMS
8284 /* We're lumping local and generic protection together for now... */
8285 case AT_LPRO:
8286 case AT_GPRO:
8287 if (rmsflg) {
8288 sstate = setgen('S', "143", z ? "1" : "0", "");
8289 return((int) sstate);
8290 }
8291 atlpri = atlpro = atgpri = atgpro = z; break;
8292 #endif /* CK_PERMS */
8293 case AT_DISP:
8294 if (rmsflg) {
8295 sstate = setgen('S', "142", z ? "1" : "0", "");
8296 return((int) sstate);
8297 }
8298 atdisi = atdiso = z; break;
8299 case AT_ENCO:
8300 if (rmsflg) {
8301 sstate = setgen('S', "141", z ? "1" : "0", "");
8302 return((int) sstate);
8303 }
8304 atenci = atenco = z; break;
8305 case AT_DATE:
8306 if (rmsflg) {
8307 sstate = setgen('S', "135", z ? "1" : "0", "");
8308 return((int) sstate);
8309 }
8310 atdati = atdato = z; break;
8311 case AT_LENB:
8312 case AT_LENK:
8313 if (rmsflg) {
8314 sstate = setgen('S', "133", z ? "1" : "0", "");
8315 return((int) sstate);
8316 }
8317 atleni = atleno = z; break;
8318 case AT_BLKS:
8319 if (rmsflg) {
8320 sstate = setgen('S', "139", z ? "1" : "0", "");
8321 return((int) sstate);
8322 }
8323 atblki = atblko = z; break;
8324 case AT_FTYP:
8325 if (rmsflg) {
8326 sstate = setgen('S', "134", z ? "1" : "0", "");
8327 return((int) sstate);
8328 }
8329 attypi = attypo = z; break;
8330 #ifdef STRATUS
8331 case AT_CREA:
8332 if (rmsflg) {
8333 sstate = setgen('S', "136", z ? "1" : "0", "");
8334 return((int) sstate);
8335 }
8336 atcrei = atcreo = z; break;
8337 case AT_ACCT:
8338 if (rmsflg) {
8339 sstate = setgen('S', "137", z ? "1" : "0", "");
8340 return((int) sstate);
8341 }
8342 atacti = atacto = z; break;
8343 #endif /* STRATUS */
8344 case AT_SYSI:
8345 if (rmsflg) {
8346 sstate = setgen('S', "145", z ? "1" : "0", "");
8347 return((int) sstate);
8348 }
8349 atsidi = atsido = z; break;
8350 case AT_RECF:
8351 if (rmsflg) {
8352 sstate = setgen('S', "146", z ? "1" : "0", "");
8353 return((int) sstate);
8354 }
8355 atfrmi = atfrmo = z; break;
8356 case AT_SYSP:
8357 if (rmsflg) {
8358 sstate = setgen('S', "147", z ? "1" : "0", "");
8359 return((int) sstate);
8360 }
8361 atsysi = atsyso = z; break;
8362 default:
8363 printf("?Not available\n");
8364 return(-2);
8365 }
8366 return(1);
8367 }
8368 #endif /* NOXFER */
8369
8370 #ifndef NOSPL
8371 int
setinp()8372 setinp() {
8373 if ((y = cmkey(inptab,ninp,"","",xxstring)) < 0) return(y);
8374 switch (y) {
8375 #ifdef OS2
8376 case IN_PAC: /* SET INPUT PACING */
8377 z = cmnum("milliseconds","0",10,&x,xxstring);
8378 return(setnum(&tt_inpacing,x,z,1000));
8379 case IN_TRM: /* SET INPUT TERMINAL */
8380 return(seton(&interm));
8381 #endif /* OS2 */
8382 case IN_DEF: /* SET INPUT DEFAULT-TIMEOUT */
8383 z = cmnum("Positive number","",10,&x,xxstring);
8384 return(setnum(&indef,x,z,94));
8385 #ifdef CKFLOAT
8386 case IN_SCA: /* SET INPUT SCALE-FACTOR */
8387 if ((x = cmfld("Number such as 2 or 0.5","1.0",&s, xxstring)) < 0)
8388 return(x);
8389 if (isfloat(s,0)) { /* A floating-point number? */
8390 extern char * inpscale;
8391 inscale = floatval; /* Yes, get its value */
8392 makestr(&inpscale,s); /* Save it as \v(inscale) */
8393 return(success = 1);
8394 } else {
8395 return(-2);
8396 }
8397 #endif /* CKFLOAT */
8398 case IN_TIM: /* SET INPUT TIMEOUT-ACTION */
8399 if ((z = cmkey(intimt,2,"","",xxstring)) < 0) return(z);
8400 if ((x = cmcfm()) < 0) return(x);
8401 intime[cmdlvl] = z;
8402 return(success = 1);
8403 case IN_CAS: /* SET INPUT CASE */
8404 if ((z = cmkey(incast,2,"","",xxstring)) < 0) return(z);
8405 if ((x = cmcfm()) < 0) return(x);
8406 inpcas[cmdlvl] = z;
8407 return(success = 1);
8408 case IN_ECH: /* SET INPUT ECHO */
8409 return(seton(&inecho));
8410 case IN_SIL: /* SET INPUT SILENCE */
8411 z = cmnum("Seconds of inactivity before INPUT fails","",10,&x,
8412 xxstring);
8413 return(setnum(&insilence,x,z,-1));
8414
8415 case IN_BUF: /* SET INPUT BUFFER-SIZE */
8416 if ((z = cmnum("Number of bytes in INPUT buffer",
8417 ckitoa(INPBUFSIZ),10,&x, xxstring)) < 0)
8418 return(z);
8419 if ((y = cmcfm()) < 0) return(y);
8420 inbufsize = 0;
8421 if (inpbuf) {
8422 free(inpbuf);
8423 inpbuf = NULL;
8424 inpbp = NULL;
8425 }
8426 if (!(s = (char *)malloc(x + 1)))
8427 return(0);
8428 inpbuf = s;
8429 inpbp = s;
8430 inbufsize = x;
8431 for (x = 0; x <= inbufsize; x++)
8432 inpbuf[x] = NUL;
8433 return(success = 1);
8434
8435 #ifdef CK_AUTODL
8436 case IN_ADL: /* AUTODOWNLOAD */
8437 return(seton(&inautodl));
8438 #endif /* CK_AUTODL */
8439
8440 case IN_CAN: /* SET INPUT INTERRUPTS */
8441 return(seton(&inintr));
8442 }
8443 return(0);
8444 }
8445 #endif /* NOSPL */
8446
8447 #ifdef NETCONN
8448 VOID
ndreset()8449 ndreset() {
8450 #ifndef NODIAL /* This depends on DIAL... */
8451 int i=0, j=0;
8452 if (!ndinited) /* Don't free garbage... */
8453 return;
8454 for (i = 0; i < nhcount; i++) { /* Clean out previous list */
8455 if (nh_p[i])
8456 free(nh_p[i]);
8457 nh_p[i] = NULL;
8458 if (nh_p2[i])
8459 free(nh_p2[i]);
8460 nh_p2[i] = NULL;
8461 for (j = 0; j < 4; j++) {
8462 if (nh_px[j][i])
8463 free(nh_px[j][i]);
8464 nh_px[j][i] = NULL;
8465 }
8466 }
8467 #endif /* NODIAL */
8468 }
8469
8470 VOID
ndinit()8471 ndinit() { /* Net directory pointers */
8472 #ifndef NODIAL /* This depends on DIAL... */
8473 int i, j;
8474 if (ndinited++) /* Don't do this more than once. */
8475 return;
8476 for (i = 0; i < MAXDDIR; i++) { /* Init all pointers to NULL */
8477 netdir[i] = NULL;
8478 }
8479 for (i = 0; i < MAXDNUMS; i++) {
8480 nh_p[i] = NULL;
8481 nh_p2[i] = NULL;
8482 for (j = 0; j < 4; j++)
8483 nh_px[j][i] = NULL;
8484 }
8485 #endif /* NODIAL */
8486 }
8487
8488 #ifndef NODIAL
8489 #ifdef NETCONN
8490 VOID /* Get net defaults from environment */
getnetenv()8491 getnetenv() {
8492 char *p = NULL;
8493
8494 makestr(&p,getenv("K_NET_DIRECTORY")); /* Dialing directories */
8495 if (p) {
8496 int i;
8497 xwords(p,MAXDDIR,netdir,0);
8498 for (i = 0; i < MAXDDIR; i++) { /* Fill in any gaps... */
8499 if (!netdir[i+1])
8500 break;
8501 else
8502 netdir[i] = netdir[i+1];
8503 debug(F111,"netdir[i]",netdir[i],i);
8504 }
8505 nnetdir = i;
8506 }
8507 }
8508 #endif /* NETCONN */
8509 #endif /* NODIAL */
8510
8511 int
8512 #ifdef CK_ANSIC
lunet(char * s)8513 lunet(char *s) /* s = name to look up */
8514 #else
8515 lunet(s) char *s;
8516 #endif /* CK_ANSIC */
8517 /* lunet */ {
8518 #ifndef NODIAL /* This depends on DIAL... */
8519 int n, n1, t, dd = 0;
8520 int ambiguous = 0;
8521 FILE * f;
8522 char *line = NULL;
8523 extern int dialdpy;
8524 int netdpy = dialdpy;
8525 char *info[8];
8526
8527 nhcount = 0; /* Set this before returning */
8528
8529 if (!s || nnetdir < 1) /* Validate arguments */
8530 return(-1);
8531
8532 if (isdigit(*s) || *s == '*' || *s == '.')
8533 return(0);
8534
8535 if ((n1 = (int) strlen(s)) < 1) /* Length of string to look up */
8536 return(-1);
8537
8538 if (!(line = malloc(1024))) /* Allocate input buffer */
8539 return(-1);
8540
8541 lu_again:
8542 f = NULL; /* Network directory file descriptor */
8543 t = nhcount = 0; /* Match count */
8544 dd = 0; /* Directory counter */
8545
8546 dirline = 0;
8547 while (1) { /* We make one pass */
8548 if (!f) { /* Directory not open */
8549 if (dd >= nnetdir) /* No directories left? */
8550 break; /* Done. */
8551 if ((f = fopen(netdir[dd],"r")) == NULL) { /* Open it */
8552 perror(netdir[dd]); /* Can't, print message saying why */
8553 dd++;
8554 continue; /* But go on to next one. */
8555 }
8556 if (netdpy)
8557 printf("Opening %s...\n",netdir[dd]);
8558 dd++;
8559 }
8560 line[0] = NUL;
8561 if (getnct(line,1023,f,1) < 0) { /* Read a line */
8562 if (f) { /* f can be clobbered! */
8563 fclose(f); /* Close the file */
8564 f = NULL; /* Indicate next one needs opening */
8565 }
8566 continue;
8567 }
8568 if (!line[0]) /* Empty line */
8569 continue;
8570
8571 xwords(line,7,info,0); /* Parse it */
8572
8573 if (!info[1] || !info[2] || !info[3]) /* Required fields */
8574 continue;
8575 if (*info[1] == ';') /* Full-line comment */
8576 continue;
8577 if ((n = (int) strlen(info[1])) < 1) /* Length of name-tag */
8578 continue;
8579 if (n < n1) /* Search name is longer */
8580 continue; /* Can't possibly match */
8581 if (ambiguous && n != n1)
8582 continue;
8583 if (ckstrcmp(s,info[1],n1,0)) /* Compare using length of */
8584 continue; /* search string s. */
8585
8586 /* Have a match */
8587
8588 makestr(&(nh_p[nhcount]), info[3]); /* address */
8589 makestr(&(nh_p2[nhcount]),info[2]); /* net type */
8590 makestr(&(nh_px[0][nhcount]),info[4]); /* net-specific stuff... */
8591 makestr(&(nh_px[1][nhcount]),info[5]);
8592 makestr(&(nh_px[2][nhcount]),info[6]);
8593 makestr(&(nh_px[3][nhcount]),info[7]);
8594
8595 nhcount++; /* Count this match */
8596 if (nhcount > MAXDNUMS) { /* Watch out for too many */
8597 printf("Warning: %d matches found, %d max\n",
8598 nhcount,
8599 MAXDNUMS
8600 );
8601 nhcount = MAXDNUMS;
8602 break;
8603 }
8604 if (nhcount == 1) { /* First one - save entry name */
8605 if (n_name) { /* Free the one from before if any */
8606 free(n_name);
8607 n_name = NULL;
8608 }
8609 if (!(n_name = (char *)malloc(n + 1))) { /* Allocate new storage */
8610 printf("?memory allocation error - lunet:3\n");
8611 if (line) {
8612 free(line);
8613 line = NULL;
8614 }
8615 nhcount = 0;
8616 return(-1);
8617 }
8618 t = n; /* Remember its length */
8619 strcpy(n_name,info[1]); /* safe */
8620 } else { /* Second or subsequent one */
8621 if ((int) strlen(info[1]) == t) /* Lengths compare */
8622 if (!ckstrcmp(n_name,info[1],t,0)) /* Caseless compare OK */
8623 continue;
8624
8625 /* Name given by user matches entries with different names */
8626
8627 if (ambiguous) /* Been here before */
8628 break;
8629
8630 ambiguous = 1; /* Now an exact match is required */
8631 ndreset(); /* Clear out previous list */
8632 goto lu_again; /* Do it all over again. */
8633 }
8634 }
8635 if (line) {
8636 free(line);
8637 line = NULL;
8638 }
8639 if (nhcount == 0 && ambiguous)
8640 printf("?\"%s\" - ambiguous in network directory\n",s);
8641 #else
8642 nhcount = 0;
8643 #endif /* NODIAL */
8644 return(nhcount);
8645 }
8646 #endif /* NETCONN */
8647
8648 #ifndef NOLOCAL
8649 /* C L S C O N N X -- Close connection */
8650
8651 int
clsconnx(ask)8652 clsconnx(ask) int ask; {
8653 int x, rc = 0;
8654 #ifdef NEWFTP
8655 extern int ftpget, ftpisopen();
8656 if ((ftpget == 1) || ((ftpget == 2) && !local && ftpisopen()))
8657 return(success = ftpbye());
8658 #endif /* NEWFTP */
8659 debug(F101,"clsconnx local","",local);
8660 if (local) {
8661 x = ask ? hupok(1) : 1; /* Make sure it's OK to close */
8662 if (!x) {
8663 rc = -1;
8664 debug(F101,"clsconnx hupok says no","",rc);
8665 return(rc);
8666 }
8667 ttflui(); /* Clear away buffered up junk */
8668 #ifndef NODIAL
8669 #ifdef OS2ONLY
8670 /* Don't hangup a line that is shared with the SLIP or PPP driver */
8671 if (!ttslip && !ttppp)
8672 #endif /* OS2ONLY */
8673 mdmhup();
8674 #endif /* NODIAL */
8675 if (network && msgflg)
8676 printf(" Closing connection\n");
8677 ttclos(0); /* Close old connection, if any */
8678 rc = 1;
8679 {
8680 extern int wasclosed, whyclosed;
8681 if (wasclosed) {
8682 whyclosed = WC_CLOS;
8683 #ifndef NOSPL
8684 if (nmac) { /* Any macros defined? */
8685 int k; /* Yes */
8686 /* printf("ON_CLOSE CLSCONNX\n"); */
8687 wasclosed = 0;
8688 k = mlook(mactab,"on_close",nmac); /* Look this up */
8689 if (k >= 0) { /* If found, */
8690 if (dodo(k,ckitoa(whyclosed),0) > -1) /* set it up, */
8691 parser(1); /* and execute it */
8692 }
8693 }
8694 #endif /* NOSPL */
8695 whyclosed = WC_REMO;
8696 wasclosed = 0;
8697 }
8698 }
8699 }
8700 #ifdef VMS /* Or maybe #ifndef UNIX? */
8701 else { /* Need to do this in VMS to */
8702 ttclos(0); /* free the tty channel number */
8703 rc = 1; /* obtained in ttopen() or else */
8704 } /* subsequent ttopen's won't work */
8705 #endif /* VMS */
8706 dologend();
8707 haveline = 0;
8708 if (mdmtyp < 0) { /* Switching from net to async? */
8709 if (mdmsav > -1) /* Restore modem type from last */
8710 mdmtyp = mdmsav; /* SET MODEM command, if any. */
8711 else
8712 mdmtyp = 0;
8713 mdmsav = -1;
8714 }
8715 if (network)
8716 network = 0;
8717 #ifdef NETCONN
8718 if (oldplex > -1) { /* Restore previous duplex setting. */
8719 duplex = oldplex;
8720 oldplex = -1;
8721 }
8722 #endif /* NETCONN */
8723 #ifndef MAC
8724 ckstrncpy(ttname,dftty,TTNAMLEN); /* Restore default communication */
8725 #endif /* MAC */
8726 local = dfloc; /* device and local/remote status */
8727 if (local) {
8728 cxtype = CXT_DIRECT; /* Something reasonable */
8729 speed = ttgspd(); /* Get the current speed */
8730 } else {
8731 cxtype = CXT_REMOTE;
8732 speed = -1L;
8733 }
8734 #ifndef NOXFER
8735 if (xreliable > -1 && !setreliable) {
8736 reliable = xreliable;
8737 debug(F101,"clsconnx reliable A","",reliable);
8738 } else if (!setreliable) {
8739 reliable = SET_AUTO;
8740 debug(F101,"clsconnx reliable B","",reliable);
8741 }
8742 #endif /* NOXFER */
8743 setflow(); /* Revert flow control */
8744 return(rc);
8745 }
8746
8747 int
clskconnx(x)8748 clskconnx(x) int x; { /* Close Kermit connection only */
8749 int t, rc; /* (not FTP) */
8750 #ifdef NEWFTP
8751 extern int ftpget;
8752 t = ftpget;
8753 ftpget = 0;
8754 #endif /* NEWFTP */
8755 rc = clsconnx(x);
8756 #ifdef NEWFTP
8757 ftpget = t;
8758 #endif /* NEWFTP */
8759 return(rc);
8760 }
8761
8762 /* May 2002: setlin() decomposition starts here ... */
8763
8764 #ifdef OS2
8765 #define SRVBUFSIZ PIPENAML
8766 #else /* OS2 */
8767 #define SRVBUFSIZ 63
8768 #endif /* OS2 */
8769 #define HOSTNAMLEN 15*65
8770
8771 int netsave = -1;
8772 static char * tmpstring = NULL;
8773 static char * tmpusrid = NULL;
8774
8775 #ifdef SSHCMD
8776 char * sshcmd = NULL;
8777 char * defsshcmd = "ssh -e none";
8778 #else
8779 #ifdef SSHBUILTIN
8780 char * sshrcmd = NULL;
8781 char * sshtmpcmd = NULL;
8782 #endif /* SSHBUILTIN */
8783 #endif /* SSHCMD */
8784
8785 /* c x _ f a i l -- Common error exit routine for cx_net, cx_line */
8786
8787 int
cx_fail(msg,text)8788 cx_fail(msg, text) int msg; char * text; {
8789 makestr(&slmsg,text); /* For the record (or GUI) */
8790 if (msg) /* Not GUI, not quiet, etc */
8791 printf("?%s\n",text); /* Print error message */
8792 slrestor(); /* Restore LINE/HOST to known state */
8793 return(msg ? -9 : (success = 0)); /* Return appropriate code */
8794 }
8795
8796 #ifdef NETCONN
8797 /* c x _ n e t -- Make a network connection */
8798
8799 /*
8800 Call with:
8801 net = network type
8802 protocol = protocol type
8803 host = string pointer to host name.
8804 svc = string pointer to service or port on host.
8805 username = username for connection
8806 password = password for connection
8807 command = command to execute
8808 param1 = Telnet: Authentication type
8809 SSH: Version
8810 param2 = Telnet: Encryption type
8811 SSH: Command as Subsystem
8812 param3 = Telnet: 1 to wait for negotiations, 0 otherwise
8813 SSH: X11 Forwarding
8814 cx = 1 to automatically enter Connect mode, 0 otherwise.
8815 sx = 1 to automatically enter Server mode, 0 otherwise.
8816 flag = if no host name given, 1 = close current connection, 0 = resume
8817 gui = 1 if called from GUI dialog, 0 otherwise.
8818 Returns:
8819 1 on success
8820 0 on failure and no message printed, slmsg set to failure message.
8821 -9 on failure and message printed, ditto.
8822 */
8823 int
8824 #ifdef CK_ANSIC
cx_net(int net,int protocol,char * xhost,char * svc,char * username,char * password,char * command,int param1,int param2,int param3,int cx,int sx,int flag,int gui)8825 cx_net( int net, int protocol, char * xhost, char * svc,
8826 char * username, char * password, char * command,
8827 int param1, int param2, int param3, int cx, int sx, int flag, int gui)
8828 #else /* CK_ANSIC */
8829 cx_net(net, protocol, xhost, svc,
8830 username, password, command,
8831 param1, param2, param3, cx, sx, flag, gui)
8832 char * xhost, * svc, * username, *password, *command;
8833 int net, protocol, cx, sx, flag, param1, param2, param3, gui;
8834 #endif /* CK_ANSIC */
8835 /* cx_net */ {
8836
8837 int i, n, x, msg;
8838 int _local = -1;
8839
8840 extern char pwbuf[], * g_pswd;
8841 extern int pwflg, pwcrypt, g_pflg, g_pcpt, nolocal;
8842
8843 char srvbuf[SRVBUFSIZ+1]; /* Service */
8844 char hostbuf[HOSTNAMLEN]; /* Host buffer to manipulate */
8845 char hostname[HOSTNAMLEN]; /* Copy of host parameter */
8846 char * host = hostbuf; /* Pointer to copy of host param */
8847
8848 if (!xhost) xhost = ""; /* Watch out for null pointers */
8849 if (!svc) svc = "";
8850 ckstrncpy(host,xhost,HOSTNAMLEN); /* Avoid buffer confusion */
8851
8852 debug(F110,"cx_net host",host,0);
8853 debug(F111,"cx_net service",svc,SRVBUFSIZ);
8854 debug(F101,"cx_net network type","",net);
8855
8856 msg = (gui == 0) && msgflg; /* Whether to print messages */
8857
8858 #ifndef NODIAL
8859 debug(F101,"cx_net nnetdir","",nnetdir);
8860 x = 0; /* Look up in network directory */
8861 if (*host == '=') { /* If number starts with = sign */
8862 host++; /* strip it */
8863 while (*host == SP) host++; /* and any leading spaces */
8864 debug(F110,"cx_net host 2",host,0);
8865 nhcount = 0;
8866 } else if (*host) { /* We want to look it up. */
8867 if (nnetdir > 0) /* If there is a directory... */
8868 x = lunet(host); /* (sets nhcount) */
8869 else /* otherwise */
8870 nhcount = 0; /* we didn't find any there */
8871 if (x < 0) /* Internal error? */
8872 return(cx_fail(msg,"Network directory lookup error"));
8873 debug(F111,"cx_net lunet nhcount",host,nhcount);
8874 }
8875 #endif /* NODIAL */
8876
8877 /* New connection wanted. Make a copy of the host name/address... */
8878
8879 if (clskconnx(1) < 0) /* Close current Kermit connection */
8880 return(cx_fail(msg,"Error closing previous connection"));
8881
8882 if (*host) { /* They gave a hostname */
8883 _local = 1; /* Network connection always local */
8884 if (mdmsav < 0)
8885 mdmsav = mdmtyp; /* Remember old modem type */
8886 mdmtyp = -net; /* Special code for network */
8887 } else { /* They just said "set host" */
8888 host = dftty; /* So go back to normal */
8889 _local = dfloc; /* default tty, location, */
8890 if (flag) { /* Close current connection */
8891 setflow(); /* Maybe change flow control */
8892 haveline = 1; /* (* is this right? *) */
8893 dologend();
8894 #ifndef NODIAL
8895 dialsta = DIA_UNK;
8896 #endif /* NODIAL */
8897 #ifdef LOCUS
8898 if (autolocus) {
8899 setlocus(1,1);
8900 }
8901 #endif /* LOCUS */
8902 /* XXX - Is this right? */
8903 /* Should we be returning without doing anything ? */
8904 /* Yes it's right -- we closed the old connection just above. */
8905 return(success = 1);
8906 }
8907 }
8908 success = 0;
8909 if (host != line) /* line[] is a global */
8910 ckstrncpy(line,host,LINBUFSIZ);
8911 ckstrncpy(hostname,host,HOSTNAMLEN);
8912 ckstrncpy(srvbuf,svc,SRVBUFSIZ+1);
8913
8914 #ifndef NODIAL
8915 if ((nhcount > 1) && msg) {
8916 int k;
8917 printf("%d entr%s found for \"%s\"%s\n",
8918 nhcount,
8919 (nhcount == 1) ? "y" : "ies",
8920 s,
8921 (nhcount > 0) ? ":" : "."
8922 );
8923 for (i = 0; i < nhcount; i++) {
8924 printf("%3d. %-12s => %-9s %s",
8925 i+1,n_name,nh_p2[i],nh_p[i]);
8926 for (k = 0; k < 4; k++) { /* Also list net-specific items */
8927 if (nh_px[k][i]) /* free format... */
8928 printf(" %s",nh_px[k][i]);
8929 else
8930 break;
8931 }
8932 printf("\n");
8933 }
8934 }
8935 if (nhcount == 0)
8936 n = 1;
8937 else
8938 n = nhcount;
8939 #else
8940 n = 1;
8941 nhcount = 0;
8942 #endif /* NODIAL */
8943
8944 for (i = 0; i < n; i++) { /* Loop for each entry found */
8945 debug(F101,"cx_net loop i","",i);
8946 #ifndef NODIAL
8947 if (nhcount > 0) { /* If we found at least one entry... */
8948 ckstrncpy(line,nh_p[i],LINBUFSIZ); /* Copy current entry */
8949 if (lookup(netcmd,nh_p2[i],nnets,&x) > -1) { /* Net type */
8950 int xx;
8951 xx = netcmd[x].kwval;
8952 /* User specified SSH so don't let net directory override */
8953 if (net != NET_SSH || xx != NET_TCPB) {
8954 net = xx;
8955 mdmtyp = 0 - net;
8956 }
8957 } else {
8958 makestr(&slmsg,"Network type not supported");
8959 if (msg)
8960 printf("Error - network type \"%s\" not supported\n",
8961 nh_p2[i]
8962 );
8963 continue;
8964 }
8965 switch (net) { /* Net-specific directory things */
8966 #ifdef SSHBUILTIN
8967 case NET_SSH: /* SSH */
8968 /* Any SSH specific network directory stuff? */
8969 break; /* NET_SSH */
8970 #endif /* SSHBUILTIN */
8971
8972 case NET_TCPB: { /* TCP/IP TELNET,RLOGIN,... */
8973 #ifdef TCPSOCKET
8974 char *q;
8975 int flag = 0;
8976
8977 /* Extract ":service", if any, from host string */
8978 debug(F110,"cx_net service 1",line,0);
8979 for (q = line; (*q != '\0') && (*q != ':'); q++)
8980 ;
8981 if (*q == ':') { *q++ = NUL; flag = 1; }
8982 debug(F111,"cx_net service 2",line,flag);
8983
8984 /* Get service, if any, from directory entry */
8985
8986 if (!*srvbuf) {
8987 if (nh_px[0][i]) {
8988 ckstrncpy(srvbuf,nh_px[0][i],SRVBUFSIZ);
8989 debug(F110,"cx_net service 3",srvbuf,0);
8990 }
8991 if (flag) {
8992 ckstrncpy(srvbuf,q,SRVBUFSIZ);
8993 debug(F110,"cx_net service 4",srvbuf,0);
8994 }
8995 }
8996 ckstrncpy(hostname,line,HOSTNAMLEN);
8997
8998 /* If we have a service, append to host name/address */
8999 if (*srvbuf) {
9000 ckstrncat(line, ":", LINBUFSIZ);
9001 ckstrncat(line, srvbuf, LINBUFSIZ);
9002 debug(F110,"cx_net service 5",line,0);
9003 }
9004 #ifdef RLOGCODE
9005 /* If no service given but command was RLOGIN */
9006 else if (ttnproto == NP_RLOGIN) { /* add this... */
9007 ckstrncat(line, ":login",LINBUFSIZ);
9008 debug(F110,"cx_net service 6",line,0);
9009 }
9010 #ifdef CK_AUTHENTICATION
9011 #ifdef CK_KERBEROS
9012 else if (ttnproto == NP_K4LOGIN ||
9013 ttnproto == NP_K5LOGIN) { /* add this... */
9014 ckstrncat(line, ":klogin",LINBUFSIZ);
9015 debug(F110,"cx_net service 7",line,0);
9016 }
9017 else if (ttnproto == NP_EK4LOGIN ||
9018 ttnproto == NP_EK5LOGIN) { /* add this... */
9019 ckstrncat(line, ":eklogin",LINBUFSIZ);
9020 debug(F110,"cx_net service 8",line,0);
9021 }
9022 #endif /* CK_KERBEROS */
9023 #endif /* CK_AUTHENTICATION */
9024 #endif /* RLOGCODE */
9025 else { /* Otherwise, add ":telnet". */
9026 ckstrncat(line, ":telnet", LINBUFSIZ);
9027 debug(F110,"cx_net service 9",line,0);
9028 }
9029 if (username) { /* This is a parameter... */
9030 ckstrncpy(uidbuf,username,UIDBUFLEN);
9031 uidflag = 1;
9032 }
9033 /* Fifth field, if any, is user ID (for rlogin) */
9034
9035 if (nh_px[1][i] && !uidflag)
9036 ckstrncpy(uidbuf,username,UIDBUFLEN);
9037 #ifdef RLOGCODE
9038 if (IS_RLOGIN() && !uidbuf[0])
9039 return(cx_fail(msg,"Username required"));
9040 #endif /* RLOGCODE */
9041 #endif /* TCPSOCKET */
9042 break;
9043 }
9044 case NET_PIPE: /* Pipe */
9045 #ifdef NPIPE
9046 if (!pipename[0]) { /* User didn't give a pipename */
9047 if (nh_px[0][i]) { /* But directory entry has one */
9048 if (strcmp(pipename,"\\pipe\\")) {
9049 ckstrncpy(pipename,"\\pipe\\",LINBUFSIZ);
9050 ckstrncat(srvbuf,nh_px[0][i],PIPENAML-6);
9051 } else {
9052 ckstrncpy(pipename,nh_px[0][i],PIPENAML);
9053 }
9054 debug(F110,"cx_net pipeneme",pipename,0);
9055 }
9056 }
9057 #endif /* NPIPE */
9058 break;
9059
9060 case NET_SLAT: /* LAT / CTERM */
9061 #ifdef SUPERLAT
9062 if (!slat_pwd[0]) { /* User didn't give a password */
9063 if (nh_px[0][i]) { /* But directory entry has one */
9064 ckstrncpy(slat_pwd,nh_px[0][i],18);
9065 debug(F110,"cx_net SuperLAT password",slat_pwd,0);
9066 }
9067 }
9068 #endif /* SUPERLAT */
9069 break;
9070
9071 case NET_SX25: /* X.25 keyword parameters */
9072 case NET_IX25:
9073 case NET_VX25: {
9074 #ifdef ANYX25
9075 int k; /* Cycle through the four fields */
9076 for (k = 0; k < 4; k++) {
9077 if (!nh_px[k][i]) /* Bail out if none left */
9078 break;
9079 if (!ckstrcmp(nh_px[k][i],"cug=",4,0)) {
9080 closgr = atoi(nh_px[k][i]+4);
9081 debug(F101,"X25 CUG","",closgr);
9082 } else if (!ckstrcmp(nh_px[k][i],"cud=",4,0)) {
9083 cudata = 1;
9084 ckstrncpy(udata,nh_px[k][i]+4,MAXCUDATA);
9085 debug(F110,"X25 CUD",cudata,0);
9086 } else if (!ckstrcmp(nh_px[k][i],"rev=",4,0)) {
9087 revcall = !ckstrcmp(nh_px[k][i]+4,"=on",3,0);
9088 debug(F101,"X25 REV","",revcall);
9089 #ifndef IBMX25
9090 } else if (!ckstrcmp(nh_px[k][i],"pad=",4,0)) {
9091 int x3par, x3val;
9092 char *s1, *s2;
9093 s1 = s2 = nh_px[k][i]+4; /* PAD parameters */
9094 while (*s2) { /* Pick them apart */
9095 if (*s2 == ':') {
9096 *s2 = NUL;
9097 x3par = atoi(s1);
9098 s1 = ++s2;
9099 continue;
9100 } else if (*s2 == ',') {
9101 *s2 = NUL;
9102 x3val = atoi(s1);
9103 s1 = ++s2;
9104 debug(F111,"X25 PAD",x3par,x3val);
9105 if (x3par > -1 &&
9106 x3par <= MAXPADPARMS)
9107 padparms[x3par] = x3val;
9108 continue;
9109 } else
9110 s2++;
9111 }
9112 #endif /* IBMX25 */
9113 }
9114 }
9115 #endif /* ANYX25 */
9116 break;
9117 }
9118 default: /* Nothing special for other nets */
9119 break;
9120 }
9121 } else
9122 #endif /* NODIAL */
9123 { /* No directory entries found. */
9124 ckstrncpy(line,hostname,LINBUFSIZ); /* Put this back... */
9125 /* If the user gave a TCP service */
9126 if (net == NET_TCPB || net == NET_SSH)
9127 if (*srvbuf) { /* Append it to host name/address */
9128 ckstrncat(line, ":", LINBUFSIZ);
9129 ckstrncat(line, srvbuf,LINBUFSIZ);
9130 }
9131 }
9132 /*
9133 Get here with host name/address and all net-specific
9134 parameters set, ready to open the connection.
9135 */
9136 mdmtyp = -net; /* This should have been done */
9137 /* already but just in case ... */
9138
9139 debug(F110,"cx_net net line[] before ttopen",line,0);
9140 debug(F101,"cx_net net mdmtyp before ttopen","",mdmtyp);
9141 debug(F101,"cx_net net ttnproto","",ttnproto);
9142
9143 #ifdef SSHBUILTIN
9144 if (net == NET_SSH) {
9145 makestr(&ssh_hst,hostname); /* Stash everything */
9146 if (username) {
9147 if (!sl_uid_saved) {
9148 ckstrncpy(sl_uidbuf,uidbuf,UIDBUFLEN);
9149 sl_uid_saved = 1;
9150 }
9151 ckstrncpy(uidbuf,username,UIDBUFLEN);
9152 }
9153 if (srvbuf[0]) {
9154 makestr(&ssh_prt,srvbuf);
9155 } else
9156 makestr(&ssh_prt,NULL);
9157
9158 if (command) {
9159 makestr(&ssh_cmd,brstrip(command));
9160 ssh_cas = param2;
9161 } else
9162 makestr(&ssh_cmd,NULL);
9163
9164 if (param1 > -1) {
9165 #ifndef SSHTEST
9166 if (!sl_ssh_ver_saved) {
9167 sl_ssh_ver = ssh_ver;
9168 sl_ssh_ver_saved = 1;
9169 }
9170 #endif /* SSHTEST */
9171 ssh_ver = param1;
9172 }
9173 if (param3 > -1) {
9174 #ifndef SSHTEST
9175 if (!sl_ssh_xfw_saved) {
9176 sl_ssh_xfw = ssh_xfw;
9177 sl_ssh_xfw_saved = 1;
9178 }
9179 #endif /* SSHTEST */
9180 ssh_xfw = param3;
9181 }
9182 } else /* NET_SSH */
9183 #endif /* SSHBUILTIN */
9184 #ifdef TCPSOCKET
9185 if (net == NET_TCPB) {
9186 switch (protocol) {
9187 #ifdef CK_SSL
9188 #ifdef COMMENT
9189 /*
9190 Jeff's version from 30 Dec 2006 - doesn't work - SSL/TLS_RAW still
9191 start Telnet negotions if a 0xff byte comes in.
9192 */
9193 case NP_SSL_RAW:
9194 ttnproto = NP_SSL_RAW;
9195 debug(F101,"NP_SSL_RAW ttnproto","",ttnproto);
9196 ssl_only_flag = 1;
9197 tls_only_flag = 0;
9198 break;
9199
9200 case NP_TLS_RAW:
9201 ttnproto = NP_TLS_RAW;
9202 debug(F101,"NP_TLS_RAW ttnproto","",ttnproto);
9203 ssl_only_flag = 0;
9204 tls_only_flag = 1;
9205 break;
9206
9207 case NP_SSL:
9208 ttnproto = NP_SSL;
9209 debug(F101,"NP_SSL ttnproto","",ttnproto);
9210 ssl_only_flag = 1;
9211 tls_only_flag = 0;
9212 break;
9213
9214 case NP_TLS:
9215 ttnproto = NP_TLS;
9216 debug(F101,"NP_TLS ttnproto","",ttnproto);
9217 ssl_only_flag = 0;
9218 tls_only_flag = 1;
9219 break;
9220
9221 case NP_SSL_TELNET:
9222 ttnproto = NP_TELNET;
9223 debug(F101,"NP_SSL_TELNET ttnproto","",ttnproto);
9224 ssl_only_flag = 1;
9225 tls_only_flag = 0;
9226 break;
9227
9228 case NP_TLS_TELNET:
9229 ttnproto = NP_TELNET;
9230 debug(F101,"NP_TLS_TELNET ttnproto","",ttnproto);
9231 ssl_only_flag = 0;
9232 tls_only_flag = 1;
9233 break;
9234 #else
9235 /* fdc version of 4 Dec 2006 works OK */
9236 case NP_SSL_RAW:
9237 case NP_SSL:
9238 ssl_raw_flag = (protocol == NP_SSL_RAW) ? 1 : 0;
9239 ttnproto = protocol;
9240 debug(F101,protocol==NP_SSL ?
9241 "NP_SSL ttnproto" :
9242 "NP_SSL_RAW ttnproto",
9243 "",ttnproto);
9244 ssl_only_flag = 1;
9245 tls_only_flag = 0;
9246 break;
9247
9248 case NP_TLS:
9249 case NP_TLS_RAW:
9250 tls_raw_flag = (protocol == NP_SSL_RAW) ? 1 : 0;
9251 ttnproto = protocol;
9252 debug(F101,protocol==NP_TLS ?
9253 "NP_TLS ttnproto" :
9254 "NP_TLS_RAW ttnproto",
9255 "",ttnproto);
9256 ssl_only_flag = 0;
9257 tls_only_flag = 1;
9258 break;
9259
9260 case NP_SSL_TELNET:
9261 ssl_raw_flag = 0;
9262 ttnproto = NP_TELNET;
9263 debug(F101,"NP_SSL_TELNET ttnproto","",ttnproto);
9264 ssl_only_flag = 1;
9265 tls_only_flag = 0;
9266 break;
9267
9268 case NP_TLS_TELNET:
9269 tls_raw_flag = 0;
9270 ttnproto = NP_TELNET;
9271 debug(F101,"NP_TLS_TELNET ttnproto","",ttnproto);
9272 ssl_only_flag = 0;
9273 tls_only_flag = 1;
9274 break;
9275 #endif /* COMMENT */
9276 #endif /* CK_SSL */
9277
9278 case NP_NONE:
9279 case NP_TCPRAW:
9280 case NP_RLOGIN:
9281 case NP_K4LOGIN:
9282 case NP_K5LOGIN:
9283 case NP_EK4LOGIN:
9284 case NP_EK5LOGIN:
9285 case NP_TELNET:
9286 case NP_KERMIT:
9287 default:
9288 ttnproto = protocol;
9289 #ifdef CK_SSL
9290 #ifdef COMMENT
9291 /* Jeff version from 30 Dec 2006 */
9292 ssl_only_flag = 0;
9293 tls_only_flag = 0;
9294 #else
9295 /* fdc version from 4 Dec 2006 */
9296 ssl_raw_flag = 0;
9297 tls_raw_flag = 0;
9298 ssl_only_flag = 0;
9299 tls_only_flag = 0;
9300 #endif /* COMMENT */
9301 #endif /* CK_SSL */
9302 break;
9303 }
9304 #ifdef CK_AUTHENTICATION
9305 if ((ttnproto == NP_TELNET || ttnproto == NP_KERMIT) &&
9306 param1 > -1) {
9307 if (!sl_auth_saved) {
9308 int x;
9309 for (x = 0; x < AUTHTYPLSTSZ; x++)
9310 sl_auth_type_user[x] = auth_type_user[x];
9311 sl_auth_saved = 1;
9312 }
9313 if (!sl_topt_a_s_saved) {
9314 sl_topt_a_su = TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION);
9315 sl_topt_a_s_saved = 1;
9316 }
9317 if (!sl_topt_a_c_saved) {
9318 sl_topt_a_cm = TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION);
9319 sl_topt_a_c_saved = 1;
9320 }
9321 switch (param1) {
9322 case AUTHTYPE_AUTO:
9323 auth_type_user[0] = AUTHTYPE_AUTO;
9324 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_RQ;
9325 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_RQ;
9326 break;
9327 case AUTHTYPE_NULL:
9328 auth_type_user[0] = AUTHTYPE_NULL;
9329 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_RF;
9330 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_RF;
9331 break;
9332 #ifdef CK_SRP
9333 case AUTHTYPE_SRP:
9334 auth_type_user[0] = AUTHTYPE_SRP;
9335 auth_type_user[1] = AUTHTYPE_NULL;
9336 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9337 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9338 break;
9339 #endif /* CK_SRP */
9340 #ifdef CK_SSL
9341 case AUTHTYPE_SSL:
9342 auth_type_user[0] = AUTHTYPE_SSL;
9343 auth_type_user[1] = AUTHTYPE_NULL;
9344 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9345 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9346 break;
9347 #endif /* CK_SSL */
9348 #ifdef NT
9349 case AUTHTYPE_NTLM:
9350 auth_type_user[0] = AUTHTYPE_NTLM;
9351 auth_type_user[1] = AUTHTYPE_NULL;
9352 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9353 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9354 break;
9355 #endif /* NT */
9356 #ifdef CK_KERBEROS
9357 case AUTHTYPE_KERBEROS_V4:
9358 auth_type_user[0] = AUTHTYPE_KERBEROS_V4;
9359 auth_type_user[1] = AUTHTYPE_NULL;
9360 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9361 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9362 break;
9363
9364 case AUTHTYPE_KERBEROS_V5:
9365 auth_type_user[0] = AUTHTYPE_KERBEROS_V5;
9366 auth_type_user[1] = AUTHTYPE_NULL;
9367 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9368 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9369 break;
9370 #endif /* CK_KERBEROS */
9371 }
9372 }
9373 /*
9374 If the user requires a particular type of Kerberos connection,
9375 make sure we have a valid TGT.
9376 */
9377 makestr(&slmsg,"Authentication failure");
9378 if ((ttnproto == NP_TELNET || ttnproto == NP_KERMIT) &&
9379 (line[0] == '*' &&
9380 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) == TN_NG_MU ||
9381 line[0] != '*' &&
9382 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) == TN_NG_MU)
9383 ) {
9384 #ifdef CK_KERBEROS
9385 if ( auth_type_user[0] == AUTHTYPE_KERBEROS_V4 ) {
9386 extern int krb4_autoget;
9387 if (!ck_krb4_is_installed())
9388 return(cx_fail(msg,
9389 "Required authentication method (Kerberos 4) is not installed"));
9390 #ifdef COMMENT
9391 /* This code results in false failures when using */
9392 /* kerberos to machines in realms other than the */
9393 /* default since we don't know the realm of the */
9394 /* other machine until perform the reverse DNS */
9395 /* lookup. */
9396 else if (line[0] != '*' && !ck_krb4_is_tgt_valid() &&
9397 (!krb4_autoget ||
9398 krb4_autoget && !ck_krb4_autoget_TGT(NULL))) {
9399 return(cx_fail(msg,
9400 "Kerberos 4: Ticket Getting Ticket not valid"));
9401 }
9402 #endif /* COMMENT */
9403 } else if (auth_type_user[0] == AUTHTYPE_KERBEROS_V5) {
9404 extern int krb5_autoget;
9405 if (!ck_krb5_is_installed()) {
9406 return(cx_fail(msg,
9407 "Required authentication method (Kerberos 5) is not installed"));
9408 }
9409 #ifdef COMMENT
9410 /* This code results in false failures when using */
9411 /* kerberos to machines in realms other than the */
9412 /* default since we don't know the realm of the */
9413 /* other machine until perform the reverse DNS */
9414 /* lookup. */
9415 else if (line[0] != '*' && !ck_krb5_is_tgt_valid() &&
9416 (!krb5_autoget ||
9417 krb5_autoget && !ck_krb5_autoget_TGT(NULL))) {
9418 return(cx_fail(msg,
9419 "Kerberos 5: Ticket Getting Ticket not valid."));
9420 }
9421 #endif /* COMMENT */
9422 }
9423 #endif /* CK_KERBEROS */
9424 #ifdef NT
9425 if (auth_type_user[0] == AUTHTYPE_NTLM) {
9426 if (!ck_ntlm_is_installed()) {
9427 return(cx_fail(msg,
9428 "Required authentication method (NTLM) is not installed"));
9429 } else if (line[0] != '*' && !ck_ntlm_is_valid(0)) {
9430 return(cx_fail(msg,"NTLM: Credentials are unavailable."));
9431 }
9432 }
9433 #endif /* NT */
9434 #ifdef CK_SSL
9435 if (auth_type_user[0] == AUTHTYPE_SSL) {
9436 if (!ck_ssleay_is_installed()) {
9437 return(cx_fail(msg,
9438 "Required authentication method (SSL) is not installed"));
9439 }
9440 }
9441 #endif /* CK_SSL */
9442 #ifdef CK_SRP
9443 if (auth_type_user[0] == AUTHTYPE_SRP) {
9444 if (!ck_srp_is_installed()) {
9445 return(cx_fail(msg,
9446 "Required authentication method (SRP) is not installed"));
9447 }
9448 }
9449 #endif /* CK_SRP */
9450 }
9451 #endif /* CK_AUTHENTICATION */
9452 #ifdef CK_ENCRYPTION
9453 if ((ttnproto == NP_TELNET || ttnproto == NP_KERMIT) &&
9454 param2 > -1) {
9455 if (!sl_cx_saved) {
9456 sl_cx_type = cx_type;
9457 sl_cx_saved = 1;
9458 }
9459 if (!sl_topt_e_s_saved) {
9460 sl_topt_e_su = TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION);
9461 sl_topt_e_sm = TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION);
9462 sl_topt_e_s_saved = 1;
9463 }
9464 if (!sl_topt_e_c_saved) {
9465 sl_topt_e_cu = TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION);
9466 sl_topt_e_cm = TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION);
9467 sl_topt_e_c_saved = 1;
9468 }
9469 cx_type = param2;
9470 if (cx_type == CX_AUTO) {
9471 TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
9472 TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
9473 TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
9474 TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
9475 } else if (cx_type == CX_NONE) {
9476 TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
9477 TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
9478 TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
9479 TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
9480 } else {
9481 TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
9482 TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
9483 TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
9484 TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
9485 }
9486 }
9487 if (ttnproto == NP_EK4LOGIN || ttnproto == NP_EK5LOGIN ||
9488 (ttnproto == NP_TELNET || ttnproto == NP_KERMIT) &&
9489 ((line[0] == '*' &&
9490 TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) == TN_NG_MU &&
9491 TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_MU) ||
9492 (line[0] != '*' &&
9493 TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) == TN_NG_MU &&
9494 TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_MU))
9495 ) {
9496 if (!ck_crypt_is_installed()) {
9497 return(cx_fail(msg,
9498 "Required Encryption methods are not installed"));
9499 }
9500 }
9501 #endif /* CK_ENCRYPTION */
9502 #ifdef RLOGCODE
9503 #ifdef CK_KERBEROS
9504 #ifdef KRB4
9505 if (ttnproto == NP_K4LOGIN || ttnproto == NP_EK4LOGIN) {
9506 extern int krb4_autoget;
9507 char tgt[256];
9508 char * realm;
9509
9510 /* We don't have the full hostname at yet so */
9511 /* we do a DNS lookup before calling ttopen() */
9512
9513 realm = ck_krb4_realmofhost(ckgetfqhostname(hostname));
9514 ckmakmsg(tgt,256,"krbtgt.",realm,"@",realm);
9515 if (!ck_krb4_is_installed()) {
9516 return(cx_fail(msg,
9517 "Required authentication method (Kerberos 4) is not installed"
9518 ));
9519 } else {
9520 if ((ck_krb4_tkt_isvalid(tgt) <= 0) &&
9521 (!krb4_autoget ||
9522 krb4_autoget && !ck_krb4_autoget_TGT(realm))) {
9523 return(cx_fail(msg,
9524 "Kerberos 4: Ticket Getting Ticket not valid"));
9525 }
9526 }
9527 }
9528 #endif /* KRB4 */
9529 #ifdef KRB5
9530 if (ttnproto == NP_K5LOGIN || ttnproto == NP_EK5LOGIN ||
9531 ttnproto == NP_K5U2U)
9532 {
9533 extern int krb5_autoget;
9534 char tgt[256];
9535 char * realm;
9536
9537 /* Must get full hostname before calling ttopen() */
9538
9539 realm = ck_krb5_realmofhost(ckgetfqhostname(hostname));
9540 ckmakmsg(tgt,256,"krbtgt/",realm,"@",realm);
9541
9542 if (!ck_krb5_is_installed()) {
9543 return(cx_fail(msg,
9544 "Required authentication method (Kerberos 5) not installed"));
9545 } else if (!((ck_krb5_tkt_isvalid(NULL,tgt) > 0) ||
9546 ck_krb5_is_tgt_valid()) &&
9547 (!krb5_autoget ||
9548 krb5_autoget && !ck_krb5_autoget_TGT(realm))) {
9549 return(cx_fail(msg,
9550 "Kerberos 5: Ticket Getting Ticket not valid."));
9551 }
9552 }
9553 #endif /* KRB5 */
9554 #endif /* CK_KERBEROS */
9555 #endif /* RLOGCODE */
9556
9557 #ifndef NOSPL
9558 #ifdef RLOGCODE
9559 if (username) {
9560 if (!sl_uid_saved) {
9561 ckstrncpy(sl_uidbuf,uidbuf,UIDBUFLEN);
9562 sl_uid_saved = 1;
9563 }
9564 ckstrncpy(uidbuf,username,UIDBUFLEN);
9565 uidflag = 1;
9566 }
9567 #endif /* RLOGCODE */
9568 #ifdef TNCODE
9569 if (!sl_tn_saved) {
9570 sl_tn_wait = tn_wait_flg;
9571 sl_tn_saved = 1;
9572 }
9573 tn_wait_flg = param3;
9574 #endif /* TNCODE */
9575 #endif /* NOSPL */
9576 } /* if (net == NET_TCPB) */
9577 #endif /* TCPSOCKET */
9578
9579 #ifndef NOSPL
9580 #ifdef CK_SECURITY
9581 if (password) {
9582 if (password[0]) {
9583 ckstrncpy(pwbuf,password,PWBUFL+1);
9584 pwflg = 1;
9585 pwcrypt = 0;
9586 } else
9587 pwflg = 0;
9588 }
9589 #endif /* CK_SECURITY */
9590 #endif /* NOSPL */
9591
9592 /* Try to open - network */
9593 ckstrncpy(ttname,line,TTNAMLEN);
9594 y = ttopen(line, &_local, mdmtyp, 0 );
9595
9596 #ifndef NOHTTP
9597 /* If the connection failed and we are using an HTTP Proxy
9598 * and the reason for the failure was an authentication
9599 * error, then we need to give the user to ability to
9600 * enter a username and password, just like a browser.
9601 *
9602 * I tried to do all of this within the netopen() call
9603 * but it is much too much work.
9604 */
9605 while (y < 0 && tcp_http_proxy != NULL ) {
9606
9607 if (tcp_http_proxy_errno == 401 ||
9608 tcp_http_proxy_errno == 407 ) {
9609 char uid[UIDBUFLEN];
9610 char pwd[256];
9611 struct txtbox tb[2];
9612 int ok;
9613
9614 tb[0].t_buf = uid;
9615 tb[0].t_len = UIDBUFLEN;
9616 tb[0].t_lbl = "Proxy Userid: ";
9617 tb[0].t_dflt = NULL;
9618 tb[0].t_echo = 1;
9619 tb[1].t_buf = pwd;
9620 tb[1].t_len = 256;
9621 tb[1].t_lbl = "Proxy Passphrase: ";
9622 tb[1].t_dflt = NULL;
9623 tb[1].t_echo = 2;
9624
9625 ok = uq_mtxt("Proxy Server Authentication Required\n",
9626 NULL, 2, tb);
9627
9628 if (ok && uid[0]) {
9629 char * proxy_user, * proxy_pwd;
9630
9631 proxy_user = tcp_http_proxy_user;
9632 proxy_pwd = tcp_http_proxy_pwd;
9633
9634 tcp_http_proxy_user = uid;
9635 tcp_http_proxy_pwd = pwd;
9636
9637 ckstrncpy(ttname,line,TTNAMLEN);
9638 y = ttopen(line, &_local, mdmtyp, 0);
9639 memset(pwd,0,sizeof(pwd));
9640 tcp_http_proxy_user = proxy_user;
9641 tcp_http_proxy_pwd = proxy_pwd;
9642 } else
9643 break;
9644 } else
9645 break;
9646 }
9647 #endif /* NOHTTP */
9648 if (y < 0) {
9649 slrestor();
9650 makestr(&slmsg,"Network connection failure");
9651 #ifdef VMS
9652 if (msg && hints && !xcmdsrc && IS_RLOGIN()) {
9653 makestr(&slmsg,"RLOGIN failure");
9654 if (socket_errno == EACCES) {
9655 printf("*************************\n");
9656 printf(
9657 "Hint: RLOGIN requires privileges to open an outbound port.\n");
9658 printf(
9659 "(Use SET HINTS OFF to suppress future hints.)\n");
9660 printf("*************************\n");
9661 }
9662 }
9663 #else /* Not VMS... */
9664 if (errno) {
9665 int x;
9666 debug(F111,"set host line, errno","",errno);
9667 makestr(&slmsg,ck_errstr());
9668 if (msg) {
9669 #ifdef OS2
9670 printf("Can't connect to %s\n",line);
9671 #else /* OS2 */
9672 #ifdef UNIX
9673 if (hints && !xcmdsrc && IS_RLOGIN()) {
9674 makestr(&slmsg,"RLOGIN failure");
9675 printf("*************************\n");
9676 printf(
9677 "Hint: RLOGIN requires privileges to open an outbound port.\n");
9678 printf(
9679 "(Use SET HINTS OFF to suppress future hints.)\n");
9680 printf("*************************\n");
9681 }
9682 #endif /* UNIX */
9683 #endif /* OS2 */
9684 } else printf("Can't connect to %s\n",line);
9685 } else
9686 #endif /* VMS */
9687 if (msg) printf("Can't open connection to %s\n",line);
9688 continue;
9689 } else {
9690 success = 1;
9691 #ifndef NODIAL
9692 dialsta = DIA_UNK;
9693 #endif /* NODIAL */
9694 switch (net) {
9695 case NET_TCPA:
9696 case NET_TCPB:
9697 cxtype = CXT_TCPIP;
9698 #ifdef COMMENT
9699 /* This works but it messes up interactive anonymous login */
9700 #ifndef NOXFER
9701 #ifdef IKS_OPTION
9702 /* If we have connected to an Internet Kermit service */
9703 /* and a /USER: switch was given, then log in. */
9704
9705 if (TELOPT_U(TELOPT_KERMIT) || TELOPT_ME(TELOPT_KERMIT)) {
9706 debug(F111,"cx_net IKSD /USER:",uidbuf,haveuser);
9707 if (haveuser /* && cx == 0 */ ) { /* /USER: given */
9708 char * psw = pwbuf; /* Do we have a password? */
9709 if (!*psw) { /* No... */
9710 if (!strcmp(uidbuf,"anonymous") ||
9711 !strcmp(uidbuf,"ftp")) {
9712 extern char myhost[];
9713 char * u = (char *)sl_uidbuf;
9714 char * h = (char *)myhost;
9715 if (!*u) u = "nobody";
9716 if (!*h) h = "nowhere";
9717 ckmakmsg(tmpbuf,TMPBUFSIZ,u,"@",h,NULL);
9718 psw = tmpbuf;
9719 debug(F110,"cx_net IKSD anon",psw,0);
9720 } else {
9721 readpass(" Password: ",pwbuf,PWBUFL);
9722 }
9723 }
9724 sstate = setgen('I',uidbuf,psw,"");
9725 }
9726 }
9727 #endif /* IKS_OPTION */
9728 #endif /* NOXFER */
9729 #endif /* COMMENT */
9730 break;
9731 case NET_SSH:
9732 cxtype = CXT_SSH;
9733 duplex = 0; /* Remote echo */
9734 break;
9735 case NET_SLAT:
9736 cxtype = CXT_LAT;
9737 break;
9738 case NET_SX25:
9739 case NET_IX25:
9740 case NET_HX25:
9741 case NET_VX25:
9742 cxtype = CXT_X25;
9743 break;
9744 case NET_BIOS:
9745 cxtype = CXT_NETBIOS;
9746 break;
9747 case NET_FILE:
9748 case NET_PIPE:
9749 case NET_CMD:
9750 case NET_DLL:
9751 case NET_PTY:
9752 cxtype = CXT_PIPE;
9753 break;
9754 default:
9755 cxtype = CXT_PIPE;
9756 break;
9757 }
9758 break;
9759 }
9760 } /* for-loop */
9761 s = line;
9762
9763 debug(F101,"cx_net post ttopen success","",success);
9764 if (!success) {
9765 local = dfloc; /* Go back to normal */
9766 #ifndef MAC
9767 ckstrncpy(ttname,dftty,TTNAMLEN); /* Restore default tty name */
9768 #endif /* MAC */
9769 speed = ttgspd();
9770 network = 0; /* No network connection active */
9771 haveline = 0;
9772 if (mdmtyp < 0) { /* Switching from net to async? */
9773 if (mdmsav > -1) /* Restore modem type from last */
9774 mdmtyp = mdmsav; /* SET MODEM command, if any. */
9775 else
9776 mdmtyp = 0;
9777 mdmsav = -1;
9778 }
9779 return(0); /* Return failure */
9780 }
9781 if (_local > -1) local = _local; /* Opened ok, set local/remote. */
9782 makestr(&slmsg,NULL);
9783 network = (mdmtyp < 0); /* Remember connection type. */
9784 ckstrncpy(ttname,s,TTNAMLEN); /* Copy name into real place. */
9785 debug(F110,"cx_net ok",ttname,0);
9786 debug(F101,"cx_net network","",network);
9787 #ifndef NOXFER
9788 if ((reliable != SET_OFF || !setreliable)) /* Assume not reliable. */
9789 reliable = SET_OFF;
9790 #endif /* NOXFER */
9791 if (!network || istncomport())
9792 speed = ttgspd(); /* Get the current speed. */
9793 debug(F101,"cx_net local","",local);
9794 if (network) {
9795 debug(F101,"cx_net net","",net);
9796 #ifndef NOXFER
9797 /* Force prefixing of 255 on TCP/IP connections... */
9798 if (net == NET_TCPB
9799 #ifdef SSHBUILTIN
9800 || net == NET_SSH
9801 #endif /* SSHBUILTIN */
9802 ) {
9803 debug(F101,"cx_net reliable A","",reliable);
9804 #ifdef CK_SPEED
9805 ctlp[(unsigned)255] = 1;
9806 #endif /* CK_SPEED */
9807 if ((reliable != SET_OFF || !setreliable)) {
9808 #ifdef TN_COMPORT
9809 if (istncomport()) { /* Telnet communication port */
9810 reliable = SET_OFF; /* Transport is not reliable */
9811 debug(F101,"cx_net reliable istncomport()","",1);
9812 } else {
9813 reliable = SET_ON; /* Transport is reliable end to end */
9814 debug(F101,"cx_net reliable istncomport()","",0);
9815 }
9816 #else
9817 reliable = SET_ON; /* Transport is reliable end to end */
9818 #endif /* ifdef TN_COMPORT */
9819 }
9820 debug(F101,"cx_net reliable B","",reliable);
9821 } else if (net == NET_SX25 ||
9822 net == NET_VX25 ||
9823 net == NET_IX25 ||
9824 net == NET_HX25) {
9825 duplex = 1; /* Local echo for X.25 */
9826 if (reliable != SET_OFF || !setreliable)
9827 reliable = SET_ON; /* Transport is reliable end to end */
9828 }
9829 #endif /* NOXFER */
9830 }
9831 #ifndef NOXFER
9832 debug(F101,"cx_net reliable","",reliable);
9833 #endif /* NOXFER */
9834 #ifdef OS2
9835 if (mdmtyp <= 0) /* Network or Direct Connection */
9836 DialerSend(OPT_KERMIT_CONNECT, 0);
9837 #endif /* OS2 */
9838
9839 xcx_net:
9840
9841 setflow(); /* Set appropriate flow control */
9842
9843 haveline = 1;
9844 #ifdef CKLOGDIAL
9845 dolognet();
9846 #endif /* CKLOGDIAL */
9847
9848 #ifndef NOSPL
9849 if (local) {
9850 if (nmac) { /* Any macros defined? */
9851 int k; /* Yes */
9852 k = mlook(mactab,"on_open",nmac); /* Look this up */
9853 if (k >= 0) { /* If found, */
9854 if (dodo(k,ttname,0) > -1) /* set it up, */
9855 parser(1); /* and execute it */
9856 }
9857 }
9858 }
9859 #endif /* NOSPL */
9860
9861 if (local && (cx || sx)) { /* /CONNECT or /SERVER switch given */
9862 if (cx) { /* /CONNECT */
9863 if (!gui) {
9864 /* Command was confirmed so we can pre-pop command level. */
9865 /* This is so CONNECT module won't think we're executing a */
9866 /* script if CONNECT was the final command in the script. */
9867 if (cmdlvl > 0)
9868 prepop();
9869 }
9870 #ifndef NODIAL
9871 dialsta = DIA_UNK;
9872 #endif /* NODIAL */
9873 #ifdef LOCUS
9874 if (autolocus) {
9875 setlocus(1,1);
9876 }
9877 #endif /* LOCUS */
9878 success = doconect(0, cmdlvl == 0 ? 1 : 0);
9879 if (ttchk() < 0)
9880 dologend();
9881 debug(F101,"cx_net post doconect success","",success);
9882 return(success);
9883 #ifndef NOXFER
9884 } else if (sx) { /* /SERVER */
9885 sstate = 'x';
9886 #ifdef MAC
9887 what = W_RECV;
9888 scrcreate();
9889 #endif /* MAC */
9890 if (local) displa = 1;
9891 #ifdef AMIGA
9892 reqoff(); /* No DOS requestors while server */
9893 #endif /* AMIGA */
9894 #endif /* NOXFER */
9895 }
9896 }
9897 #ifndef NODIAL
9898 dialsta = DIA_UNK;
9899 #endif /* NODIAL */
9900 #ifdef LOCUS
9901 if (autolocus) {
9902 setlocus(1,1);
9903 }
9904 #endif /* LOCUS */
9905 return(success = 1);
9906 }
9907 #endif /* NETCONN */
9908
9909 /* c x _ s e r i a l -- Make a serial connection */
9910
9911 /*
9912 Call with:
9913 device = string pointer to device name.
9914 cx = 1 to automatically enter Connect mode, 0 otherwise.
9915 sx = 1 to automatically enter Server mode, 0 otherwise.
9916 shr = 1 if device should be opened in shareable mode, 0 otherwise.
9917 flag = if no dev name given: 1 = close current connection, 0 = resume.
9918 gui = 1 if called from GUI dialog, 0 otherwise.
9919 Returns:
9920 1 on success
9921 0 on failure and no message printed, slmsg set to failure message.
9922 -9 on failure and message printed, ditto.
9923 */
9924
9925 /* these are bit flags */
9926 #define CX_TAPI 1
9927 #define CX_PPP 2
9928 #define CX_SLIP 4
9929
9930 int
9931 #ifdef CK_ANSIC
cx_serial(char * device,int cx,int sx,int shr,int flag,int gui,int special)9932 cx_serial(char *device,
9933 int cx, int sx, int shr, int flag, int gui, int special)
9934 #else /* CK_ANSIC */
9935 cx_serial(device, cx, sx, shr, flag, gui, special)
9936 char * device; int cx, sx, shr, flag, gui, special;
9937 #endif /* CK_ANSIC */
9938 /* cx_serial */ {
9939 int i, n, x, y, msg;
9940 int _local = -1;
9941 char *s;
9942
9943 debug(F110,"cx_serial device",device,0);
9944 s = device;
9945 msg = (gui == 0) && msgflg; /* Whether to print messages */
9946 success = 0;
9947
9948 #ifndef NODIAL
9949 dialsta = DIA_UNK;
9950 #endif /* NODIAL */
9951 debug(F101,"cx_serial mdmtyp","",mdmtyp);
9952 if (clskconnx(1) < 0) /* Close the Kermit connection */
9953 return(success = 0);
9954 if (*s) { /* They gave a device name */
9955 _local = -1; /* Let ttopen decide about it */
9956 } else { /* They just said "set line" */
9957 s = dftty; /* so go back to normal tty */
9958 _local = dfloc; /* and mode. */
9959 }
9960 #ifdef VMS
9961 {
9962 extern int ok_to_share;
9963 ok_to_share = shr;
9964 }
9965 #endif /* VMS */
9966
9967 #ifdef OS2 /* Must wait until after ttclos() */
9968 #ifdef NT /* to change these settings */
9969 #ifdef CK_TAPI
9970 tttapi = special & CX_TAPI;
9971 #endif /* CK_TAPI */
9972 #else
9973 ttslip = special & CX_SLIP;
9974 ttppp = special & CX_PPP;
9975 #endif /* NT */
9976 ttshare = shr; /* Shareable device ? */
9977 debug(F110,"OS2 SET PORT final s",s,"");
9978 #endif /* OS2 */
9979
9980 /* Open the new line */
9981
9982 ckstrncpy(ttname,s,TTNAMLEN);
9983 if ((y = ttopen(s,&_local,mdmtyp,cdtimo)) > -1) {
9984 cxtype = (mdmtyp > 0) ? CXT_MODEM : CXT_DIRECT;
9985 #ifndef NODIAL
9986 dialsta = DIA_UNK;
9987 #ifdef CK_TAPI
9988 /* if the line is a tapi device, then we need to auto-execute */
9989 /* SET MODEM TYPE TAPI - which we do the equivalent of here. */
9990 if (tttapi) {
9991 extern int usermdm;
9992 usermdm = 0;
9993 initmdm(38); /* From ckudia.c n_TAPI == 38 */
9994 }
9995 #endif /* CK_TAPI */
9996 #endif /* NODIAL */
9997 success = 1;
9998 } else { /* Failed */
9999 #ifdef OS2ONLY
10000 if (!strcmp(s,dftty)) /* Do not generate an error with dftty */
10001 ;
10002 else if (y == -6 && ttslip) {
10003 makestr(&slmsg,"Can't access SLIP driver");
10004 if (msg) printf("?%s\n",slmsg);
10005 } else if (y == -6 && ttppp) {
10006 makestr(&slmsg,"Can't access PPP driver");
10007 if (msg) printf("?%s\n",slmsg);
10008 } else
10009 #endif /* OS2ONLY */
10010 if (y == -2) {
10011 makestr(&slmsg,"Timed out - no carrier");
10012 if (msg) {
10013 printf("?%s\n",slmsg);
10014 if (hints) {
10015 printf("\n*************************\n");
10016 printf(
10017 "HINT (Use SET HINTS OFF to suppress future hints):\n");
10018 printf(
10019 "Try SET CARRIER OFF and SET LINE again, or else\n");
10020 printf("SET MODEM, SET LINE, and then DIAL.\n");
10021 printf("*************************\n\n");
10022 }
10023 }
10024 } else if (y == -3) {
10025 makestr(&slmsg,"Access to lock denied");
10026 if (msg) {
10027 #ifdef UNIX
10028 printf(
10029 "Sorry, write access to UUCP lockfile directory denied.\n");
10030 #ifndef NOHINTS
10031 if (hints) {
10032 printf("\n*************************\n");
10033 printf(
10034 "HINT (Use SET HINTS OFF to suppress future hints):\n");
10035 printf(
10036 "Please read the installation instructions file, %sckuins.txt,\n",
10037 k_info_dir ? k_info_dir : ""
10038 );
10039 printf(
10040 "or the UNIX appendix of the manual, \"Using C-Kermit\"\n"
10041 );
10042 printf(
10043 "or visit http://www.kermitproject.org/ckuins.html \n"
10044 );
10045 printf("*************************\n\n");
10046 }
10047 #endif /* NOHINTS */
10048 #else
10049 printf("Sorry, access to lock denied: %s\n",s);
10050 #endif /* UNIX */
10051 }
10052 } else if (y == -4) {
10053 makestr(&slmsg,"Access to device denied");
10054 if (msg) {
10055 printf("Sorry, access to device denied: %s\n",s);
10056 #ifdef UNIX
10057 #ifndef NOHINTS
10058 if (hints) {
10059 printf("\n*************************\n");
10060 printf(
10061 "HINT (Use SET HINTS OFF to suppress future hints):\n");
10062 printf(
10063 "Please read the installation instructions file, %sckuins.txt,\n",
10064 k_info_dir ? k_info_dir : ""
10065 );
10066 printf(
10067 "or the UNIX appendix of the manual, \"Using C-Kermit\".\n"
10068 );
10069 printf("*************************\n\n");
10070 }
10071 #endif /* NOHINTS */
10072 #endif /* UNIX */
10073 }
10074 } else if (y == -5) {
10075 makestr(&slmsg,"Device is in use or unavailable");
10076 if (msg)
10077 #ifdef VMS
10078 printf(
10079 "Sorry, device is in use or otherwise unavailable: %s\n",s);
10080 #else
10081 printf("Sorry, device is in use: %s\n",s);
10082 #endif /* VMS */
10083 } else { /* Other error. */
10084 makestr(&slmsg,"Device open failed");
10085 if (
10086 #ifdef VMS
10087 1
10088 #else
10089 errno
10090 #endif /* VMS */
10091 ) {
10092 int x; /* Find a safe, long buffer */
10093 makestr(&slmsg,ck_errstr());
10094 #ifndef VMS
10095 debug(F111,"cx_serial serial errno",slmsg,errno);
10096 #endif /* VMS */
10097 if (msg)
10098 printf("Connection to %s failed: %s\n",s,slmsg);
10099 } else if (msg)
10100 printf("Sorry, can't open connection: %s\n",s);
10101 }
10102 }
10103 network = 0; /* No network connection active */
10104 speed = ttgspd();
10105 if (!success) {
10106 local = dfloc; /* Go back to normal */
10107 #ifndef MAC
10108 ckstrncpy(ttname,dftty,TTNAMLEN); /* Restore default tty name */
10109 #endif /* MAC */
10110 haveline = 0;
10111 if (mdmtyp < 0) { /* Switching from net to async? */
10112 if (mdmsav > -1) /* Restore modem type from last */
10113 mdmtyp = mdmsav; /* SET MODEM command, if any. */
10114 else
10115 mdmtyp = 0;
10116 mdmsav = -1;
10117 }
10118 return(msg ? -9 : 0); /* Return failure */
10119 }
10120 if (_local > -1)
10121 local = _local; /* Opened ok, set local/remote. */
10122 makestr(&slmsg,NULL); /* Erase SET LINE message */
10123 ckstrncpy(ttname,s,TTNAMLEN); /* Copy name into real place. */
10124 debug(F110,"cx_serial ok",ttname,0);
10125 #ifndef NOXFER
10126 if ((reliable != SET_OFF || !setreliable)) /* Assume not reliable. */
10127 reliable = SET_OFF;
10128 #endif /* NOXFER */
10129
10130 xcx_serial:
10131 setflow(); /* Set appropriate flow control */
10132 haveline = 1;
10133 #ifdef CKLOGDIAL
10134 dologline();
10135 #endif /* CKLOGDIAL */
10136
10137 #ifndef NOSPL
10138 if (local) {
10139 if (nmac) { /* Any macros defined? */
10140 int k; /* Yes */
10141 k = mlook(mactab,"on_open",nmac); /* Look this up */
10142 if (k >= 0) { /* If found, */
10143 if (dodo(k,ttname,0) > -1) /* set it up, */
10144 parser(1); /* and execute it */
10145 }
10146 }
10147 }
10148 #endif /* NOSPL */
10149
10150 if (local && (cx || sx)) { /* /CONNECT or /SERVER switch given */
10151 extern int carrier;
10152 if (carrier != CAR_OFF) { /* Looking for carrier? */
10153 /* Open() turns on DTR -- wait up to a second for CD to come up */
10154 int i, x;
10155 for (i = 0; i < 10; i++) { /* WAIT 1 CD... */
10156 x = ttgmdm();
10157 if (x < 0 || x & BM_DCD)
10158 break;
10159 msleep(100);
10160 }
10161 }
10162 if (cx) { /* /CONNECT */
10163 /* Command was confirmed so we can pre-pop command level. */
10164 /* This is so CONNECT module won't think we're executing a */
10165 /* script if CONNECT was the final command in the script. */
10166
10167 if (cmdlvl > 0)
10168 prepop();
10169 #ifndef NODIAL
10170 dialsta = DIA_UNK;
10171 #endif /* NODIAL */
10172 #ifdef LOCUS
10173 if (autolocus) {
10174 setlocus(1,1);
10175 }
10176 #endif /* LOCUS */
10177 success = doconect(0, cmdlvl == 0 ? 1 : 0);
10178 if (ttchk() < 0)
10179 dologend();
10180 return(success);
10181 #ifndef NOXFER
10182 } else if (sx) { /* /SERVER */
10183 sstate = 'x';
10184 #ifdef MAC
10185 what = W_RECV;
10186 scrcreate();
10187 #endif /* MAC */
10188 if (local) displa = 1;
10189 #ifdef AMIGA
10190 reqoff(); /* No DOS requestors while server */
10191 #endif /* AMIGA */
10192 #endif /* NOXFER */
10193 }
10194 }
10195 #ifndef NODIAL
10196 dialsta = DIA_UNK;
10197 #endif /* NODIAL */
10198 #ifdef LOCUS
10199 if (autolocus) {
10200 setlocus(1,1);
10201 }
10202 #endif /* LOCUS */
10203 return(success = 1);
10204 }
10205
10206
10207 /* S E T L I N -- parse name of and then open communication device. */
10208 /*
10209 Call with:
10210 xx == XYLINE for a serial (tty) line, XYHOST for a network host,
10211 zz == 0 means if user doesn't give a device name, continue current
10212 active connection (if any);
10213 zz != 0 means if user doesn't give a device name, then close the
10214 current connection and restore the default communication device.
10215 fc == 0 to just make the connection, 1 to also CONNECT (e.g. "telnet").
10216 */
10217 int
setlin(xx,zz,fc)10218 setlin(xx, zz, fc)
10219 int xx, zz, fc;
10220 {
10221 extern char pwbuf[], * g_pswd;
10222 extern int pwflg, pwcrypt, g_pflg, g_pcpt, nolocal;
10223 int wait;
10224 /* int tn_wait_sv; */
10225 int mynet;
10226 int _local = -1;
10227 int c, i, haveswitch = 0;
10228 int haveuser = 0;
10229 int getval = 0;
10230 int wild = 0; /* Filespec has wildcards */
10231 int cx = 0; /* Connect after */
10232 int sx = 0; /* Become server after */
10233 int a_type = -1; /* Authentication type */
10234 int e_type = -1; /* Telnet /ENCRYPT type */
10235 #ifdef CK_ENCRYPTION
10236 int encrypt = 0; /* Encrypted? */
10237 #endif /* CK_ENCRYPTION */
10238 int shr = 0; /* Share serial device */
10239 int confirmed = 0; /* Command has been entered */
10240 struct FDB sw, tx, nx;
10241 #ifdef OS2
10242 struct FDB fl;
10243 #endif /* OS2 */
10244
10245 char * ss;
10246 #ifdef TCPSOCKET
10247 int rawflg = 0;
10248 #endif /* TCPSOCKET */
10249
10250 char srvbuf[SRVBUFSIZ+1];
10251
10252 #ifdef OS2
10253 #ifdef NT
10254 int xxtapi = 0;
10255 #else
10256 int xxslip = 0, xxppp = 0;
10257 #endif /* NT */
10258 #endif /* OS2 */
10259
10260 int dossh = 0;
10261
10262 debug(F101,"setlin fc","",fc);
10263 debug(F101,"setlin zz","",zz);
10264 debug(F101,"setlin xx","",xx);
10265
10266 #ifdef SSHCMD
10267 if (xx == XXSSH) { /* SSH becomes PTY SSH ... */
10268 dossh = 1;
10269 xx = XYHOST;
10270 } else if (!ckstrcmp("ssh ",line,4,0)) { /* 2010/03/01 */
10271 dossh = 1;
10272 xx = XYHOST;
10273 }
10274 debug(F101,"setlin dossh","",dossh);
10275 #endif /* SSHCMD */
10276
10277 #ifdef TNCODE
10278 /* tn_wait_sv = tn_wait_flg; */
10279 wait = tn_wait_flg;
10280 #else
10281 /* tn_wait_sv = 0; */
10282 wait = 0;
10283 #endif /* TNCODE */
10284
10285 mynet = nettype;
10286
10287 if (nolocal) {
10288 makestr(&slmsg,"Making connections is disabled");
10289 printf("?Sorry, making connections is disabled\n");
10290 return(-9);
10291 }
10292 if (netsave > -1)
10293 nettype = netsave;
10294
10295 if (fc != 0 || zz == 0) /* Preset /CONNECT switch */
10296 cx = 1;
10297
10298 debug(F101,"setlin cx","",cx);
10299
10300 *srvbuf = NUL;
10301
10302 line[0] = NUL;
10303 s = line;
10304
10305 #ifdef NETCONN
10306 #ifdef CK_SECURITY
10307 if (tmpstring)
10308 makestr(&tmpstring,NULL);
10309 #endif /* CK_SECURITY */
10310 if (tmpusrid)
10311 makestr(&tmpusrid,NULL);
10312 #endif /* NETCONN */
10313
10314 autoflow = 1; /* Enable automatic flow setting */
10315
10316 if (xx == XYHOST) { /* SET HOST <hostname> */
10317 #ifndef NETCONN
10318 makestr(&slmsg,"Network connections not supported");
10319 printf("?%s\n",slmsg);
10320 return(-9);
10321 #else /* NETCONN */
10322 #ifndef NOPUSH
10323 if ((mynet == NET_CMD || mynet == NET_PTY || dossh) && nopush) {
10324 makestr(&slmsg,"Access to external commands is disabled");
10325 printf("?Sorry, access to external commands is disabled\n");
10326 return(-9);
10327 }
10328 #endif /* NOPUSH */
10329
10330 #ifdef SSHCMD
10331 if (dossh) { /* SSH connection via pty */
10332 int k;
10333 extern int ttyfd; /* 2010/03/01 */
10334 k = ckstrncpy(line, sshcmd ? sshcmd : defsshcmd, LINBUFSIZ);
10335 debug(F111,"setlin sshcmd 1",line,k);
10336 if ((x = cmtxt("Optional switches and hostname","",&s,xxstring))<0)
10337 return(x);
10338
10339 /* 2010-03-30 */
10340 if (!*s && ttyfd < 0 && !ckstrcmp("ssh ",ttname,4,0)) {
10341 x = ckstrncpy(line,ttname,LINBUFSIZ);
10342 } else {
10343 if (!*s) {
10344 printf("?SSH to where?\n");
10345 return(-9);
10346 }
10347 if (k < LINBUFSIZ) {
10348 line[k++] = SP;
10349 line[k] = NUL;
10350 debug(F111,"setlin sshcmd 2",line,k);
10351 } if (k < LINBUFSIZ) {
10352 ckstrncpy(&line[k],s,LINBUFSIZ-k);
10353 debug(F111,"setlin sshcmd 3",line,k);
10354 } else {
10355 printf("?Too long\n");
10356 return(-9);
10357 }
10358 }
10359 x = cx_net( NET_PTY, /* network type */
10360 0, /* protocol (not used) */
10361 line, /* host */
10362 NULL, /* service (not used) */
10363 NULL, /* username (not used) */
10364 NULL, /* password (not used) */
10365 NULL, /* command (not used) */
10366 -1,-1,-1, /* params 1-3 (not used) */
10367 1, /* connect immediately */
10368 sx, /* server? */
10369 zz, /* close current? */
10370 0); /* not gui */
10371 debug(F111,"setlin cx_net",line,x);
10372 return(x);
10373 }
10374 #endif /* SSHCMD */
10375
10376 /*
10377 Here we parse optional switches and then the hostname or whatever,
10378 which depends on the network type. The tricky part is, the network type
10379 can be set by a switch.
10380 */
10381 #ifndef NOSPL
10382 makestr(&g_pswd,pwbuf); /* Save global pwbuf */
10383 g_pflg = pwflg; /* and flag */
10384 g_pcpt = pwcrypt;
10385 #endif /* NOSPL */
10386
10387 confirmed = 0;
10388 haveswitch = 0;
10389 #ifdef NETFILE
10390 if (mynet != NET_FILE) {
10391 #endif /* NETFILE */
10392 ss = (mynet == NET_CMD || mynet == NET_PTY) ?
10393 "Command, or switch" :
10394 (mynet == NET_TCPA || mynet == NET_TCPB
10395 || mynet == NET_SSH) ?
10396 "Hostname, ip-address, or switch" :
10397 "Host or switch";
10398 if (fc) {
10399 if (mynet == NET_TCPB &&
10400 (ttnproto == NP_TELNET || ttnproto == NP_KERMIT)) {
10401 if (nshteltab) {
10402 haveswitch++;
10403 cmfdbi(&sw,_CMKEY,ss,"","",nshteltab,4,xxstring,
10404 shteltab,&nx);
10405 }
10406 }
10407 #ifdef RLOGCODE
10408 else if (mynet == NET_TCPB && ttnproto == NP_RLOGIN) {
10409 if (nshrlgtab) {
10410 haveswitch++;
10411 cmfdbi(&sw,_CMKEY,ss,"","",nshrlgtab,4,xxstring,
10412 shrlgtab,&nx);
10413 }
10414 }
10415 #endif /* RLOGCODE */
10416 } else {
10417 haveswitch++;
10418 cmfdbi(&sw,_CMKEY,ss,"","",nshtab,4,xxstring,shtab,&nx);
10419 }
10420 #ifdef NETFILE
10421 }
10422 #endif /* NETFILE */
10423 if (mynet == NET_TCPB || mynet == NET_SLAT ||
10424 mynet == NET_SSH || mynet == NET_DEC) {
10425 cmfdbi(&nx,_CMFLD,"Host","","",0,0,xxstring,NULL,NULL);
10426 #ifdef NETFILE
10427 } else if (mynet == NET_FILE) {
10428 cmfdbi(&nx,_CMIFI,"Filename","","",0,0,xxstring,NULL,NULL);
10429 #endif /* NETFILE */
10430 #ifdef PTYORPIPE
10431 } else if (mynet == NET_CMD || mynet == NET_PTY) {
10432 cmfdbi(&nx,_CMTXT,"Command","","",0,0,xxstring,NULL,NULL);
10433 #endif /* PTYORPIPE */
10434 } else {
10435 cmfdbi(&nx,_CMTXT,"Host","","",0,0,xxstring,NULL,NULL);
10436 }
10437 while (1) {
10438 x = cmfdb(haveswitch ? &sw : &nx);
10439 debug(F101,"setlin cmfdb","",x);
10440 if (x < 0)
10441 if (x != -3)
10442 return(x);
10443 if (x == -3) {
10444 if ((x = cmcfm()) < 0) {
10445 return(x);
10446 } else {
10447 confirmed = 1;
10448 break;
10449 }
10450 }
10451 if (cmresult.fcode != _CMKEY) { /* Not a switch */
10452 ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Save the data */
10453 s = line; /* that was parsed... */
10454 if (cmresult.fcode == _CMIFI) {
10455 wild = cmresult.nresult;
10456 } else if (cmresult.fcode == _CMTXT) {
10457 confirmed = 1;
10458 }
10459 break; /* and break out of this loop */
10460 }
10461 c = cmgbrk(); /* Have switch - get break character */
10462 getval = (c == ':' || c == '='); /* Must parse an agument? */
10463 if (getval && !(cmresult.kflags & CM_ARG)) {
10464 printf("?This switch does not take arguments\n");
10465 return(-9);
10466 }
10467 if (!getval && (cmgkwflgs() & CM_ARG)) {
10468 printf("?This switch requires an argument\n");
10469 return(-9);
10470 }
10471 switch (cmresult.nresult) { /* It's a switch.. */
10472 case SL_CNX: /* /CONNECT */
10473 cx = 1;
10474 sx = 0;
10475 break;
10476 case SL_SRV: /* /SERVER */
10477 cx = 0;
10478 sx = 1;
10479 break;
10480 #ifdef NETCMD
10481 case SL_CMD: /* /COMMAND */
10482 netsave = mynet;
10483 mynet = NET_CMD;
10484 break;
10485 #endif /* NETCMD */
10486 #ifdef NETPTY
10487 case SL_PTY: /* /PTY */
10488 netsave = mynet;
10489 mynet = NET_PTY;
10490 break;
10491 #endif /* NETPTY */
10492 case SL_NET: /* /NETWORK-TYPE */
10493 if ((x = cmkey(netcmd,nnets,"","",xxstring)) < 0)
10494 return(x);
10495 mynet = x;
10496 break;
10497
10498 #ifdef CK_SECURITY
10499 case SL_PSW: /* /PASSWORD: */
10500 if (!getval)
10501 break;
10502 debok = 0;
10503 if ((x = cmfld("Password","",&s,xxstring)) < 0) {
10504 if (x == -3) {
10505 makestr(&tmpstring,"");
10506 } else {
10507 return(x);
10508 }
10509 } else {
10510 s = brstrip(s);
10511 if ((x = (int)strlen(s)) > PWBUFL) {
10512 makestr(&slmsg,"Internal error");
10513 printf("?Sorry, too long - max = %d\n",PWBUFL);
10514 return(-9);
10515 }
10516 makestr(&tmpstring,s);
10517 }
10518 break;
10519 #endif /* CK_SECURITY */
10520
10521 case SL_UID: /* /USERID: */
10522 if (!getval)
10523 break;
10524 if ((x = cmfld("Userid","",&s,xxstring)) < 0) {
10525 if (x == -3) {
10526 makestr(&tmpusrid,"");
10527 } else {
10528 return(x);
10529 }
10530 } else {
10531 s = brstrip(s);
10532 if ((x = (int)strlen(s)) > 63) {
10533 makestr(&slmsg,"Internal error");
10534 printf("?Sorry, too long - max = %d\n",63);
10535 return(-9);
10536 }
10537 makestr(&tmpusrid,s);
10538 haveuser = 1;
10539 }
10540 break;
10541
10542 #ifdef CK_AUTHENTICATION
10543 #ifdef CK_SRP
10544 case SL_SRP:
10545 a_type = AUTHTYPE_SRP;
10546 break;
10547 #endif /* CK_SRP */
10548 #ifdef CK_SSL
10549 case SL_SSL:
10550 a_type = AUTHTYPE_SSL;
10551 break;
10552 #endif /* CK_SSL */
10553 #ifdef NT
10554 case SL_NTLM:
10555 a_type = AUTHTYPE_NTLM;
10556 break;
10557 #endif /* NT */
10558 #ifdef CK_KERBEROS
10559 case SL_KRB4:
10560 a_type = AUTHTYPE_KERBEROS_V4;
10561 if (ttnproto == NP_RLOGIN)
10562 ttnproto =
10563 #ifdef CK_ENCRYPTION
10564 encrypt ? NP_EK4LOGIN :
10565 #endif /* CK_ENCRYPTION */
10566 NP_K4LOGIN;
10567 else if (ttnproto == NP_K5LOGIN)
10568 ttnproto = NP_K4LOGIN;
10569 #ifdef CK_ENCRYPTION
10570 else if (ttnproto == NP_EK5LOGIN)
10571 ttnproto = NP_EK4LOGIN;
10572 #endif /* CK_ENCRYPTION */
10573 break;
10574 case SL_KRB5:
10575 a_type = AUTHTYPE_KERBEROS_V5;
10576 if (ttnproto == NP_RLOGIN)
10577 ttnproto =
10578 #ifdef CK_ENCRYPTION
10579 encrypt ? NP_EK5LOGIN :
10580 #endif /* CK_ENCRYPTION */
10581 NP_K5LOGIN;
10582 else if (ttnproto == NP_K4LOGIN)
10583 ttnproto = NP_K5LOGIN;
10584 #ifdef CK_ENCRYPTION
10585 else if (ttnproto == NP_EK4LOGIN)
10586 ttnproto = NP_EK5LOGIN;
10587 #endif /* CK_ENCRYPTION */
10588 break;
10589 #endif /* CK_KERBEROS */
10590 case SL_AUTH: {
10591 extern struct keytab autyptab[];
10592 extern int nautyp;
10593 if ((x = cmkey(autyptab,nautyp,"type of authentication",
10594 "automatic",xxstring)) < 0)
10595 return(x);
10596 a_type = x;
10597 break;
10598 }
10599 #endif /* CK_AUTHENTICATION */
10600 #ifdef CK_ENCRYPTION
10601 case SL_ENC:
10602 switch (ttnproto) {
10603 case NP_K4LOGIN:
10604 ttnproto = NP_EK4LOGIN;
10605 encrypt = 1;
10606 break;
10607 case NP_K5LOGIN:
10608 ttnproto = NP_EK5LOGIN;
10609 encrypt = 1;
10610 break;
10611 case NP_KERMIT:
10612 case NP_TELNET: {
10613 static struct keytab * tnetbl = NULL;
10614 static int ntnetbl = 0;
10615 x = ck_get_crypt_table(&tnetbl,&ntnetbl);
10616 debug(F101,"ck_get_crypt_table x","",x);
10617 debug(F101,"ck_get_crypt_table n","",ntnetbl);
10618 if (x < 1 || !tnetbl || ntnetbl < 1) /* Didn't get it */
10619 x = 0;
10620 if (!x) {
10621 makestr(&slmsg,"Internal error");
10622 printf("?Oops, types not loaded\n");
10623 return(-9);
10624 }
10625 if ((x = cmkey(tnetbl,ntnetbl,"type of encryption",
10626 "automatic",xxstring)) < 0)
10627 return(x);
10628 e_type = x;
10629 break;
10630 }
10631 }
10632 break;
10633 #endif /* CK_ENCRYPTION */
10634 case SL_WAIT:
10635 wait = 1;
10636 break;
10637 case SL_NOWAIT:
10638 wait = 0;
10639 break;
10640 }
10641 }
10642
10643 #ifdef NETFILE
10644 if (mynet == NET_FILE) { /* Parsed by cmifi() */
10645 if ((x = cmcfm()) < 0) /* Needs confirmation */
10646 return(x);
10647 x = cx_net(mynet, /* nettype */
10648 0, /* protocol (not used) */
10649 line, /* host */
10650 "", /* port */
10651 NULL, /* alternate username */
10652 NULL, /* password */
10653 NULL, /* command to execute */
10654 0, /* param1 */
10655 0, /* param2 */
10656 0, /* param3 */
10657 cx, /* enter CONNECT mode */
10658 sx, /* enter SERVER mode */
10659 zz, /* close connection if open */
10660 0 /* gui */
10661 );
10662 }
10663 #endif /* NETFILE */
10664
10665 #ifdef NETCMD
10666 if (mynet == NET_CMD || mynet == NET_PTY) {
10667 char *p = NULL;
10668 if (!confirmed) {
10669 if ((x = cmtxt("Rest of command","",&s,xxstring)) < 0)
10670 return(x);
10671 if (*s) {
10672 ckstrncat(line," ",LINBUFSIZ);
10673 ckstrncat(line,s,LINBUFSIZ);
10674 }
10675 s = line;
10676 }
10677 /* s == line - so we must protect the line buffer */
10678 s = brstrip(s);
10679 makestr(&p,s);
10680 ckstrncpy(line,p,LINBUFSIZ);
10681 makestr(&p,NULL);
10682
10683 x = cx_net( mynet, /* nettype */
10684 0, /* protocol (not used) */
10685 line, /* host */
10686 "", /* port */
10687 NULL, /* alternate username */
10688 NULL, /* password */
10689 NULL, /* command to execute */
10690 0, /* param1 */
10691 0, /* param2 */
10692 0, /* param3 */
10693 cx, /* enter CONNECT mode */
10694 sx, /* enter SERVER mode */
10695 zz, /* close connection if open */
10696 0 /* gui */
10697 );
10698 }
10699 #endif /* NETCMD */
10700
10701 #ifdef NPIPE /* Named pipe */
10702 if (mynet == NET_PIPE) { /* Needs backslash twiddling */
10703 if (line[0]) {
10704 if (strcmp(line,"*")) { /* If remote, begin with */
10705 char * p = NULL;
10706 makestr(&p,line);
10707 ckstrncpy(line,"\\\\",LINBUFSIZ); /* server name */
10708 ckstrncat(line,p,LINBUFSIZ);
10709 makestr(&p,NULL);
10710 } else {
10711 line[0]='\0';
10712 }
10713 ckstrncat(line,"\\pipe\\", LINBUFSIZ); /* Make pipe name */
10714 ckstrncat(line,pipename, LINBUFSIZ); /* Add name of pipe */
10715
10716 x = cx_net(mynet, /* nettype */
10717 0, /* protocol (not used) */
10718 line, /* host */
10719 "", /* port */
10720 NULL, /* alternate username */
10721 NULL, /* password */
10722 NULL, /* command to execute */
10723 0, /* param1 */
10724 0, /* param2 */
10725 0, /* param3 */
10726 cx, /* enter CONNECT mode */
10727 sx, /* enter SERVER mode */
10728 zz, /* close connection if open */
10729 0 /* gui */
10730 );
10731 }
10732 }
10733 #endif /* NPIPE */
10734
10735 #ifdef SUPERLAT
10736 if (mynet == NET_SLAT) { /* Needs password, etc. */
10737 slat_pwd[0] = NUL; /* Erase any previous password */
10738 debok = 0;
10739 if (*line) { /* If they gave a host name... */
10740 if ((x = cmfld(
10741 "password,\n or carriage return if no password required",
10742 "",
10743 &s,
10744 xxstring
10745 )) < 0 && x != -3)
10746 return(x);
10747 ckstrncpy(slat_pwd,s,18); /* Set the password, if any */
10748 }
10749 if ((x = cmcfm()) < 0) return(x); /* Confirm the command */
10750
10751 x = cx_net(mynet, /* nettype */
10752 0, /* protocol (not used) */
10753 line, /* host */
10754 "", /* port */
10755 NULL, /* alternate username */
10756 NULL, /* password */
10757 NULL, /* command to execute */
10758 0, /* param1 */
10759 0, /* param2 */
10760 0, /* param3 */
10761 cx, /* enter CONNECT mode */
10762 sx, /* enter SERVER mode */
10763 zz, /* close connection if open */
10764 0 /* gui */
10765 );
10766 }
10767 #endif /* SUPERLAT */
10768
10769 #ifdef DECNET
10770 if (mynet == NET_DEC) {
10771 if (!line[0]) { /* If they gave a host name... */
10772 printf("?hostname required\n");
10773 return(-3);
10774 }
10775 if ((x = cmcfm()) < 0) return(x); /* Confirm the command */
10776
10777 x = cx_net(mynet, /* nettype */
10778 0, /* protocol (not used) */
10779 line, /* host */
10780 "", /* port */
10781 NULL, /* alternate username */
10782 NULL, /* password */
10783 NULL, /* command to execute */
10784 0, /* param1 */
10785 0, /* param2 */
10786 0, /* param3 */
10787 cx, /* enter CONNECT mode */
10788 sx, /* enter SERVER mode */
10789 zz, /* close connection if open */
10790 0 /* gui */
10791 );
10792 }
10793 #endif /* DECNET */
10794
10795 #ifdef SSHBUILTIN
10796 if (mynet == NET_SSH) { /* SSH connection */
10797 int k, havehost = 0, trips = 0;
10798 int tmpver = -1, tmpxfw = -1, tmpssh_cas;
10799 #ifndef SSHTEST
10800 extern int sl_ssh_xfw, sl_ssh_xfw_saved;
10801 extern int sl_ssh_ver, sl_ssh_ver_saved;
10802 #endif /* SSHTEST */
10803 extern struct keytab sshopnsw[];
10804 extern int nsshopnsw;
10805 extern char *ssh_tmpcmd, *ssh_tmpport;
10806 struct FDB sw, kw, fl;
10807
10808 debug(F110,"setlin SSH service 0",srvbuf,0);
10809 debug(F110,"setlin SSH host s 2",s,0);
10810 if (*s) { /* If they gave a host name... */
10811 debug(F110,"setlin SSH host s 1",s,0);
10812 if (*s == '*') {
10813 makestr(&slmsg,"Incoming connections not supported");
10814 printf(
10815 "?Sorry, incoming connections not supported for SSH.\n"
10816 );
10817 return(-9);
10818 }
10819 ckstrncpy(line,s,LINBUFSIZ);
10820 } else {
10821 printf("?hostname required\n");
10822 return(-3);
10823 }
10824
10825 /* Parse [ port ] [ switches ] */
10826 cmfdbi(&kw, /* Switches */
10827 _CMKEY,
10828 "Port number or service name,\nor switch",
10829 "",
10830 "",
10831 nsshopnsw,
10832 4,
10833 xxstring,
10834 sshopnsw,
10835 &fl
10836 );
10837 cmfdbi(&fl, /* Port number or service name */
10838 _CMFLD,
10839 "",
10840 "",
10841 "",
10842 0,
10843 0,
10844 xxstring,
10845 NULL,
10846 NULL
10847 );
10848 trips = 0; /* Explained below */
10849 while (1) { /* Parse port and switches */
10850 y = cmfdb(&kw); /* Get a field */
10851 if (y == -3) /* User typed CR so quit from loop */
10852 break;
10853 if (y < 0) /* Other parse error, pass it back */
10854 return(y);
10855 switch (cmresult.fcode) { /* Field or Keyword? */
10856 case _CMFLD: /* Field */
10857 ckstrncpy(srvbuf,cmresult.sresult,SRVBUFSIZ);
10858 break;
10859 case _CMKEY: /* Keyword */
10860 switch (cmresult.nresult) { /* Which one? */
10861 case SSHSW_PWD:
10862 if (!cmgbrk()) {
10863 printf("?This switch requires an argument\n");
10864 return(-9);
10865 }
10866 debok = 0;
10867 if ((y = cmfld("Password","",&s,xxstring)) < 0) {
10868 if (y == -3) {
10869 makestr(&tmpstring,"");
10870 } else {
10871 return(y);
10872 }
10873 } else {
10874 s = brstrip(s);
10875 if ((y = (int)strlen(s)) > PWBUFL) {
10876 makestr(&slmsg,"Internal error");
10877 printf("?Sorry, too long - max = %d\n",PWBUFL);
10878 return(-9);
10879 }
10880 makestr(&tmpstring,s);
10881 }
10882 break;
10883 case SSHSW_USR: /* /USER: */
10884 if (!cmgbrk()) {
10885 printf("?This switch requires an argument\n");
10886 return(-9);
10887 }
10888 if ((y = cmfld("Username","",&s,xxstring)) < 0)
10889 return(y);
10890 s = brstrip(s);
10891 makestr(&tmpusrid,s);
10892 break;
10893 case SSHSW_VER:
10894 if ((y = cmnum("Number","",10,&z,xxstring)) < 0)
10895 return(y);
10896 if (z < 1 || z > 2) {
10897 printf("?Out of range: %d\n",z);
10898 return(-9);
10899 }
10900 tmpver = z;
10901 break;
10902 case SSHSW_CMD:
10903 case SSHSW_SUB:
10904 if ((y = cmfld("Text","",&s,xxstring)) < 0)
10905 return(y);
10906 makestr(&ssh_tmpcmd,s);
10907 tmpssh_cas = (cmresult.nresult == SSHSW_SUB);
10908 break;
10909 case SSHSW_X11:
10910 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0)
10911 return(y);
10912 tmpxfw = y;
10913 break;
10914 default:
10915 return(-2);
10916 }
10917 }
10918 if (trips++ == 0) { /* After first time through */
10919 cmfdbi(&kw, /* only parse switches, not port. */
10920 _CMKEY,
10921 "Switch",
10922 "",
10923 "",
10924 nsshopnsw,
10925 4,
10926 xxstring,
10927 sshopnsw,
10928 NULL
10929 );
10930 }
10931 }
10932 if ((y = cmcfm()) < 0) /* Get confirmation */
10933 return(y);
10934
10935 debug(F110,"setlin pre-cx_net line",line,0);
10936 debug(F110,"setlin pre-cx_net srvbuf",srvbuf,0);
10937 x = cx_net( mynet, /* nettype */
10938 0, /* protocol (not used) */
10939 line, /* host */
10940 srvbuf, /* port */
10941 tmpusrid, /* alternate username */
10942 tmpstring, /* password */
10943 ssh_tmpcmd, /* command to execute */
10944 tmpver, /* param1 - ssh version */
10945 tmpssh_cas, /* param2 - ssh cas */
10946 tmpxfw, /* param3 - ssh x11fwd */
10947 cx, /* enter CONNECT mode */
10948 sx, /* enter SERVER mode */
10949 zz, /* close connection if open */
10950 0 /* gui */
10951 );
10952 if (tmpusrid)
10953 makestr(&tmpusrid,NULL);
10954 if (ssh_tmpcmd)
10955 makestr(&ssh_tmpcmd,NULL);
10956 }
10957 #endif /* SSHBUILTIN */
10958
10959 #ifdef TCPSOCKET
10960 if (mynet == NET_TCPB) { /* TCP/IP connection */
10961 debug(F110,"setlin service 0",srvbuf,0);
10962 debug(F110,"setlin host s 2",s,0);
10963 if (*s) { /* If they gave a host name... */
10964 debug(F110,"setlin host s 1",s,0);
10965 #ifdef NOLISTEN
10966 if (*s == '*') {
10967 makestr(&slmsg,"Incoming connections not supported");
10968 printf(
10969 "?Sorry, incoming connections not supported in this version of Kermit.\n"
10970 );
10971 return(-9);
10972 }
10973 #endif /* NOLISTEN */
10974 #ifdef RLOGCODE
10975 /* Allow a username if rlogin is requested */
10976 if (mynet == NET_TCPB &&
10977 (ttnproto == NP_RLOGIN || ttnproto == NP_K5LOGIN ||
10978 ttnproto == NP_EK5LOGIN || ttnproto == NP_K4LOGIN ||
10979 ttnproto == NP_EK4LOGIN
10980 )) {
10981 int y;
10982 uidflag = 0;
10983 /* Check for "host:service" */
10984 for ( ; (*s != '\0') && (*s != ':'); s++) ;
10985 if (*s) { /* Service, save it */
10986 *s = NUL;
10987 ckstrncpy(srvbuf,++s,SRVBUFSIZ);
10988 } else { /* No :service, then use default. */
10989 #ifdef VMS
10990 switch (ttnproto) {
10991 case NP_RLOGIN:
10992 ckstrncpy(srvbuf,"513",SRVBUFSIZ); /* "login" */
10993 break;
10994 case NP_K4LOGIN:
10995 case NP_K5LOGIN:
10996 ckstrncpy(srvbuf,"543",SRVBUFSIZ); /* "klogin" */
10997 break;
10998 case NP_EK4LOGIN:
10999 case NP_EK5LOGIN:
11000 ckstrncpy(srvbuf,"2105",SRVBUFSIZ); /* "eklogin" */
11001 break;
11002 }
11003 #else /* VMS */
11004 switch (ttnproto) {
11005 case NP_RLOGIN:
11006 ckstrncpy(srvbuf,"login",SRVBUFSIZ);
11007 break;
11008 case NP_K4LOGIN:
11009 case NP_K5LOGIN:
11010 ckstrncpy(srvbuf,"klogin",SRVBUFSIZ);
11011 break;
11012 case NP_EK4LOGIN:
11013 case NP_EK5LOGIN:
11014 ckstrncpy(srvbuf,"eklogin",SRVBUFSIZ);
11015 break;
11016 }
11017 #endif /* VMS */
11018 }
11019 if (!confirmed) {
11020 y = cmfld("Userid on remote system",
11021 uidbuf,&s,xxstring);
11022 if (y < 0 && y != -3)
11023 return(y);
11024 if ((int)strlen(s) > 63) {
11025 makestr(&slmsg,"Internal error");
11026 printf("Sorry, too long\n");
11027 return(-9);
11028 }
11029 makestr(&tmpusrid,s);
11030 }
11031 } else { /* TELNET or SET HOST */
11032 #endif /* RLOGCODE */
11033 /* Check for "host:service" */
11034 for ( ; (*s != '\0') && (*s != ':'); s++) ;
11035 if (*s) { /* Service, save it */
11036 *s = NUL;
11037 ckstrncpy(srvbuf,++s,SRVBUFSIZ);
11038 } else if (!confirmed) {
11039 /* No :service, let them type one. */
11040 if (*line != '*') { /* Not incoming */
11041 if (mynet == NET_TCPB && ttnproto == NP_KERMIT) {
11042 if ((x = cmfld(
11043 "TCP service name or number",
11044 "kermit",&s,xxstring)
11045 ) < 0 && x != -3)
11046 return(x);
11047 #ifdef RLOGCODE
11048 } else if (mynet == NET_TCPB &&
11049 ttnproto == NP_RLOGIN) {
11050 if ((x = cmfld(
11051 "TCP service name or number,\n or carriage return for rlogin (513)",
11052 "login",&s,xxstring)
11053 ) < 0 && x != -3)
11054 return(x);
11055 #ifdef CK_AUTHENTICATION
11056 #ifdef CK_KERBEROS
11057 } else if (mynet == NET_TCPB &&
11058 (ttnproto == NP_K4LOGIN ||
11059 ttnproto == NP_K5LOGIN)) {
11060 if ((x = cmfld(
11061 "TCP service name or number,\n or carriage return for klogin (543)",
11062 "klogin",&s,xxstring)
11063 ) < 0 && x != -3)
11064 return(x);
11065 } else if (mynet == NET_TCPB &&
11066 (ttnproto == NP_EK4LOGIN ||
11067 ttnproto == NP_EK5LOGIN)) {
11068 if ((x = cmfld(
11069 "TCP service name or number,\n or carriage return for eklogin (2105)",
11070 "eklogin",&s,xxstring)
11071 ) < 0 && x != -3)
11072 return(x);
11073 #endif /* CK_KERBEROS */
11074 #endif /* CK_AUTHENTICATION */
11075 #endif /* RLOGCODE */
11076 } else {
11077 /* Do not set a default value in this call */
11078 /* If you do then it will prevent entries */
11079 /* in the network directory from accessing */
11080 /* alternate ports. */
11081
11082 if ((x = cmfld(
11083 "TCP service name or number",
11084 "",&s,xxstring)
11085 ) < 0 && x != -3)
11086 return(x);
11087 }
11088 } else { /* Incoming connection */
11089 if ((x = cmfld("TCP service name or number",
11090 "",&s,xxstring)
11091 ) < 0 && x != -3)
11092 return(x);
11093 }
11094 if (*s) /* If they gave a service, */
11095 ckstrncpy(srvbuf,s,SRVBUFSIZ); /* copy it */
11096 debug(F110,"setlin service 0.5",srvbuf,0);
11097 }
11098 #ifdef RLOGCODE
11099 }
11100 #endif /* RLOGCODE */
11101 if (!confirmed) {
11102 char * defproto;
11103 switch (ttnproto) {
11104 case NP_RLOGIN:
11105 defproto = "/rlogin";
11106 break;
11107 case NP_K4LOGIN:
11108 defproto = "/k4login";
11109 break;
11110 case NP_K5LOGIN:
11111 defproto = "/k5login";
11112 break;
11113 case NP_EK4LOGIN:
11114 defproto = "/ek4login";
11115 break;
11116 case NP_EK5LOGIN:
11117 defproto = "/ek5login";
11118 break;
11119 case NP_KERMIT:
11120 case NP_TELNET:
11121 defproto = "/telnet";
11122 break;
11123 default:
11124 defproto = "/default";
11125 }
11126 if ((x = cmkey(tcprawtab,ntcpraw,"Switch",defproto,
11127 xxstring)) < 0) {
11128 if (x != -3)
11129 return(x);
11130 else if ((x = cmcfm()) < 0)
11131 return(x);
11132 } else {
11133 rawflg = x;
11134 if ((x = cmcfm()) < 0)
11135 return(x);
11136 }
11137 }
11138 }
11139 debug(F110,"setlin pre-cx_net line",line,0);
11140 debug(F110,"setlin pre-cx_net srvbuf",srvbuf,0);
11141 x = cx_net( mynet, /* nettype */
11142 rawflg /* protocol */,
11143 line, /* host */
11144 srvbuf, /* port */
11145 tmpusrid, /* alternate username */
11146 tmpstring, /* password */
11147 NULL, /* command to execute */
11148 a_type, /* param1 - telnet authtype */
11149 e_type, /* param2 - telnet enctype */
11150 wait, /* param3 - telnet wait */
11151 cx, /* enter CONNECT mode */
11152 sx, /* enter SERVER mode */
11153 zz, /* close connection if open */
11154 0 /* gui */
11155 );
11156 }
11157 #endif /* TCPSOCKET */
11158
11159 #ifdef CK_SECURITY
11160 if (tmpstring)
11161 makestr(&tmpstring,NULL);
11162 #endif /* CK_SECURITY */
11163 if (tmpusrid)
11164 makestr(&tmpusrid,NULL);
11165 debug(F111,"setlin cx_net",line,x);
11166 return(x);
11167 #endif /* NETCONN */
11168 }
11169
11170 /* Serial tty device, possibly modem, connection... */
11171
11172 #ifdef OS2
11173 /*
11174 User can type:
11175 COM1..COM8 = Regular COM port
11176 1..8 = Synonym for COM1..COM8, is translated to COM1..COM8
11177 _n = (n is a number) = open file handle
11178 string = any text string = name of some other kind of device,
11179 taken literally, as given.
11180 */
11181 s = "Communication device name";
11182
11183 #ifdef CK_TAPI
11184 if (TAPIAvail)
11185 cktapiBuildLineTable(&tapilinetab, &_tapilinetab, &ntapiline);
11186 if (!(tapilinetab && _tapilinetab && ntapiline > 0) &&
11187 xx == XYTAPI_LIN ) {
11188 makestr(&slmsg,"TAPI device not configured");
11189 printf("\nNo TAPI Line Devices are configured for this system\n");
11190 return(-9);
11191 }
11192 if (xx == XYTAPI_LIN) { /* Default (first) TAPI line */
11193 s = "tapi"; /* (whatever it is) */
11194 } else { /* Query the user */
11195 #endif /* CK_TAPI */
11196
11197 /* Now parse optional switches and then device name */
11198
11199 confirmed = 0;
11200 cmfdbi(&sw,_CMKEY,"Device name, or switch",
11201 "","",npsltab,4,xxstring,psltab,&fl);
11202 cmfdbi(&fl,_CMFLD,"",dftty,"",0,0,xxstring,NULL,NULL);
11203 while (1) {
11204 x = cmfdb(&sw);
11205 debug(F101,"setlin cmfdb","",x);
11206 if (x < 0)
11207 if (x != -3)
11208 return(x);
11209 if (x == -3) {
11210 if ((x = cmcfm()) < 0) {
11211 return(x);
11212 } else {
11213 confirmed = 1;
11214 break;
11215 }
11216 }
11217 if (cmresult.fcode == _CMFLD) {
11218 s = cmresult.sresult;
11219 break;
11220 } else if (cmresult.fcode == _CMKEY) {
11221 switch (cmresult.nresult) {
11222 case SL_CNX: /* /CONNECT */
11223 cx = 1;
11224 sx = 0;
11225 break;
11226 case SL_SRV: /* /SERVER */
11227 cx = 0;
11228 sx = 1;
11229 break;
11230 case SL_SHR: /* /SHARE */
11231 shr = 1;
11232 break;
11233 case SL_NSH: /* /NOSHARE */
11234 shr = 0;
11235 break;
11236 }
11237 }
11238 }
11239 #ifdef CK_TAPI
11240 }
11241 #endif /* CK_TAPI */
11242
11243 debug(F110,"OS2 SET PORT s",s,0);
11244 y = lookup(os2devtab,s,nos2dev,&x); /* Look up in keyword table */
11245 debug(F101,"OS2 SET PORT x","",x);
11246 debug(F101,"OS2 SET PORT y","",y);
11247 if ((y > -1) && (x >= 0 && x < 8)) { /* User typed a digit 1..8 */
11248 s = os2devtab[x+8].kwd; /* Substitite its real name */
11249 #ifdef NT
11250 xxtapi = 0;
11251 #else /* NT */
11252 xxslip = xxppp = 0;
11253 #endif /* NT */
11254 debug(F110,"OS2 SET PORT subst s",s,"");
11255 #ifndef NT
11256 } else if ((y >-1) && (x >= 16 && x < 24)) { /* SLIP access */
11257 s = os2devtab[x-8].kwd; /* Substitite its real name */
11258 debug(F110,"OS2 SET PORT SLIP subst s",s,"");
11259 xxslip = 1;
11260 xxppp = 0;
11261 } else if ((y >-1) && (x >= 24 && x < 32)) { /* PPP access */
11262 s = os2devtab[x-16].kwd; /* Substitite its real name */
11263 debug(F110,"OS2 SET PORT PPP subst s",s,"");
11264 xxppp = 1;
11265 xxslip = 0;
11266 if ((y = cmkey(os2ppptab,
11267 nos2ppp,
11268 "PPP driver interface",
11269 "ppp0",
11270 xxstring)
11271 ) < 0)
11272 return(y);
11273 debug(F101,"OS2 SET PORT PPP INTERFACE y","",y);
11274 xxppp = (y % 10) + 1;
11275 #endif /* NT */
11276 } else if (*s == '_') { /* User used "_" prefix */
11277 s++; /* Remove it */
11278 /* Rest must be numeric */
11279 debug(F110,"OS2 SET PORT HANDLE _subst s",s,0);
11280 if (!rdigits(s)) {
11281 makestr(&slmsg,"Invalid file handle");
11282 printf("?Invalid format for file handle\n");
11283 return(-9);
11284 }
11285 #ifdef NT
11286 xxtapi = 0;
11287 #else /* NT */
11288 xxslip = xxppp = 0;
11289 #endif /* NT */
11290 } else { /* A normal COMx port or a string */
11291 s = brstrip(s); /* Strip braces if any */
11292 #ifdef NT
11293 #ifdef CK_TAPI
11294 /* Windows TAPI support - Look up in keyword table */
11295 if (tapilinetab && _tapilinetab && ntapiline > 0) {
11296 if (!ckstrcmp(s,"tapi",4,0)) {
11297
11298 /* Find out what the lowest numbered TAPI device is */
11299 /* and use it as the default. */
11300 int j = 9999, k = -1;
11301 for (i = 0; i < ntapiline; i++) {
11302 if (tapilinetab[i].kwval < j) {
11303 j = tapilinetab[i].kwval;
11304 k = i;
11305 }
11306 }
11307 if (k >= 0)
11308 s = _tapilinetab[k].kwd;
11309 else
11310 s = "";
11311
11312 if ((y = cmkey(_tapilinetab,ntapiline,
11313 "TAPI device name",s,xxstring)) < 0)
11314 return(y);
11315
11316 xxtapi = 1;
11317
11318 /* Get the non Underscored string */
11319 for (i = 0; i < ntapiline; i++ ) {
11320 if (tapilinetab[i].kwval == y) {
11321 s = tapilinetab[i].kwd;
11322 break;
11323 }
11324 }
11325 } else
11326 xxtapi = 0;
11327 }
11328 #endif /* CK_TAPI */
11329 #else /* NT */
11330 /* not OS/2 SLIP or PPP */
11331 xxslip = xxppp = 0;
11332 #endif /* NT */
11333 }
11334 ckstrncpy(tmpbuf,s,TMPBUFSIZ); /* Copy to a safe place */
11335 s = tmpbuf;
11336 if ((x = cmcfm()) < 0)
11337 return(x);
11338
11339 #else /* !OS2 */
11340
11341 cmfdbi(&sw,_CMKEY,"Device name, or switch",
11342 "","",npsltab,4,xxstring,psltab,&tx);
11343 cmfdbi(&tx,_CMTXT,"",dftty,"",0,0,xxstring,NULL,NULL);
11344 while (!confirmed) {
11345 x = cmfdb(&sw);
11346 debug(F101,"setlin cmfdb","",x);
11347 if (x < 0)
11348 if (x != -3)
11349 return(x);
11350 if (x == -3) {
11351 if ((x = cmcfm()) < 0) {
11352 return(x);
11353 } else {
11354 confirmed = 1;
11355 break;
11356 }
11357 }
11358 switch (cmresult.fcode) {
11359 case _CMTXT:
11360 ckstrncpy(tmpbuf,cmresult.sresult,TMPBUFSIZ);
11361 s = tmpbuf;
11362 debug(F110,"setlin CMTXT",tmpbuf,0);
11363 confirmed = 1;
11364 break;
11365 case _CMKEY: /* Switch */
11366 debug(F101,"setlin CMKEY",tmpbuf,cmresult.nresult);
11367 switch (cmresult.nresult) {
11368 case SL_CNX: /* /CONNECT */
11369 cx = 1;
11370 sx = 0;
11371 break;
11372 case SL_SRV: /* /SERVER */
11373 cx = 0;
11374 sx = 1;
11375 break;
11376 #ifdef VMS
11377 case SL_SHR: /* /SHARE */
11378 shr = 1;
11379 break;
11380 case SL_NSH: /* /NOSHARE */
11381 shr = 0;
11382 break;
11383 #endif /* VMS */
11384 }
11385 continue;
11386 default:
11387 debug(F101,"setlin bad cmfdb result","",cmresult.fcode);
11388 makestr(&slmsg,"Internal error");
11389 printf("?Internal parsing error\n");
11390 return(-9);
11391 }
11392 }
11393 #endif /* OS2 */
11394 if (!confirmed)
11395 if ((x = cmcfm()) < 0)
11396 return(x);
11397
11398 debug(F110,"setlin pre-cx_serial s",s,0);
11399 debug(F110,"setlin pre-cx_serial line",line,0);
11400 x = cx_serial(s,cx,sx,shr,zz,0,
11401 #ifdef OS2
11402 #ifdef NT
11403 (xxtapi ? CX_TAPI : 0)
11404 #else
11405 (xxslip ? CX_SLIP : 0) | (xxppp ? CX_PPP : 0)
11406 #endif /* NT */
11407 #else /* OS2 */
11408 0
11409 #endif /* OS2 */
11410 );
11411 debug(F111,"setlin cx_serial",line,x);
11412 return(x);
11413 }
11414 #endif /* NOLOCAL */
11415
11416 #ifdef CKCHANNELIO
11417 /*
11418 C-Library based file-i/o package for scripts. This should be portable to
11419 all C-Kermit versions since it uses the same APIs we have always used for
11420 processing command files. The entire channel i/o package is contained
11421 herein, apart from some keyword table entries in the main keyword table
11422 and the help text in the HELP command module.
11423
11424 On platforms like VMS and VOS, this package handles only UNIX-style
11425 stream files. If desired, it can be replaced for those platforms by
11426 <#>ifdef'ing out this code and adding the equivalent replacement routines
11427 to the ck?fio.c module, e.g. for RMS-based file i/o in ckvfio.c.
11428 */
11429 #ifndef NOSTAT
11430 #ifdef VMS
11431 /* 2010-03-09 SMS. VAX C needs help to find "sys". It's easier not to try. */
11432 #include <stat.h>
11433 #else /* def VMS */
11434 #include <sys/stat.h>
11435 #endif /* def VMS [else] */
11436 #endif /* NOSTAT */
11437
11438 #ifdef NLCHAR
11439 static int z_lt = 1; /* Length of line terminator */
11440 #else
11441 static int z_lt = 2;
11442 #endif /* NLCHAR */
11443
11444 struct ckz_file { /* C-Kermit file struct */
11445 FILE * z_fp; /* Includes the C-Lib file struct */
11446 unsigned int z_flags; /* Plus C-Kermit mode flags, */
11447 CK_OFF_T z_nline; /* current line number if known, */
11448 char z_name[CKMAXPATH+2]; /* and the file's name. */
11449 };
11450 static struct ckz_file ** z_file = NULL; /* Array of C-Kermit file structs */
11451 static int z_inited = 0; /* Flag for array initialized */
11452 int z_maxchan = Z_MAXCHAN; /* Max number of C-Kermit channels */
11453 int z_openmax = CKMAXOPEN; /* Max number of open files overall */
11454 int z_nopen = 0; /* How many channels presently open */
11455 int z_error = 0; /* Most recent error */
11456 int z_filcount = -1; /* Most recent FILE COUNT result */
11457
11458 #define RD_LINE 0 /* FILE READ options */
11459 #define RD_CHAR 1
11460 #define RD_SIZE 2
11461 #define RD_TRIM 8 /* Like Snobol &TRIM = 1 */
11462 #define RD_UNTA 9 /* Untabify */
11463
11464 #define WR_LINE RD_LINE /* FILE WRITE options */
11465 #define WR_CHAR RD_CHAR
11466 #define WR_SIZE RD_SIZE
11467 #define WR_STRI 3
11468 #define WR_LPAD 4
11469 #define WR_RPAD 5
11470
11471 #ifdef UNIX
11472 extern int ckmaxfiles; /* Filled in by sysinit(). */
11473 #endif /* UNIX */
11474
11475 /* See ckcker.h for error numbers */
11476 /* See ckcdeb.h for Z_MAXCHAN and CKMAXOPEN definitions */
11477 /* NOTE: For VMS we might be able to fill in ckmaxfiles */
11478 /* from FILLM and CHANNELCNT -- find out about these... */
11479
11480 static char * fopnargs[] = { /* Mode combinations for fopen() */
11481 #ifdef COMMENT
11482 /* All combinations of rwa */
11483 "", "r", "w", "rw", "a", "ra", "wa", "rwa", /* Text mode */
11484 "b", "rb", "wb", "rwb", "ab", "rab", "wab", "rwab" /* Binary mode */
11485 #else
11486 /* Combinations and syntax permitted by C libraries... */
11487 "", "r", "w", "r+", "a", "", "a", "", /* Text mode */
11488 #ifdef OS2
11489 "", "rb", "wb", "r+b", "ab", "", "ab", "" /* Binary modes for K95 */
11490 #else
11491 #ifdef VMS
11492 "", "rb", "wb", "r+b", "ab", "", "ab", "" /* Binary modes for VMS */
11493 #else
11494 "", "r", "w", "r+", "a", "", "a", "" /* Binary modes for UNIX */
11495 #endif /* VMS */
11496 #endif /* OS2 */
11497 #endif /* COMMENT */
11498 };
11499 static int nfopnargs = sizeof(fopnargs) / sizeof(char *);
11500
11501 char * /* Error messages */
ckferror(n)11502 ckferror(n) int n; {
11503 switch (n) {
11504 case FX_NER: return("No error");
11505 case FX_SYS: return(ck_errstr());
11506 case FX_EOF: return("End of file");
11507 case FX_NOP: return("File not open");
11508 case FX_CHN: return("Channel out of range");
11509 case FX_RNG: return("Parameter out of range");
11510 case FX_NMF: return("Too many files open");
11511 case FX_FOP: return("Operation conflicts with OPEN mode");
11512 case FX_NYI: return("OPEN mode not supported");
11513 case FX_BOM: return("Illegal combination of OPEN modes");
11514 case FX_ACC: return("Access denied");
11515 case FX_FNF: return("File not found");
11516 case FX_OFL: return("Buffer overflow");
11517 case FX_LNU: return("Current line number unknown");
11518 case FX_ROO: return("Off limits");
11519 case FX_UNK: return("Operation fails - reason unknown");
11520 default: return("Error number out of range");
11521 }
11522 }
11523
11524 /*
11525 Z _ O P E N -- Open a file for the requested type of access.
11526
11527 Call with:
11528 name: Name of file to be opened.
11529 flags: Any combination of FM_xxx values except FM_EOF (ckcker.h).
11530 Returns:
11531 >= 0 on success: The assigned channel number
11532 < 0 on failure: A negative FX_xxx error code (ckcker.h).
11533 */
11534 int
z_open(name,flags)11535 z_open(name, flags) char * name; int flags; {
11536 int i, n;
11537 FILE * t;
11538 char * mode;
11539 debug(F111,"z_open",name,flags);
11540 if (!name) name = ""; /* Check name argument */
11541 if (!name[0])
11542 return(z_error = FX_BFN);
11543 if (flags & FM_CMD) /* Opening pipes not implemented yet */
11544 return(z_error = FX_NYI); /* (and not portable either) */
11545 debug(F101,"z_open nfopnargs","",nfopnargs);
11546
11547 if (flags & FM_STDIN) { /* Read from standard input */
11548 mode = "r";
11549 } else if (flags & (FM_STDOUT|FM_STDERR)) {
11550 mode = "w";
11551 } else { /* If regular file, not stdin.. */
11552 if (flags < 0 || flags >= nfopnargs) /* Range check flags */
11553 return(z_error = FX_RNG);
11554 mode = fopnargs[flags]; /* Get fopen() arg */
11555 debug(F111,"z_open fopen args",mode,flags);
11556 if (!mode[0]) /* Check for illegal combinations */
11557 return(z_error = FX_BOM);
11558 }
11559 if (!z_inited) { /* If file structs not inited */
11560 debug(F101,"z_open z_maxchan 1","",z_maxchan);
11561 #ifdef UNIX
11562 debug(F101,"z_open ckmaxfiles","",ckmaxfiles);
11563 if (ckmaxfiles > 0) { /* Set in ck?tio.c: sysinit() */
11564 int x;
11565 x = ckmaxfiles - ZNFILS - 5;
11566 if (x > z_maxchan) /* sysconf() value greater than */
11567 z_maxchan = x; /* value from header files. */
11568 debug(F101,"z_open z_maxchan 2","",z_maxchan);
11569 }
11570 #endif /* UNIX */
11571 if (z_maxchan < Z_MINCHAN) /* Allocate at least this many. */
11572 z_maxchan = Z_MINCHAN;
11573 debug(F101,"z_open z_maxchan 3","",z_maxchan);
11574 /* Note: This could be a pretty big chunk of memory */
11575 /* if z_maxchan is a big number. If this becomes a problem */
11576 /* we'll need to malloc and free each element at open/close time */
11577 #ifdef COMMENT
11578 /* May 2006 - it's time - in current Linux this about 3MB */
11579 if (!(z_file = (struct ckz_file *)
11580 malloc(sizeof(struct ckz_file) * (z_maxchan + 1))))
11581 return(z_error = FX_NMF);
11582 for (i = 0; i < z_maxchan; i++) {
11583 z_file[i].z_fp = NULL;
11584 z_file[i].z_flags = 0;
11585 z_file[i].z_nline = 0;
11586 *(z_file[i].z_name) = '\0';
11587 }
11588 #else
11589 /* New economical way, allocate storage for each channel as needed */
11590 if (!z_file) {
11591 debug(F100,"z_file[] is NULL","",0);
11592 debug(F101,"sizeof(struct ckz_file *)","",
11593 sizeof(struct ckz_file *));
11594 z_file = (struct ckz_file **)malloc((z_maxchan + 1) *
11595 sizeof(struct ckz_file *));
11596 debug(F101,"z_open z_maxchan 4","",z_maxchan);
11597 if (!z_file)
11598 return(z_error = FX_NMF);
11599 for (i = 0; i < z_maxchan; i++)
11600 z_file[i] = NULL;
11601 debug(F101,"z_open z_maxchan 5","",z_maxchan);
11602 }
11603 #endif /* COMMENT */
11604 debug(F101,"z_open z_maxchan 6","",z_maxchan);
11605 z_inited = 1; /* Remember we initialized */
11606 }
11607 for (n = -1, i = 0; i < z_maxchan; i++) { /* Find a free channel */
11608 #ifdef COMMENT
11609 if (!z_file[i].z_fp) {
11610 n = i;
11611 break;
11612 }
11613 #else
11614 debug(F101,"z_open find-free-channel loop","",i);
11615 if (!z_file[i]) {
11616 z_file[i] = (struct ckz_file *) malloc(sizeof(struct ckz_file));
11617 if (!z_file[i])
11618 return(z_error = FX_NMF);
11619 n = i;
11620 break;
11621 }
11622 #endif /* COMMENT */
11623
11624 }
11625 debug(F101,"z_open found free channel","",n);
11626 if (n < 0 || n >= z_maxchan) /* Any free channels? */
11627 return(z_error = FX_NMF); /* No, fail. */
11628 debug(F100,"z_open check n ok","",0);
11629 errno = 0;
11630 debug(F100,"z_open errno ok","",0);
11631 z_file[n]->z_flags = 0; /* In case of failure... */
11632 debug(F100,"z_open z_file[n] flags ok","",0);
11633 z_file[n]->z_fp = NULL; /* Set file pointer to NULL */
11634 debug(F100,"z_open z_file[n] fps ok","",0);
11635
11636 #ifdef UNIX
11637 if (flags & FM_STDIN) { /* Standard input */
11638 t = (FILE *)stdin; /* We just use the ready-made stream */
11639 z_nopen++; /* Count it. */
11640 z_file[n]->z_fp = t; /* Stash the file pointer */
11641 z_file[n]->z_flags = flags; /* and the flags */
11642 z_file[n]->z_nline = 0; /* Current line number is 0 */
11643 ckstrncpy(z_file[n]->z_name,name,CKMAXPATH); /* "filename" */
11644 z_error = 0; /* No error so far */
11645 return(n); /* Return the channel number */
11646 }
11647 if (flags & FM_STDOUT) { /* Standard output */
11648 t = (FILE *)stdout; /* Same deal */
11649 z_nopen++;
11650 z_file[n]->z_fp = t;
11651 z_file[n]->z_flags = flags;
11652 z_file[n]->z_nline = 0;
11653 ckstrncpy(z_file[n]->z_name,name,CKMAXPATH);
11654 z_error = 0;
11655 return(n);
11656 }
11657 if (flags & FM_STDERR) { /* Standard error */
11658 t = (FILE *)stderr;
11659 z_nopen++;
11660 z_file[n]->z_fp = t;
11661 z_file[n]->z_flags = flags;
11662 z_file[n]->z_nline = 0;
11663 ckstrncpy(z_file[n]->z_name,name,CKMAXPATH);
11664 z_error = 0;
11665 return(n);
11666 }
11667 #endif /* UNIX */
11668 t = fopen(name, mode); /* Try to open the file. */
11669 if (!t) { /* Failed... */
11670 debug(F111,"z_open error",name,errno);
11671 #ifdef EMFILE
11672 if (errno == EMFILE)
11673 return(z_error = FX_NMF);
11674 #endif /* EMFILE */
11675 free(z_file[n]);
11676 z_file[n] = NULL;
11677 return(z_error = (errno ? FX_SYS : FX_UNK)); /* Return error code */
11678 }
11679 #ifdef NT
11680 #ifdef O_SEQUENTIAL
11681 if (t) /* Caching hint for NT */
11682 _setmode(_fileno(t),O_SEQUENTIAL);
11683 #endif /* O_SEQUENTIAL */
11684 #endif /* NT */
11685
11686 z_nopen++; /* Open, count it. */
11687 z_file[n]->z_fp = t; /* Stash the file pointer */
11688 z_file[n]->z_flags = flags; /* and the flags */
11689 z_file[n]->z_nline = 0; /* Current line number is 0 */
11690 z_error = 0;
11691 zfnqfp(name,CKMAXPATH,z_file[n]->z_name); /* and the file's full name */
11692 return(n); /* Return the channel number */
11693 }
11694
11695 int
z_close(channel)11696 z_close(channel) int channel; { /* Close file on given channel */
11697 int x;
11698 FILE * t;
11699 if (!z_inited) /* Called before any files are open? */
11700 return(z_error = FX_NOP);
11701 if (channel >= z_maxchan) /* Channel out of range? */
11702 return(z_error = FX_CHN);
11703 if (!z_file[channel])
11704 return(z_error = FX_NOP);
11705 if (!(t = z_file[channel]->z_fp)) /* Channel wasn't open? */
11706 return(z_error = FX_NOP);
11707 errno = 0; /* Set errno 0 to get a good reading */
11708 if (!(z_file[channel]->z_flags & FM_STDM)) /* If not stdin/out/err... */
11709 x = fclose(t); /* Try to close */
11710 if (x == EOF) /* On failure */
11711 return(z_error = FX_SYS); /* indicate system error. */
11712 z_nopen--; /* Closed OK, decrement open count */
11713 z_file[channel]->z_fp = NULL; /* Set file pointer to NULL */
11714 z_file[channel]->z_nline = 0; /* Current line number is 0 */
11715 z_file[channel]->z_flags = 0; /* Set flags to 0 */
11716 *(z_file[channel]->z_name) = '\0'; /* Clear name */
11717 free(z_file[channel]);
11718 z_file[channel] = NULL;
11719 return(z_error = 0);
11720 }
11721
11722 /*
11723 Z _ O U T -- Output string to channel.
11724
11725 Call with:
11726 channel: Channel number to write to.
11727 s: String to write.
11728 length > -1: How many characters of s to write.
11729 length < 0: Write entire NUL-terminated string.
11730 flags == 0: Supply line termination.
11731 flags > 0: Don't supply line termination.
11732 flags < 0: Write 'length' NUL characters.
11733 Special case:
11734 If flags > -1 and s is empty or NULL and length == 1, write 1 NUL.
11735 Returns:
11736 Number of characters written to channel on success, or
11737 negative FX_xxx error code on failure.
11738 */
11739 int
z_out(channel,s,length,flags)11740 z_out(channel,s,length,flags) int channel, flags, length; char * s; {
11741 FILE * t;
11742 int x, n;
11743 char c = '\0';
11744
11745 if (!s) s = ""; /* Guard against null pointer */
11746 #ifdef DEBUG
11747 if (deblog) {
11748 debug(F111,"z_out",s,channel);
11749 debug(F101,"z_out length","",length);
11750 debug(F101,"z_out flags","",flags);
11751 }
11752 #endif /* DEBUG */
11753 if (!z_inited) /* File i/o inited? */
11754 return(z_error = FX_NOP);
11755 if (channel >= z_maxchan) /* Channel in range? */
11756 return(z_error = FX_CHN);
11757 if (!z_file[channel])
11758 return(z_error = FX_NOP);
11759 if (!(t = z_file[channel]->z_fp)) /* File open? */
11760 return(z_error = FX_NOP);
11761 if (!((z_file[channel]->z_flags) & (FM_WRI|FM_APP))) /* In write mode? */
11762 return(z_error = FX_FOP);
11763 n = length; /* Length of string to write */
11764 if (n < 0) { /* Negative means get it ourselves */
11765 if (flags < 0) /* Except when told to write NULs in */
11766 return(z_error = FX_RNG); /* which case args are inconsistent */
11767 n = strlen(s); /* Get length of string arg */
11768 }
11769 errno = 0; /* Reset errno */
11770 debug(F101,"z_out n","",n);
11771 if (flags < 0) { /* Writing NULs... */
11772 int i;
11773 for (i = 0; i < n; i++) {
11774 x = fwrite(&c,1,1,t);
11775 if (x < 1)
11776 return(z_error = (errno ? FX_SYS : FX_UNK));
11777 }
11778 z_file[channel]->z_nline = -1; /* Current line no longer known */
11779 z_error = 0;
11780 return(i);
11781 } else { /* Writing string arg */
11782 if (n == 1 && !s[0]) /* Writing one char but it's NUL */
11783 x = fwrite(&c,1,1,t);
11784 else /* Writing non-NUL char or string */
11785 x = fwrite(s,1,n,t);
11786 debug(F101,"z_out fwrite",ckitoa(x),errno);
11787 if (x < n) /* Failure to write requested amount */
11788 return(z_error = (errno ? FX_SYS : FX_UNK)); /* Return error */
11789 if (flags == 0) { /* If supplying line termination */
11790 if (fwrite("\n",1,1,t)) /* do that */
11791 x += z_lt; /* count the terminator */
11792 if (z_file[channel]->z_nline > -1) /* count this line */
11793 z_file[channel]->z_nline++;
11794 } else {
11795 z_file[channel]->z_nline = -1; /* Current line no longer known */
11796 }
11797 }
11798 z_error = 0;
11799 return(x);
11800 }
11801
11802 #define Z_INBUFLEN 64
11803
11804 /*
11805 Z _ I N -- Multichannel i/o file input function.
11806
11807 Call with:
11808 channel number to read from.
11809 s = address of destination buffer.
11810 buflen = destination buffer length.
11811 length = Number of bytes to read, must be < buflen.
11812 flags: 0 = read a line; nonzero = read the given number of bytes.
11813 Returns:
11814 Number of bytes read into buffer or a negative error code.
11815 A terminating NUL is deposited after the last byte that was read.
11816 */
11817 int
z_in(channel,s,buflen,length,flags)11818 z_in(channel,s,buflen,length,flags)
11819 int channel, buflen, length, flags; char * s;
11820 /* z_in */ {
11821 int i, j, x;
11822 FILE * t;
11823 char * p;
11824
11825 if (!z_inited) /* Check everything... */
11826 return(z_error = FX_NOP);
11827 if (channel >= z_maxchan)
11828 return(z_error = FX_CHN);
11829 if (!z_file[channel])
11830 return(z_error = FX_NOP);
11831 if (!(t = z_file[channel]->z_fp))
11832 return(z_error = FX_NOP);
11833 if (!((z_file[channel]->z_flags) & FM_REA))
11834 return(z_error = FX_FOP);
11835 if (!s) /* Check destination */
11836 return(z_error = FX_RNG);
11837 s[0] = NUL;
11838 if (length == 0) /* Read 0 bytes - easy. */
11839 return(z_error = 0);
11840 debug(F101,"z_in channel","",channel);
11841 debug(F101,"z_in buflen","",buflen);
11842 debug(F101,"z_in length","",length);
11843 debug(F101,"z_in flags","",flags);
11844 if (length < 0 || buflen < 0) /* Check length args */
11845 return(z_error = FX_RNG);
11846 if (buflen <= length)
11847 return(z_error = FX_RNG);
11848 errno = 0; /* Reset errno */
11849 if (flags) { /* Read block or byte */
11850 int n; /* 20050912 */
11851 n = length; /* 20050912 */
11852 i = 0; /* 20050912 */
11853 while (n > 0) { /* 20050912 */
11854 i = fread(s,1,n,t); /* 20050912 */
11855 #ifdef DEBUG
11856 if (deblog) {
11857 debug(F111,"z_in block",s,i);
11858 debug(F101,"z_in block errno","",errno);
11859 debug(F101,"z_in block ferror","",ferror(t));
11860 debug(F101,"z_in block feof","",feof(t));
11861 }
11862 #endif /* DEBUG */
11863 if (i == 0) break; /* 20050912 */
11864 s += i; /* 20050912 */
11865 n -= i; /* 20050912 */
11866 }
11867 /* Current line no longer known */
11868 z_file[channel]->z_nline = (CK_OFF_T)-1;
11869 } else { /* Read line */
11870 #ifndef COMMENT
11871 /* This method is used because it's simpler than the others */
11872 /* and also marginally faster. */
11873 debug(F101,"z_in getc loop","",CKFTELL(t));
11874 for (i = 0; i < length; i++) {
11875 if ((x = getc(t)) == EOF) {
11876 debug(F101,"z_in getc error","",CKFTELL(t));
11877 s[i] = '\0';
11878 break;
11879 }
11880 s[i] = x;
11881 if (s[i] == '\n') {
11882 s[i] = '\0';
11883 break;
11884 }
11885 }
11886 debug(F111,"z_in line byte loop",ckitoa(errno),i);
11887 debug(F111,"z_in line got",s,z_file[channel]->z_nline);
11888 if (z_file[channel]->z_nline > -1)
11889 z_file[channel]->z_nline++;
11890 #else
11891 #ifdef COMMENT2
11892 /* Straightforward but strlen() slows it down. */
11893 s[0] = '\0';
11894 i = 0;
11895 if (fgets(s,length,t)) {
11896 i = strlen(s);
11897 if (i > 0 && s[i-1] == '\n') i--;
11898 }
11899 debug(F111,"z_in line fgets",ckitoa(errno),i);
11900 if (z_file[channel]->z_nline > -1)
11901 z_file[channel]->z_nline++;
11902 #else
11903 /* This is a do-it-yourself fgets() with its own readahead and */
11904 /* putback. It's a bit faster than real fgets() but not enough */
11905 /* to justify the added complexity or the risk of the ftell() and */
11906 /* fseek() calls failing. */
11907 int k, flag = 0;
11908 CK_OFF_T pos;
11909 for (i = 0; !flag && i <= (length - Z_INBUFLEN); i += Z_INBUFLEN) {
11910 k = ((length - i) < Z_INBUFLEN) ? length - i : Z_INBUFLEN;
11911 if ((x = fread(s+i,1,k,t)) < 1)
11912 break;
11913 s[i+x] = '\0';
11914 for (j = 0; j < x; j++) {
11915 if (s[i+j] == '\n') {
11916 s[i+j] = '\0';
11917 flag ++;
11918 pos = CKFTELL(t);
11919 if (pos > -1) {
11920 pos -= (x - j - 1);
11921 x = CKFSEEK(t, pos, 0);
11922 i += j;
11923 break;
11924 } else
11925 return(z_error = FX_SYS);
11926 }
11927 }
11928 }
11929 if (z_file[channel]->z_nline > -1)
11930 z_file[channel]->z_nline++;
11931 debug(F111,"z_in line chunk loop",ckitoa(errno),i);
11932 #endif /* COMMENT2 */
11933 #endif /* COMMENT */
11934 }
11935 debug(F111,"z_in i",ckitoa(errno),i);
11936 if (i < 0) i = 0; /* NUL-terminate result */
11937 s[i] = '\0';
11938 if (i > 0) {
11939 z_error = 0;
11940 return(i);
11941 }
11942 if (i == 0 && feof(t)) /* EOF on reading? */
11943 return(z_error = FX_EOF); /* Return EOF code */
11944 return(errno ? (z_error = -1) : i); /* Return length or system error */
11945 }
11946
11947 int
z_flush(channel)11948 z_flush(channel) int channel; { /* Flush output channel */
11949 FILE * t;
11950 int x;
11951 if (!z_inited) /* Regular checks */
11952 return(z_error = FX_NOP);
11953 if (channel >= z_maxchan)
11954 return(z_error = FX_CHN);
11955 if (!z_file[channel])
11956 return(z_error = FX_NOP);
11957 if (!(t = z_file[channel]->z_fp))
11958 return(z_error = FX_NOP);
11959 if (!((z_file[channel]->z_flags) & (FM_WRI|FM_APP))) /* Write access? */
11960 return(z_error = FX_FOP);
11961 errno = 0; /* Reset errno */
11962 x = fflush(t); /* Try to flush */
11963 return(x ? (z_error = FX_SYS) : 0); /* Return system error or 0 if OK */
11964 }
11965
11966 int
11967 #ifdef CK_ANSIC
z_seek(int channel,CK_OFF_T pos)11968 z_seek(int channel, CK_OFF_T pos) /* Move file pointer to byte */
11969 #else
11970 z_seek(channel,pos) int channel; CK_OFF_T pos; /* (seek to given position) */
11971 #endif /* CK_ANSIC */
11972 {
11973 int i, x = 0, rc;
11974 FILE * t;
11975 if (!z_inited) /* Check... */
11976 return(z_error = FX_NOP);
11977 if (channel >= z_maxchan)
11978 return(z_error = FX_CHN);
11979 if (!z_file[channel])
11980 return(z_error = FX_NOP);
11981 if (!(t = z_file[channel]->z_fp))
11982 return(z_error = FX_NOP);
11983 if (pos < 0L) {
11984 x = 2;
11985 pos = (pos == -2) ? -1L : 0L;
11986 }
11987 errno = 0;
11988 rc = CKFSEEK(t,pos,x); /* Try to seek */
11989 debug(F111,"z_seek",ckitoa(errno),rc);
11990 if (rc < 0) /* OK? */
11991 return(z_error = FX_SYS); /* No. */
11992 z_file[channel]->z_nline = ((pos || x) ? -1 : 0);
11993 return(z_error = 0);
11994 }
11995
11996 int
11997 #ifdef CK_ANSIC
z_line(int channel,CK_OFF_T pos)11998 z_line(int channel, CK_OFF_T pos) /* Move file pointer to line */
11999 #else
12000 z_line(channel,pos) int channel; CK_OFF_T pos; /* (seek to given position) */
12001 #endif /* CK_ANSIC */
12002 {
12003 int i, len, x = 0;
12004 CK_OFF_T current = (CK_OFF_T)0, prev = (CK_OFF_T)-1, old = (CK_OFF_T)-1;
12005 FILE * t;
12006 char tmpbuf[256];
12007 if (!z_inited) /* Check... */
12008 return(z_error = FX_NOP);
12009 if (channel >= z_maxchan)
12010 return(z_error = FX_CHN);
12011 if (!z_file[channel])
12012 return(z_error = FX_NOP);
12013 if (!(t = z_file[channel]->z_fp))
12014 return(z_error = FX_NOP);
12015 debug(F101,"z_line pos","",pos);
12016 if (pos < 0L) { /* EOF wanted */
12017 CK_OFF_T n;
12018 n = z_file[channel]->z_nline;
12019 debug(F101,"z_line n","",n);
12020 if (n < 0 || pos < 0) {
12021 rewind(t);
12022 n = 0;
12023 }
12024 while (1) { /* This could take a while... */
12025 if ((x = getc(t)) == EOF)
12026 break;
12027 if (x == '\n') {
12028 n++;
12029 if (pos == -2) {
12030 old = prev;
12031 prev = CKFTELL(t);
12032 }
12033 }
12034 }
12035 debug(F101,"z_line old","",old);
12036 debug(F101,"z_line prev","",prev);
12037 if (pos == -2) {
12038 if ((x = z_seek(channel,old)) < 0)
12039 return(z_error = x);
12040 else
12041 n--;
12042 }
12043 z_file[channel]->z_nline = n;
12044 return(z_error = 0);
12045 }
12046 if (pos == 0L) { /* Rewind wanted */
12047 z_file[channel]->z_nline = 0L;
12048 rewind(t);
12049 debug(F100,"z_line rewind","",0);
12050 return(0L);
12051 }
12052 tmpbuf[255] = NUL; /* Make sure buf is NUL terminated */
12053 current = z_file[channel]->z_nline; /* Current line */
12054 /*
12055 If necessary the following could be optimized, e.g. for positioning
12056 to a previous line in a large file without starting over.
12057 */
12058 if (current < 0 || pos < current) { /* Not known or behind us... */
12059 debug(F101,"z_line rewinding","",pos);
12060 if ((x = z_seek(channel, 0L)) < 0) /* Rewind */
12061 return(z_error = x);
12062 if (pos == 0) /* If 0th line wanted we're done */
12063 return(z_error = 0);
12064 current = 0;
12065 }
12066 while (current < pos) { /* Search for specified line */
12067 if (fgets(tmpbuf,255,t)) {
12068 len = strlen(tmpbuf);
12069 if (len > 0 && tmpbuf[len-1] == '\n') {
12070 current++;
12071 debug(F111,"z_line read",ckitoa(len),current);
12072 } else if (len == 0) {
12073 return(z_error = FX_UNK);
12074 }
12075 } else {
12076 z_file[channel]->z_nline = -1L;
12077 debug(F101,"z_line premature EOF","",current);
12078 return(z_error = FX_EOF);
12079 }
12080 }
12081 z_file[channel]->z_nline = current;
12082 debug(F101,"z_line result","",current);
12083 z_error = 0;
12084 return(current);
12085 }
12086
12087 char *
z_getname(channel)12088 z_getname(channel) int channel; { /* Return name of file on channel */
12089 FILE * t;
12090 if (!z_inited) {
12091 z_error = FX_NOP;
12092 return(NULL);
12093 }
12094 if (channel >= z_maxchan) {
12095 z_error = FX_CHN;
12096 return(NULL);
12097 }
12098 if (!z_file[channel]) {
12099 z_error = FX_NOP;
12100 return(NULL);
12101 }
12102 if (!(t = z_file[channel]->z_fp)) {
12103 z_error = FX_NOP;
12104 return(NULL);
12105 }
12106 return((char *)(z_file[channel]->z_name));
12107 }
12108
12109 int
z_getmode(channel)12110 z_getmode(channel) int channel; { /* Return OPEN modes of channel */
12111 FILE * t; /* 0 if file not open */
12112 #ifndef NOSTAT
12113 #ifdef NT
12114 struct _stat statbuf;
12115 #else /* NT */
12116 struct stat statbuf;
12117 #endif /* NT */
12118 #endif /* NOSTAT */
12119 int x;
12120 if (!z_inited)
12121 return(0);
12122 if (channel >= z_maxchan)
12123 return(z_error = FX_CHN);
12124 if (!z_file[channel])
12125 return(0);
12126 if (!(t = z_file[channel]->z_fp))
12127 return(0);
12128 x = z_file[channel]->z_flags;
12129 if (feof(t)) { /* This might not work for */
12130 x |= FM_EOF; /* output files */
12131 #ifndef NOSTAT
12132 /* But this does if we can use it. */
12133 } else if (stat(z_file[channel]->z_name,&statbuf) > -1) {
12134 if (CKFTELL(t) == statbuf.st_size)
12135 x |= FM_EOF;
12136 #endif /* NOSTAT */
12137 }
12138 return(x);
12139 }
12140
12141 CK_OFF_T
z_getpos(channel)12142 z_getpos(channel) int channel; { /* Get file pointer position */
12143 FILE * t; /* on this channel */
12144 CK_OFF_T x;
12145 if (!z_inited)
12146 return(z_error = FX_NOP);
12147 if (channel >= z_maxchan)
12148 return(z_error = FX_CHN);
12149 if (!z_file[channel])
12150 return(z_error = FX_NOP);
12151 if (!(t = z_file[channel]->z_fp))
12152 return(z_error = FX_NOP);
12153 x = CKFTELL(t);
12154 return((x < 0L) ? (z_error = FX_SYS) : x);
12155 }
12156
12157 CK_OFF_T
z_getline(channel)12158 z_getline(channel) int channel; { /* Get current line number */
12159 FILE * t; /* in file on this channel */
12160 CK_OFF_T rc;
12161 if (!z_inited)
12162 return(z_error = FX_NOP);
12163 if (channel >= z_maxchan)
12164 return(z_error = FX_CHN);
12165 if (!z_file[channel])
12166 return(z_error = FX_NOP);
12167 if (!(t = z_file[channel]->z_fp))
12168 return(z_error = FX_NOP);
12169 debug(F101,"z_getline","",z_file[channel]->z_nline);
12170 rc = z_file[channel]->z_nline;
12171 return((rc < 0) ? (z_error = FX_LNU) : rc);
12172 }
12173
12174 int
z_getfnum(channel)12175 z_getfnum(channel) int channel; { /* Get file number / handle */
12176 FILE * t; /* for file on this channel */
12177 if (!z_inited)
12178 return(z_error = FX_NOP);
12179 if (channel >= z_maxchan)
12180 return(z_error = FX_CHN);
12181 if (!z_file[channel])
12182 return(z_error = FX_NOP);
12183 if (!(t = z_file[channel]->z_fp))
12184 return(z_error = FX_NOP);
12185 z_error = 0;
12186 return(fileno(t));
12187 }
12188
12189 /*
12190 Line-oriented counts and seeks are as dumb as they can be at the moment.
12191 Later we can speed them up by building little indexes.
12192 */
12193 CK_OFF_T
z_count(channel,what)12194 z_count(channel, what) int channel, what; { /* Count bytes or lines in file */
12195 FILE * t;
12196 int i, x;
12197 CK_OFF_T pos, count = (CK_OFF_T)0;
12198 if (!z_inited) /* Check stuff... */
12199 return(z_error = FX_NOP);
12200 if (channel >= z_maxchan)
12201 return(z_error = FX_CHN);
12202 if (!z_file[channel])
12203 return(z_error = FX_NOP);
12204 if (!(t = z_file[channel]->z_fp))
12205 return(z_error = FX_NOP);
12206 pos = CKFTELL(t); /* Save current file pointer */
12207 errno = 0;
12208 z_error = 0;
12209 if (what == RD_CHAR) { /* Size in bytes requested */
12210 #ifdef COMMENT
12211 if (!CKFSEEK(t,0L,2)) { /* Seek to end */
12212 count = CKFTELL(t); /* Get file pointer */
12213 CKFSEEK(t,pos,0); /* Restore file file pointer */
12214 return(count);
12215 } else /* Fallback in case seek fails */
12216 #endif /* COMMENT */
12217 return(zgetfs(z_file[channel]->z_name));
12218 }
12219 rewind(t); /* Line count requested - rewind. */
12220 while (1) { /* Count lines. */
12221 if ((x = getc(t)) == EOF) /* Stupid byte loop */
12222 break; /* but it works as well as anything */
12223 if (x == '\n') /* else... */
12224 count++;
12225 }
12226 x = CKFSEEK(t,pos,0); /* Restore file pointer */
12227 return(count);
12228 }
12229
12230 /* User interface for generalized channel-oriented file i/o */
12231
12232 struct keytab fctab[] = { /* FILE subcommands */
12233 { "close", FIL_CLS, 0 },
12234 { "count", FIL_COU, 0 },
12235 { "flush", FIL_FLU, 0 },
12236 { "list", FIL_LIS, 0 },
12237 { "open", FIL_OPN, 0 },
12238 { "read", FIL_REA, 0 },
12239 { "rewind", FIL_REW, 0 },
12240 { "seek", FIL_SEE, 0 },
12241 { "status", FIL_STA, 0 },
12242 { "write", FIL_WRI, 0 }
12243 };
12244 int nfctab = (sizeof (fctab) / sizeof (struct keytab));
12245
12246 static struct keytab fcswtab[] = { /* OPEN modes */
12247 { "/append", FM_APP, 0 },
12248 { "/binary", FM_BIN, 0 },
12249 #ifdef COMMENT
12250 { "/command", FM_CMD, 0 }, /* Not implemented */
12251 #endif /* COMMENT */
12252 { "/read", FM_REA, 0 },
12253 #ifdef UNIX /* Could be expanded to VMS etc.. */
12254 { "/stderr", FM_STDERR,0 },
12255 { "/stdin", FM_STDIN,0 },
12256 { "/stdout", FM_STDOUT,0 },
12257 #endif /* UNIX */
12258 { "/write", FM_WRI, 0 }
12259 };
12260 static int nfcswtab = (sizeof (fcswtab) / sizeof (struct keytab));
12261
12262 static struct keytab fclkwtab[] = { /* CLOSE options */
12263 { "all", 1, 0 }
12264 };
12265
12266 static struct keytab fsekwtab[] = { /* SEEK symbols */
12267 { "eof", 1, 0 },
12268 { "last", 2, 0 }
12269 };
12270 static int nfsekwtab = (sizeof (fsekwtab) / sizeof (struct keytab));
12271
12272 #define SEE_LINE RD_LINE /* SEEK options */
12273 #define SEE_CHAR RD_CHAR
12274 #define SEE_REL 3
12275 #define SEE_ABS 4
12276 #define SEE_FIND 5
12277
12278 static struct keytab fskswtab[] = {
12279 { "/absolute", SEE_ABS, 0 },
12280 { "/byte", SEE_CHAR, 0 },
12281 { "/character", SEE_CHAR, CM_INV },
12282 { "/find", SEE_FIND, CM_ARG },
12283 { "/line", SEE_LINE, 0 },
12284 { "/relative", SEE_REL, 0 }
12285 };
12286 static int nfskswtab = (sizeof (fskswtab) / sizeof (struct keytab));
12287
12288 #define COU_LINE RD_LINE /* COUNT options */
12289 #define COU_CHAR RD_CHAR
12290 #define COU_LIS 3
12291 #define COU_NOL 4
12292
12293 static struct keytab fcoswtab[] = {
12294 { "/bytes", COU_CHAR, 0 },
12295 { "/characters",COU_CHAR, CM_INV },
12296 { "/lines", COU_LINE, 0 },
12297 { "/list", COU_LIS, 0 },
12298 { "/nolist", COU_NOL, 0 },
12299 { "/quiet", COU_NOL, CM_INV }
12300 };
12301 static int nfcoswtab = (sizeof (fcoswtab) / sizeof (struct keytab));
12302
12303 static struct keytab frdtab[] = { /* READ types */
12304 { "/block", RD_SIZE, CM_INV|CM_ARG },
12305 { "/byte", RD_CHAR, CM_INV },
12306 { "/character", RD_CHAR, 0 },
12307 { "/line", RD_LINE, 0 },
12308 { "/size", RD_SIZE, CM_ARG },
12309 { "/trim", RD_TRIM, 0 },
12310 { "/untabify", RD_UNTA, 0 }
12311 };
12312 static int nfrdtab = (sizeof (frdtab) / sizeof (struct keytab));
12313
12314 static struct keytab fwrtab[] = { /* WRITE types */
12315 { "/block", WR_SIZE, CM_INV|CM_ARG },
12316 { "/byte", WR_CHAR, CM_INV },
12317 { "/character", WR_CHAR, 0 },
12318 { "/line", WR_LINE, 0 },
12319 { "/lpad", WR_LPAD, CM_ARG },
12320 { "/rpad", WR_RPAD, CM_ARG },
12321 { "/size", WR_SIZE, CM_ARG },
12322 { "/string", WR_STRI, 0 }
12323 };
12324 static int nfwrtab = (sizeof (fwrtab) / sizeof (struct keytab));
12325
12326 static char blanks[] = "\040\040\040\040"; /* Some blanks for formatting */
12327 static char * seek_target = NULL;
12328
12329 int
dofile(op)12330 dofile(op) int op; { /* Do the FILE command */
12331 char vnambuf[VNAML]; /* Buffer for variable names */
12332 char *vnp = NULL; /* Pointer to same */
12333 char zfilnam[CKMAXPATH+2];
12334 char * p, * m;
12335 struct FDB fl, sw, nu;
12336 CK_OFF_T z;
12337 int rsize, filmode = 0, relative = -1, eofflg = 0;
12338 int rc, x, y, cx, n, getval, dummy, confirmed, listing = -1;
12339 int charflag = 0, sizeflag = 0;
12340 int pad = 32, wr_lpad = 0, wr_rpad = 0, rd_trim = 0, rd_untab = 0;
12341
12342 makestr(&seek_target,NULL);
12343
12344 if (op == XXFILE) { /* FILE command was given */
12345 /* Get subcommand */
12346 if ((cx = cmkey(fctab,nfctab,"Operation","",xxstring)) < 0) {
12347 if (cx == -3) {
12348 printf("?File operation required\n");
12349 x = -9;
12350 }
12351 return(cx);
12352 }
12353 } else { /* Shorthand command was given */
12354 switch (op) {
12355 case XXF_CL: cx = FIL_CLS; break; /* FCLOSE */
12356 case XXF_FL: cx = FIL_FLU; break; /* FFLUSH */
12357 case XXF_LI: cx = FIL_LIS; break; /* FLIST */
12358 case XXF_OP: cx = FIL_OPN; break; /* etc... */
12359 case XXF_RE: cx = FIL_REA; break;
12360 case XXF_RW: cx = FIL_REW; break;
12361 case XXF_SE: cx = FIL_SEE; break;
12362 case XXF_ST: cx = FIL_STA; break;
12363 case XXF_WR: cx = FIL_WRI; break;
12364 case XXF_CO: cx = FIL_COU; break;
12365 default: return(-2);
12366 }
12367 }
12368 switch (cx) { /* Do requested subcommand */
12369 case FIL_OPN: /* OPEN */
12370 cmfdbi(&sw, /* Switches */
12371 _CMKEY, /* fcode */
12372 "Variable or switch", /* hlpmsg */
12373 "", /* default */
12374 "", /* addtl string data */
12375 nfcswtab, /* addtl numeric data 1: tbl size */
12376 4, /* addtl numeric data 2: 4 = cmswi */
12377 xxstring, /* Processing function */
12378 fcswtab, /* Keyword table */
12379 &fl /* Pointer to next FDB */
12380 );
12381 cmfdbi(&fl, /* Anything that doesn't match */
12382 _CMFLD, /* fcode */
12383 "Variable", /* hlpmsg */
12384 "",
12385 "",
12386 0,
12387 0,
12388 NULL,
12389 NULL,
12390 NULL
12391 );
12392 while (1) {
12393 x = cmfdb(&sw); /* Parse something */
12394 if (x < 0) {
12395 if (x == -3) {
12396 printf("?Variable name and file name required\n");
12397 x = -9;
12398 }
12399 return(x);
12400 }
12401 if (cmresult.fcode == _CMFLD)
12402 break;
12403 else if (cmresult.fcode == _CMKEY) {
12404 char c;
12405 c = cmgbrk();
12406 if ((getval =
12407 (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
12408 printf("?This switch does not take an argument\n");
12409 return(-9);
12410 }
12411 #ifdef COMMENT
12412 /* Uncomment if we add any FOPEN switches that take args */
12413 if (!getval && (cmgkwflgs() & CM_ARG)) {
12414 printf("?This switch requires an argument\n");
12415 return(-9); /* (none do...) */
12416 }
12417 #endif /* COMMENT */
12418 debug(F101,"filmode A","",filmode);
12419 filmode |= cmresult.nresult; /* OR in the file mode */
12420 debug(F101,"filmode B","",filmode);
12421 debug(F101,"filmode & (FM_REA|FM_STDIN)","",
12422 filmode & (FM_REA|FM_STDIN));
12423 debug(F101,"filmode & (FM_WRI|FM_STDOUT|FM_STDERR)","",
12424 filmode & (FM_WRI|FM_STDOUT|FM_STDERR));
12425 if ((filmode & (FM_REA|FM_STDIN)) &&
12426 (filmode & (FM_WRI|FM_STDOUT|FM_STDERR))) {
12427 printf("?Conflicting file modes\n");
12428 return(-9);
12429 }
12430 } else
12431 return(-2);
12432 }
12433 /* Not a switch - get the string */
12434 ckstrncpy(vnambuf,cmresult.sresult,VNAML);
12435 if (!vnambuf[0] || chknum(vnambuf)) { /* (if there is one...) */
12436 printf("?Variable name required\n");
12437 return(-9);
12438 }
12439 vnp = vnambuf; /* Check variable-name syntax */
12440 if (vnambuf[0] == CMDQ &&
12441 (vnambuf[1] == '%' || vnambuf[1] == '&'))
12442 vnp++;
12443 y = 0;
12444 if (*vnp == '%' || *vnp == '&') {
12445 if ((y = parsevar(vnp,&x,&dummy)) < 0) {
12446 printf("?Syntax error in variable name\n");
12447 return(-9);
12448 }
12449 }
12450 /* Assign a negative channel number in case we fail */
12451 addmac(vnambuf,"-1");
12452
12453 if (!(filmode & FM_RWA)) /* If no access mode specified */
12454 filmode |= FM_REA; /* default to /READ. */
12455
12456 #ifdef UNIX
12457 if (filmode & FM_STDIN) { /* If STDIN specified */
12458 filmode |= FM_REA; /* it implies /READ */
12459 /* We don't need to parse anything further */
12460 s = "(stdin)";
12461 goto xdofile; /* Skip around the following */
12462 }
12463 if (filmode & FM_STDOUT) { /* If STDIN specified */
12464 filmode |= FM_WRI; /* it implies /WRITE */
12465 /* We don't need to parse anything further */
12466 s = "(stdout)";
12467 goto xdofile; /* Skip around the following */
12468 }
12469 if (filmode & FM_STDIN) { /* If STDIN specified */
12470 filmode |= FM_WRI; /* it implies /WRITE */
12471 /* We don't need to parse anything further */
12472 s = "(stderr)";
12473 goto xdofile; /* Skip around the following */
12474 }
12475 #endif /* UNIX */
12476 y = 0; /* Now parse the filename */
12477 if ((filmode & FM_RWA) == FM_WRI) {
12478 x = cmofi("Name of new file","",&s,xxstring);
12479 } else if ((filmode & FM_RWA) == FM_REA) {
12480 x = cmifi("Name of existing file","",&s,&y,xxstring);
12481 } else {
12482 x = cmiofi("Filename","",&s,&y,xxstring);
12483 debug(F111,"fopen /append x",s,x);
12484 }
12485 if (x < 0) {
12486 if (x == -3) {
12487 printf("?Filename required\n");
12488 x = -9;
12489 }
12490 return(x);
12491 }
12492 if (y) { /* No wildcards */
12493 printf("?Wildcards not allowed here\n");
12494 return(-9);
12495 }
12496 if (filmode & (FM_APP|FM_WRI)) { /* Check output access */
12497 #ifndef VMS
12498 if (zchko(s) < 0) { /* and set error code if denied */
12499 z_error = FX_ACC;
12500 printf("?Write access denied - \"%s\"\n",s);
12501 return(-9);
12502 }
12503 #endif /* VMS */
12504 }
12505
12506 xdofile:
12507 ckstrncpy(zfilnam,s,CKMAXPATH); /* Is OK - make safe copy */
12508 if ((x = cmcfm()) < 0) /* Get confirmation of command */
12509 return(x);
12510 if ((n = z_open(zfilnam,filmode)) < 0) {
12511 printf("?OPEN failed - %s: %s\n",zfilnam,ckferror(n));
12512 return(-9);
12513 }
12514 addmac(vnambuf,ckitoa(n)); /* Assign channel number to variable */
12515 return(success = 1);
12516
12517 case FIL_REW: /* REWIND */
12518 if ((x = cmnum("Channel number","",10,&n, xxstring)) < 0) {
12519 if (x == -3) {
12520 printf("?Channel number required\n");
12521 x = -9;
12522 }
12523 return(x);
12524 }
12525 if ((x = cmcfm()) < 0)
12526 return(x);
12527 if (n == -9) return(success = 0);
12528 if (n == -8) return(success = 1);
12529
12530 if ((rc = z_seek(n,0L)) < 0) {
12531 printf("?REWIND failed - Channel %d: %s\n",n,ckferror(rc));
12532 return(-9);
12533 }
12534 return(success = 1);
12535
12536 case FIL_CLS: /* CLOSE */
12537 #ifdef COMMENT /* fdc 20100804 - bad idea */
12538 {
12539 int i, j, k; /* Supply default if only one open */
12540 s = "";
12541 for (k = 0, j = 0, i = 0; i < z_maxchan; i++) {
12542 if (z_file)
12543 if (z_file[i])
12544 if (z_file[i]->z_fp) { k++; j = i; }
12545 }
12546 if (k == 1) s = ckitoa(j);
12547 }
12548 #endif /* COMMENT */
12549 cmfdbi(&nu, /* Second FDB - channel number */
12550 _CMNUM, /* fcode */
12551 "Channel number or ALL", /* Help message */
12552 s, /* default */
12553 "", /* addtl string data */
12554 10, /* addtl numeric data 1: radix */
12555 0, /* addtl numeric data 2: 0 */
12556 xxstring, /* Processing function */
12557 NULL, /* Keyword table */
12558 &sw /* Pointer to next FDB */
12559 ); /* Pointer to next FDB */
12560 cmfdbi(&sw, /* First FDB - command switches */
12561 _CMKEY, /* fcode */
12562 "", /* help message */
12563 "", /* Default */
12564 "", /* No addtl string data */
12565 1, /* addtl numeric data 1: tbl size */
12566 0, /* addtl numeric data 2: 4 = cmswi */
12567 xxstring, /* Processing function */
12568 fclkwtab, /* Keyword table */
12569 NULL /* Last in chain */
12570 );
12571 x = cmfdb(&nu); /* Parse something */
12572 if (x < 0) {
12573 if (x == -3) {
12574 printf("?Channel number or ALL required\n");
12575 x = -9;
12576 }
12577 return(x);
12578 }
12579 if (cmresult.fcode == _CMNUM)
12580 n = cmresult.nresult;
12581 else if (cmresult.fcode == _CMKEY)
12582 n = -1;
12583 if ((x = cmcfm()) < 0)
12584 return(x);
12585 if (n == -9) return(success = 0);
12586 if (n == -8) return(success = 1);
12587
12588 rc = 1;
12589 if (n < 0) {
12590 int count = 0;
12591 int i;
12592 for (i = 0; i < z_maxchan; i++) {
12593 x = z_close(i);
12594 if (x == FX_SYS) {
12595 printf("?CLOSE failed - Channel %d: %s\n",n,ckferror(x));
12596 rc = 0;
12597 } else if (x > -1)
12598 count++;
12599 }
12600 debug(F101,"FILE CLOSE ALL","",count);
12601 } else if ((x = z_close(n)) < 0) {
12602 printf("?CLOSE failed - Channel %d: %s\n",n,ckferror(x));
12603 return(-9);
12604 }
12605 return(success = rc);
12606
12607 case FIL_REA: /* READ */
12608 case FIL_WRI: /* WRITE */
12609 rsize = 0;
12610 cmfdbi(&sw, /* Switches */
12611 _CMKEY, /* fcode */
12612 "Channel or switch", /* hlpmsg */
12613 "", /* default */
12614 "", /* addtl string data */
12615 (cx == FIL_REA) ? nfrdtab : nfwrtab,
12616 4, /* addtl numeric data 2: 4 = cmswi */
12617 xxstring, /* Processing function */
12618 (cx == FIL_REA) ? frdtab : fwrtab, /* Keyword table */
12619 &nu /* Pointer to next FDB */
12620 );
12621 cmfdbi(&nu, /* Channel number */
12622 _CMNUM, /* fcode */
12623 "Channel",
12624 "", /* default */
12625 "", /* addtl string data */
12626 10, /* addtl numeric data 1: radix */
12627 0, /* addtl numeric data 2: 0 */
12628 xxstring, /* Processing function */
12629 NULL, /* Keyword table */
12630 NULL /* Pointer to next FDB */
12631 );
12632 do {
12633 x = cmfdb(&sw); /* Parse something */
12634 if (x < 0) {
12635 if (x == -3) {
12636 printf("?Channel number required\n");
12637 x = -9;
12638 }
12639 return(x);
12640 }
12641 if (cmresult.fcode == _CMNUM) /* Channel number */
12642 break;
12643 else if (cmresult.fcode == _CMKEY) { /* Switch */
12644 char c;
12645 c = cmgbrk();
12646 if ((getval =
12647 (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
12648 printf("?This switch does not take an argument\n");
12649 return(-9);
12650 }
12651 if (!getval && (cmgkwflgs() & CM_ARG)) {
12652 printf("?This switch requires an argument\n");
12653 return(-9);
12654 }
12655 switch (cmresult.nresult) {
12656 case WR_LINE:
12657 charflag = 0;
12658 sizeflag = 0;
12659 rsize = 0;
12660 break;
12661 case WR_CHAR:
12662 rsize = 1;
12663 charflag = 1;
12664 sizeflag = 1;
12665 break;
12666 case WR_SIZE:
12667 if ((x = cmnum("Bytes","",10,&rsize, xxstring)) < 0) {
12668 if (x == -3) {
12669 printf("?Number required\n");
12670 x = -9;
12671 }
12672 return(x);
12673 }
12674 if (rsize > LINBUFSIZ) {
12675 printf("?Maximum FREAD/FWRITE size is %d\n",LINBUFSIZ);
12676 rsize = 0;
12677 return(-9);
12678 }
12679 charflag = 0;
12680 sizeflag = 1;
12681 break;
12682 case WR_STRI:
12683 rsize = 1;
12684 charflag = 0;
12685 sizeflag = 0;
12686 break;
12687 case WR_LPAD:
12688 case WR_RPAD:
12689 if ((x = cmnum("Numeric ASCII character value",
12690 "32",10,&pad, xxstring)) < 0)
12691 return(x);
12692 if (cmresult.nresult == WR_LPAD)
12693 wr_lpad = 1;
12694 else
12695 wr_rpad = 1;
12696 break;
12697 case RD_TRIM:
12698 rd_trim = 1;
12699 break;
12700 case RD_UNTA:
12701 rd_untab = 1;
12702 break;
12703 }
12704 debug(F101,"FILE READ rsize 2","",rsize);
12705 } else
12706 return(-2);
12707 } while
12708 (cmresult.fcode == _CMKEY);
12709
12710 n = cmresult.nresult; /* Channel */
12711 debug(F101,"FILE READ/WRITE channel","",n);
12712
12713 if (cx == FIL_WRI) { /* WRITE */
12714 int len = 0;
12715 if ((x = cmtxt("Text","",&s,xxstring)) < 0)
12716 return(x);
12717 if (n == -9) return(success = 0);
12718 if (n == -8) return(success = 1);
12719
12720 ckstrncpy(line,s,LINBUFSIZ); /* Make a safe copy */
12721 s = line;
12722 s = brstrip(s); /* Strip braces */
12723 if (charflag) { /* Write one char */
12724 len = 1; /* So length = 1 */
12725 rsize = 1; /* Don't supply terminator */
12726 } else if (!sizeflag) { /* Write a string */
12727 len = -1; /* So length is unspecified */
12728 } else { /* Write a block of given size */
12729 int i, k, xx;
12730 if (rsize > TMPBUFSIZ) {
12731 z_error = FX_OFL;
12732 printf("?Buffer overflow\n");
12733 return(-9);
12734 }
12735 len = rsize; /* rsize is really length */
12736 rsize = 1; /* Don't supply a terminator */
12737 xx = strlen(s); /* Size of given string */
12738 if (xx >= len) { /* Bigger or equal */
12739 s[len] = NUL;
12740 } else if (wr_lpad) { /* Smaller, left-padding requested */
12741 for (i = 0; i < len - xx; i++) /* Must make a copy */
12742 tmpbuf[i] = pad;
12743 ckstrncpy(tmpbuf+i,s,TMPBUFSIZ-i);
12744 tmpbuf[len] = NUL;
12745 s = tmpbuf; /* Redirect write source */
12746 } else if (wr_rpad) { /* Smaller with right-padding */
12747 for (i = xx; i < len; i++)
12748 s[i] = pad;
12749 s[len] = NUL;
12750 }
12751 }
12752 if ((rc = z_out(n,s,len,rsize)) < 0) { /* Try to write */
12753 printf("?Channel %d WRITE error: %s\n",n,ckferror(rc));
12754 return(-9);
12755 }
12756 } else { /* FIL_REA READ */
12757 confirmed = 0;
12758 vnambuf[0] = NUL;
12759 x = cmfld("Variable name","",&s,NULL);
12760 debug(F111,"FILE READ cmfld",s,x);
12761 if (x < 0) {
12762 if (x == -3 || !*s) {
12763 if ((x = cmcfm()) < 0)
12764 return(x);
12765 else
12766 confirmed++;
12767 } else
12768 return(x);
12769 }
12770 ckstrncpy(vnambuf,s,VNAML);
12771 debug(F111,"FILE READ vnambuf",vnambuf,confirmed);
12772 if (vnambuf[0]) { /* Variable name given, check it */
12773 if (!confirmed) {
12774 x = cmcfm();
12775 if (x < 0)
12776 return(x);
12777 else
12778 confirmed++;
12779 }
12780 vnp = vnambuf;
12781 if (vnambuf[0] == CMDQ &&
12782 (vnambuf[1] == '%' || vnambuf[1] == '&'))
12783 vnp++;
12784 y = 0;
12785 if (*vnp == '%' || *vnp == '&') {
12786 if ((y = parsevar(vnp,&x,&dummy)) < 0) {
12787 printf("?Syntax error in variable name\n");
12788 return(-9);
12789 }
12790 }
12791 }
12792 debug(F111,"FILE READ variable",vnambuf,confirmed);
12793
12794 if (!confirmed)
12795 if ((x = cmcfm()) < 0)
12796 return(x);
12797
12798 if (n == -9) return(success = 0);
12799 if (n == -8) return(success = 1);
12800
12801 line[0] = NUL; /* Clear destination buffer */
12802 #ifdef COMMENT
12803 if (rsize >= LINBUFSIZ) /* Don't overrun it */
12804 rsize = LINBUFSIZ - 1;
12805 #endif /* COMMENT */
12806
12807 if (rsize == 0) { /* Read a line */
12808 rc = z_in(n,line,LINBUFSIZ,LINBUFSIZ-1,0);
12809 } else {
12810 rc = z_in(n,line,LINBUFSIZ,rsize,1); /* Read a block */
12811 }
12812 if (rc < 0) { /* Error... */
12813 debug(F101,"FILE READ error","",rc);
12814 debug(F101,"FILE READ errno","",errno);
12815 if (rc == FX_EOF) { /* EOF - fail but no error message */
12816 return(success = 0);
12817 } else { /* Other error - fail and print msg */
12818 printf("?READ error: %s\n",ckferror(rc));
12819 return(-9);
12820 }
12821 }
12822 if (rsize == 0) { /* FREAD /LINE postprocessing */
12823 if (rd_trim) { /* Trim */
12824 int i, k;
12825 k = strlen(line);
12826 if (k > 0) {
12827 for (i = k-1; i > 0; i--) {
12828 if (line[i] == SP || line[i] == '\t')
12829 line[i] = NUL;
12830 else
12831 break;
12832 }
12833 }
12834 }
12835 if (rd_untab) { /* Untabify */
12836 if (untabify(line,tmpbuf,TMPBUFSIZ) > -1)
12837 ckstrncpy(line,tmpbuf,LINBUFSIZ);
12838 }
12839 }
12840 debug(F110,"FILE READ data",line,0);
12841 if (vnambuf[0]) /* Read OK - If variable name given */
12842 addmac(vnambuf,line); /* Assign result to variable */
12843 else /* otherwise */
12844 printf("%s\n",line); /* just print it */
12845 }
12846 return(success = 1);
12847
12848 case FIL_SEE: /* SEEK */
12849 case FIL_COU: /* COUNT */
12850 rsize = RD_CHAR; /* Defaults to /BYTE */
12851 cmfdbi(&sw, /* Switches */
12852 _CMKEY, /* fcode */
12853 "Channel or switch", /* hlpmsg */
12854 "", /* default */
12855 "", /* addtl string data */
12856 ((cx == FIL_SEE) ? nfskswtab : nfcoswtab),
12857 4, /* addtl numeric data 2: 4 = cmswi */
12858 xxstring, /* Processing function */
12859 ((cx == FIL_SEE) ? fskswtab : fcoswtab),
12860 &nu /* Pointer to next FDB */
12861 );
12862 cmfdbi(&nu, /* Channel number */
12863 _CMNUM, /* fcode */
12864 "Channel",
12865 "", /* default */
12866 "", /* addtl string data */
12867 10, /* addtl numeric data 1: radix */
12868 0, /* addtl numeric data 2: 0 */
12869 xxstring, /* Processing function */
12870 NULL, /* Keyword table */
12871 NULL /* Pointer to next FDB */
12872 );
12873 do {
12874 x = cmfdb(&sw); /* Parse something */
12875 if (x < 0) {
12876 if (x == -3) {
12877 printf("?Channel number required\n");
12878 x = -9;
12879 }
12880 return(x);
12881 }
12882 if (cmresult.fcode == _CMNUM) /* Channel number */
12883 break;
12884 else if (cmresult.fcode == _CMKEY) { /* Switch */
12885 char c;
12886 c = cmgbrk();
12887 if ((getval =
12888 (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
12889 printf("?This switch does not take an argument\n");
12890 return(-9);
12891 }
12892 if (cx == FIL_SEE) {
12893 switch (cmresult.nresult) {
12894 case SEE_REL: relative = 1; break;
12895 case SEE_ABS: relative = 0; break;
12896 case SEE_FIND: {
12897 if (getval) {
12898 y = cmfld("string or pattern","",&s,xxstring);
12899 if (y < 0)
12900 return(y);
12901 makestr(&seek_target,brstrip(s));
12902 break;
12903 }
12904 }
12905 default: rsize = cmresult.nresult;
12906 }
12907 } else if (cx == FIL_COU) {
12908 switch (cmresult.nresult) {
12909 case COU_LIS: listing = 1; break;
12910 case COU_NOL: listing = 0; break;
12911 default: rsize = cmresult.nresult;
12912 }
12913 }
12914 }
12915 } while
12916 (cmresult.fcode == _CMKEY);
12917
12918 n = cmresult.nresult; /* Channel */
12919 debug(F101,"FILE SEEK/COUNT channel","",n);
12920 if (cx == FIL_COU) {
12921 if ((x = cmcfm()) < 0)
12922 return(x);
12923 if (n == -9) return(success = 0);
12924 if (n == -8) return(success = 1);
12925
12926 z_filcount = z_count(n,rsize);
12927 if (z_filcount < 0) {
12928 rc = z_filcount;
12929 printf("?COUNT error: %s\n",ckferror(rc));
12930 return(-9);
12931 }
12932 if (listing < 0)
12933 listing = !xcmdsrc;
12934 if (listing)
12935 printf(" %ld %s%s\n",
12936 z_filcount,
12937 ((rsize == RD_CHAR) ? "byte" : "line"),
12938 ((z_filcount == 1L) ? "" : "s")
12939 );
12940 return(success = (z_filcount > -1) ? 1 : 0);
12941 }
12942 m = (rsize == RD_CHAR) ?
12943 "Number of bytes;\n or keyword" :
12944 "Number of lines;\n or keyword";
12945 cmfdbi(&sw, /* SEEK symbolic targets (EOF) */
12946 _CMKEY, /* fcode */
12947 m,
12948 "",
12949 "", /* addtl string data */
12950 nfsekwtab, /* addtl numeric data 1: table size */
12951 0, /* addtl numeric data 2: 4 = cmswi */
12952 xxstring, /* Processing function */
12953 fsekwtab, /* Keyword table */
12954 &nu /* Pointer to next FDB */
12955 );
12956 cmfdbi(&nu, /* Byte or line number */
12957 _CMNUW, /* fcode */
12958 "",
12959 "", /* default */
12960 "", /* addtl string data */
12961 10, /* addtl numeric data 1: radix */
12962 0, /* addtl numeric data 2: 0 */
12963 xxstring, /* Processing function */
12964 NULL, /* Keyword table */
12965 NULL /* Pointer to next FDB */
12966 );
12967 x = cmfdb(&sw); /* Parse something */
12968 if (x < 0) {
12969 if (x == -3) {
12970 printf("?Channel number or EOF required\n");
12971 x = -9;
12972 }
12973 return(x);
12974 }
12975 if (cmresult.fcode == _CMNUW) {
12976 z = cmresult.wresult;
12977 debug(F110,"FILE SEEK atmbuf",atmbuf,0);
12978 if (relative < 0) {
12979 if (cx == FIL_SEE && (atmbuf[0] == '+' || atmbuf[0] == '-'))
12980 relative = 1;
12981 else
12982 relative = 0;
12983 }
12984 } else if (cmresult.fcode == _CMKEY) {
12985 eofflg = cmresult.nresult;
12986 relative = 0;
12987 y = 0 - eofflg;
12988 }
12989 if ((x = cmcfm()) < 0)
12990 return(x);
12991 if (n == -9) return(success = 0);
12992 if (n == -8) return(success = 1);
12993 y = 1; /* Recycle this */
12994 z_flush(n);
12995 debug(F101,"FILE SEEK relative","",relative);
12996 debug(F101,"FILE SEEK rsize","",rsize);
12997
12998 if (rsize == RD_CHAR) { /* Seek to byte position */
12999 if (relative > 0) {
13000 CK_OFF_T pos;
13001 pos = z_getpos(n);
13002 if (pos < (CK_OFF_T)0) {
13003 rc = pos;
13004 printf("?Relative SEEK failed: %s\n",ckferror(rc));
13005 return(-9);
13006 }
13007 z += pos;
13008 } else {
13009 if (z < 0 && !eofflg) { /* Negative arg but not relative */
13010 y = 0; /* Remember this was bad */
13011 z = 0; /* but substitute 0 */
13012 }
13013 }
13014 debug(F101,"FILE SEEK /CHAR z","",z);
13015 if (z < 0 && !eofflg) {
13016 z_error = FX_RNG;
13017 return(success = 0);
13018 }
13019 if ((rc = z_seek(n,z)) < 0) {
13020 if (rc == FX_EOF) return(success = 0);
13021 printf("?SEEK /BYTE failed - Channel %d: %s\n",n,ckferror(rc));
13022 return(-9);
13023 }
13024 } else { /* Seek to line */
13025 if (relative > 0) {
13026 CK_OFF_T pos;
13027 pos = z_getline(n);
13028 debug(F101,"FILE SEEK /LINE pos","",pos);
13029 if (pos < 0) {
13030 rc = pos;
13031 printf("?Relative SEEK failed: %s\n",ckferror(rc));
13032 return(-9);
13033 }
13034 z += pos;
13035 }
13036 debug(F101,"FILE SEEK /LINE z","",z);
13037 debug(F101,"FILE SEEK /LINE eofflg","",eofflg);
13038 if (z < 0 && !eofflg) {
13039 z_error = FX_RNG;
13040 return(success = 0);
13041 }
13042 if ((rc = z_line(n,z)) < 0) {
13043 if (rc == FX_EOF) return(success = 0);
13044 printf("?SEEK /LINE failed - Channel %d: %s\n",n,ckferror(rc));
13045 return(-9);
13046 }
13047 }
13048 /*
13049 Now, having sought to the desired starting spot, if a /FIND:
13050 target was specified, look for it now.
13051 */
13052 if (seek_target) {
13053 int flag = 0, ispat = 0, matchresult = 0;
13054 while (!flag) {
13055 y = z_in(n,line,LINBUFSIZ,LINBUFSIZ-1,0);
13056 if (y < 0) {
13057 y = 0;
13058 break;
13059 }
13060 if (ispattern(seek_target)) {
13061 matchresult = ckmatch(seek_target,line,inpcas[cmdlvl],1+4);
13062 } else {
13063 /* This is faster */
13064 matchresult = ckindex(seek_target,line,0,0,inpcas[cmdlvl]);
13065 }
13066 if (matchresult) {
13067 flag = 1;
13068 break;
13069 }
13070 }
13071 if (flag) {
13072 debug(F111,"FSEEK HAVE MATCH",seek_target,z_getline(n));
13073 /* Back up to beginning of line where target found */
13074 if ((y = z_line(n,z_getline(n)-1)) < 0) {
13075 if (rc == FX_EOF) return(success = 0);
13076 printf("?SEEK /LINE failed - Channel %d: %s\n",
13077 n,ckferror(rc));
13078 return(-9);
13079 }
13080 debug(F101,"FSEEK LINE","",y);
13081 }
13082 }
13083 return(success = (y < 0) ? 0 : 1);
13084
13085 case FIL_LIS: { /* LIST open files */
13086 #ifdef CK_TTGWSIZ
13087 extern int cmd_rows, cmd_cols;
13088 #endif /* CK_TTGWSIZ */
13089 extern int xaskmore;
13090 int i, x, n = 0, paging = 0;
13091 char * s;
13092
13093 if ((x = cmcfm()) < 0)
13094 return(x);
13095
13096 #ifdef CK_TTGWSIZ
13097 if (cmd_rows > 0 && cmd_cols > 0)
13098 #endif /* CK_TTGWSIZ */
13099 paging = xaskmore;
13100
13101 printf("System open file limit:%5d\n", z_openmax);
13102 printf("Maximum for FILE OPEN: %5d\n", z_maxchan);
13103 printf("Files currently open: %5d\n\n", z_nopen);
13104 n = 4;
13105 for (i = 0; i < z_maxchan; i++) {
13106 s = z_getname(i); /* Got one? */
13107 if (s) { /* Yes */
13108 char m[8];
13109 m[0] = NUL;
13110 printf("%2d. %s",i,s); /* Print name */
13111 n++; /* Count it */
13112 x = z_getmode(i); /* Get modes & print them */
13113 if (x > 0) {
13114 if (x & FM_REA) ckstrncat(m,"R",8);
13115 if (x & FM_WRI) ckstrncat(m,"W",8);
13116 if (x & FM_APP) ckstrncat(m,"A",8);
13117 if (x & FM_BIN) ckstrncat(m,"B",8);
13118 if (m[0])
13119 printf(" (%s)",m);
13120 if (x & FM_EOF)
13121 printf(" [EOF]");
13122 else /* And file position too */
13123 printf(" %s",ckfstoa(z_getpos(i)));
13124 }
13125 printf("\n");
13126 #ifdef CK_TTGWSIZ
13127 if (paging > 0) { /* Pause at end of screen */
13128 if (n > cmd_rows - 3) {
13129 if (!askmore())
13130 break;
13131 else
13132 n = 0;
13133 }
13134 }
13135 #endif /* CK_TTGWSIZ */
13136 }
13137 }
13138 return(success = 1);
13139 }
13140
13141 case FIL_FLU: /* FLUSH */
13142 if ((x = cmnum("Channel number","",10,&n, xxstring)) < 0) {
13143 if (x == -3) {
13144 printf("?Channel number required\n");
13145 x = -9;
13146 }
13147 return(x);
13148 }
13149 if ((x = cmcfm()) < 0)
13150 return(x);
13151 if (n == -9) return(success = 0);
13152 if (n == -8) return(success = 1);
13153 if ((rc = z_flush(n)) < 0) {
13154 printf("?FLUSH failed - Channel %d: %s\n",n,ckferror(rc));
13155 return(-9);
13156 }
13157 return(success = 1);
13158
13159 case FIL_STA: /* STATUS */
13160 {
13161 int i, j, k; /* Supply default if only one open */
13162 s = "";
13163 for (k = 0, j = 0, i = 0; i < z_maxchan; i++) {
13164 if (z_file)
13165 if (z_file[i])
13166 if (z_file[i]->z_fp) { k++; j = i; }
13167 }
13168 if (k == 1) s = ckitoa(j);
13169 }
13170 if ((x = cmnum("Channel number",s,10,&n, xxstring)) < 0) {
13171 if (x == -3) {
13172 if (z_nopen > 1) {
13173 printf("?%d files open - please supply channel number\n",
13174 z_nopen);
13175 return(-9);
13176 }
13177 } else
13178 return(x);
13179 }
13180 if ((y = cmcfm()) < 0)
13181 return(y);
13182 if ((!z_file || z_nopen == 0) && x == -3) {
13183 printf("No files open\n");
13184 return(success = 1);
13185 }
13186 p = blanks + 3; /* Tricky formatting... */
13187 if (n < 1000) p--;
13188 if (n < 100) p--;
13189 if (n < 10) p--;
13190 if ((rc = z_getmode(n)) < 0) {
13191 printf("Channel %d:%s%s\n",n,p,ckferror(rc));
13192 return(success = 0);
13193 } else if (!rc) {
13194 printf("Channel %d:%sNot open\n",n,p);
13195 return(success = 0);
13196 } else {
13197 CK_OFF_T xx;
13198 s = z_getname(n);
13199 if (!s) s = "(name unknown)";
13200 printf("Channel %d:%sOpen\n",n,p);
13201 printf(" File: %s\n Modes: ",s);
13202 if (rc & FM_REA) printf(" /READ");
13203 if (rc & FM_WRI) printf(" /WRITE");
13204 if (rc & FM_APP) printf(" /APPEND");
13205 if (rc & FM_BIN) printf(" /BINARY");
13206 if (rc & FM_CMD) printf(" /COMMAND");
13207 if (rc & FM_EOF) printf(" [EOF]");
13208 printf("\n Size: %s\n",ckfstoa(z_count(n,RD_CHAR)));
13209 printf(" At byte: %s\n",ckfstoa(z_getpos(n)));
13210 xx = z_getline(n);
13211 if (xx > (CK_OFF_T)-1)
13212 printf(" At line: %s\n",ckfstoa(xx));
13213 return(success = 1);
13214 }
13215 default:
13216 return(-2);
13217 }
13218 }
13219 #endif /* CKCHANNELIO */
13220
13221 #ifndef NOSETKEY
13222 /* Save Key maps and in OS/2 Mouse maps */
13223 int
savkeys(name,disp)13224 savkeys(name,disp) char * name; int disp; {
13225 char *tp;
13226 static struct filinfo xx;
13227 int savfil, i, j, k;
13228 char buf[1024];
13229
13230 zclose(ZMFILE);
13231
13232 if (disp) {
13233 xx.bs = 0; xx.cs = 0; xx.rl = 0; xx.org = 0; xx.cc = 0;
13234 xx.typ = 0; xx.dsp = XYFZ_A; xx.os_specific = "";
13235 xx.lblopts = 0;
13236 savfil = zopeno(ZMFILE,name,NULL,&xx);
13237 } else savfil = zopeno(ZMFILE,name,NULL,NULL);
13238
13239 if (savfil) {
13240 #ifdef OS2
13241 ztime(&tp);
13242 zsout(ZMFILE, "; Kermit 95 SAVE KEYMAP file: ");
13243 zsoutl(ZMFILE,tp);
13244 if (mskkeys) {
13245 zsoutl(ZMFILE,
13246 "if eq \"\\v(program)\" \"C-Kermit\" set mskermit keycodes on");
13247 } else {
13248 zsoutl(ZMFILE,
13249 "if NOT eq \"\\v(program)\" \"C-Kermit\" stop 1 C-Kermit required.");
13250 zsoutl(ZMFILE,"set mskermit keycodes off");
13251 }
13252 zsoutl(ZMFILE,"");
13253 #else /* OS2 */
13254 ztime(&tp);
13255 zsout(ZMFILE, "; C-Kermit SAVE KEYMAP file: ");
13256 zsoutl(ZMFILE,tp);
13257 #endif /* OS2 */
13258
13259 zsoutl(ZMFILE,"; Clear previous keyboard mappings ");
13260 zsoutl(ZMFILE,"set key clear");
13261 #ifdef OS2
13262 for (k = 0; k < nttkey; k++) {
13263 if (!ttkeytab[k].flgs) {
13264 ckmakmsg(buf,1024,
13265 "set terminal key ",
13266 ttkeytab[k].kwd,
13267 " clear",
13268 NULL
13269 );
13270 zsoutl(ZMFILE,buf);
13271 }
13272 }
13273 #endif /* OS2 */
13274 zsoutl(ZMFILE,"");
13275
13276 for (i = 0; i < KMSIZE; i++) {
13277 if (macrotab[i]) {
13278 int len = strlen((char *)macrotab[i]);
13279 #ifdef OS2
13280 ckmakmsg(buf,
13281 1024,
13282 "set key \\",
13283 ckitoa(mskkeys ? cktomsk(i) : i),
13284 " ",
13285 NULL
13286 );
13287 #else /* OS2 */
13288 ckmakmsg(buf,
13289 1024,
13290 "set key \\",
13291 ckitoa(i),
13292 NULL,NULL
13293 );
13294 #endif /* OS2 */
13295 zsout(ZMFILE,buf);
13296
13297 for (j = 0; j < len; j++) {
13298 char ch = macrotab[i][j];
13299 if (ch <= SP || ch >= DEL ||
13300 ch == '-' || ch == ',' ||
13301 ch == '{' || ch == '}' ||
13302 ch == ';' || ch == '?' ||
13303 ch == '.' || ch == '\'' ||
13304 ch == '\\' || ch == '/' ||
13305 ch == '#') {
13306 ckmakmsg(buf,1024,"\\{",ckitoa((int)ch),"}",NULL);
13307 zsout(ZMFILE,buf);
13308 } else {
13309 ckmakmsg(buf,1024,ckctoa((char)ch),NULL,NULL,NULL);
13310 zsout(ZMFILE,buf);
13311 }
13312 }
13313 #ifdef OS2
13314 ckmakmsg(buf,1024,"\t; ",keyname(i),NULL,NULL);
13315 zsoutl(ZMFILE,buf);
13316 #else
13317 zsoutl(ZMFILE,"");
13318 #endif /* OS2 */
13319 } else if ( keymap[i] != i ) {
13320 #ifndef NOKVERBS
13321 if (IS_KVERB(keymap[i])) {
13322 for (j = 0; j < nkverbs; j++)
13323 if (kverbs[j].kwval == (keymap[i] & ~F_KVERB))
13324 break;
13325 if (j != nkverbs) {
13326 #ifdef OS2
13327 #ifdef COMMENT
13328 sprintf(buf, "set key \\%d \\K%s\t; %s",
13329 mskkeys ? cktomsk(i) : i,
13330 kverbs[j].kwd, keyname(i)
13331 );
13332 #else
13333 ckmakxmsg(buf, /* 12 string args */
13334 1024,
13335 "set key \\",
13336 ckitoa(mskkeys ? cktomsk(i) : i),
13337 " \\K",
13338 kverbs[j].kwd,
13339 "\t; ",
13340 keyname(i),
13341 NULL, NULL, NULL, NULL, NULL, NULL);
13342 #endif /* COMMENT */
13343 zsoutl(ZMFILE,buf);
13344 #else
13345 #ifdef COMMENT
13346 sprintf(buf, "set key \\%d \\K%s", i, kverbs[j].kwd);
13347 #else
13348 ckmakmsg(buf,1024,
13349 "set key \\",
13350 ckitoa(i),
13351 " \\K",
13352 kverbs[j].kwd
13353 );
13354 #endif /* COMMENT */
13355 zsoutl(ZMFILE,buf);
13356 #endif
13357 }
13358 } else
13359 #endif /* NOKVERBS */
13360 {
13361 #ifdef OS2
13362 #ifdef COMMENT
13363 sprintf(buf, "set key \\%d \\{%d}\t; %s",
13364 mskkeys ? cktomsk(i) : i,
13365 keymap[i],
13366 keyname(i)
13367 );
13368 #else
13369 ckmakxmsg(buf, /* 8 string args */
13370 1024,
13371 "set key \\",
13372 ckitoa(mskkeys ? cktomsk(i) : i),
13373 " \\{",
13374 ckitoa(keymap[i]),
13375 "}\t; ",
13376 keyname(i),
13377 NULL,NULL,NULL,NULL,NULL,NULL);
13378 #endif /* COMMENT */
13379 zsoutl(ZMFILE,buf);
13380 #else
13381 #ifdef COMMENT
13382 sprintf(buf, "set key \\%d \\{%d}", i, keymap[i]);
13383 #else
13384 ckmakxmsg(buf,1024,
13385 "set key \\",
13386 ckitoa(i),
13387 " \\{",
13388 ckitoa(keymap[i]),
13389 "}",
13390 NULL,NULL,NULL,NULL,NULL,NULL,NULL);
13391 #endif /* COMMENT */
13392 zsoutl(ZMFILE,buf);
13393 #endif /* OS2 */
13394 }
13395 }
13396 }
13397 #ifdef OS2
13398 /* OS/2 also has the SET TERMINAL KEY <termtype> defines */
13399 for (k = 0; k < nttkey; k++) {
13400 extern struct keynode * ttkeymap[];
13401 struct keynode * pnode = NULL;
13402
13403 if (ttkeytab[k].flgs) /* Don't process CM_INV or CM_ABR */
13404 continue;
13405
13406 zsoutl(ZMFILE,"");
13407 ckmakmsg(buf,1024,"; SET TERMINAL KEY ",ttkeytab[k].kwd,NULL,NULL);
13408 zsoutl(ZMFILE,buf);
13409
13410 for (pnode = ttkeymap[ttkeytab[k].kwval];
13411 pnode;
13412 pnode = pnode->next
13413 ) {
13414 switch (pnode->def.type) {
13415 case key:
13416 #ifdef COMMENT
13417 sprintf(buf, "set terminal key %s \\%d \\{%d}\t; %s",
13418 ttkeytab[k].kwd,
13419 mskkeys ? cktomsk(pnode->key) : pnode->key,
13420 pnode->def.key.scancode,
13421 keyname(pnode->key)
13422 );
13423 #else
13424 ckmakxmsg(buf,
13425 1024,
13426 "set terminal key ",
13427 ttkeytab[k].kwd,
13428 " \\",
13429 ckitoa(mskkeys ?
13430 cktomsk(pnode->key) :
13431 pnode->key),
13432 " \\{",
13433 ckitoa(pnode->def.key.scancode),
13434 "}\t; ",
13435 keyname(pnode->key),
13436 NULL,NULL,NULL,NULL
13437 );
13438 #endif /* COMMENT */
13439 zsoutl(ZMFILE,buf);
13440 break;
13441 case kverb:
13442 for (j = 0; j < nkverbs; j++)
13443 if (kverbs[j].kwval == (pnode->def.kverb.id & ~F_KVERB))
13444 break;
13445 if (j != nkverbs) {
13446 #ifdef COMMENT
13447 sprintf(buf, "set terminal key %s \\%d \\K%s\t; %s",
13448 ttkeytab[k].kwd,
13449 mskkeys ? cktomsk(pnode->key) : pnode->key,
13450 kverbs[j].kwd, keyname(pnode->key)
13451 );
13452 #else
13453 ckmakxmsg(buf,
13454 1024,
13455 "set terminal key ",
13456 ttkeytab[k].kwd,
13457 " \\",
13458 ckitoa(mskkeys ?
13459 cktomsk(pnode->key) :
13460 pnode->key),
13461 " \\K",
13462 kverbs[j].kwd,
13463 "\t; ",
13464 keyname(pnode->key),
13465 NULL,NULL,NULL,NULL
13466 );
13467 #endif /* COMMENT */
13468 zsoutl(ZMFILE,buf);
13469 }
13470 break;
13471 case macro: {
13472 int len = strlen((char *)pnode->def.macro.string);
13473 #ifdef COMMENT
13474 sprintf(buf,"set terminal key %s \\%d ",
13475 ttkeytab[k].kwd,
13476 mskkeys ? cktomsk(pnode->key) : pnode->key);
13477 #else
13478 ckmakxmsg(buf,
13479 1024,
13480 "set terminal key ",
13481 ttkeytab[k].kwd,
13482 " \\",
13483 ckitoa(mskkeys ?
13484 cktomsk(pnode->key) :
13485 pnode->key),
13486 " ",
13487 NULL,NULL,NULL,NULL,NULL,NULL,NULL
13488 );
13489 #endif /* COMMENT */
13490 zsout(ZMFILE,buf);
13491
13492 for (j = 0; j < len; j++) {
13493 char ch = pnode->def.macro.string[j];
13494 if (ch <= SP || ch >= DEL ||
13495 ch == '-' || ch == ',' ||
13496 ch == '{' || ch == '}' ||
13497 ch == ';' || ch == '?' ||
13498 ch == '.' || ch == '\'' ||
13499 ch == '\\' || ch == '/' ||
13500 ch == '#') {
13501 ckmakmsg(buf,1024,
13502 "\\{",ckitoa((int)ch),"}",NULL);
13503 zsout(ZMFILE,buf);
13504 } else {
13505 ckmakmsg(buf,1024,
13506 ckctoa((char)ch),NULL,NULL,NULL);
13507 zsout(ZMFILE,buf);
13508 }
13509 }
13510 ckmakmsg(buf,1024,"\t; ",keyname(pnode->key),NULL,NULL);
13511 zsoutl(ZMFILE,buf);
13512 break;
13513 }
13514 case literal: {
13515 int len = strlen((char *)pnode->def.literal.string);
13516 #ifdef COMMENT
13517 sprintf(buf,"set terminal key %s /literal \\%d ",
13518 ttkeytab[k].kwd,
13519 mskkeys ? cktomsk(pnode->key) : pnode->key);
13520 #else
13521 ckmakxmsg(buf,
13522 1024,
13523 "set terminal key ",
13524 ttkeytab[k].kwd,
13525 " /literal \\",
13526 ckitoa(mskkeys ?
13527 cktomsk(pnode->key) :
13528 pnode->key),
13529 " ",
13530 NULL,NULL,NULL,NULL,NULL,NULL,NULL);
13531 #endif /* COMMENT */
13532 zsout(ZMFILE,buf);
13533
13534 for (j = 0; j < len; j++) {
13535 char ch = pnode->def.literal.string[j];
13536 if (ch <= SP || ch >= DEL ||
13537 ch == '-' || ch == ',' ||
13538 ch == '{' || ch == '}' ||
13539 ch == ';' || ch == '?' ||
13540 ch == '.' || ch == '\'' ||
13541 ch == '\\' || ch == '/' ||
13542 ch == '#') {
13543 ckmakmsg(buf,1024,
13544 "\\{",ckitoa((int)ch),"}",NULL);
13545 zsout(ZMFILE,buf);
13546 } else {
13547 ckmakmsg(buf,1024,
13548 ckctoa((char)ch),NULL,NULL,NULL);
13549 zsout(ZMFILE,buf);
13550 }
13551 }
13552 ckmakmsg(buf,1024,"\t; ",keyname(pnode->key),NULL,NULL);
13553 zsoutl(ZMFILE,buf);
13554 break;
13555 }
13556 case esc:
13557 #ifdef COMMENT
13558 sprintf(buf,
13559 "set terminal key %s /literal \\%d \\{%d}\\{%d}\t; %s",
13560 ttkeytab[k].kwd,
13561 mskkeys ? cktomsk(pnode->key) : pnode->key,
13562 ISDG200(ttkeytab[k].kwval) ? 30 : 27,
13563 pnode->def.esc.key & ~F_ESC,
13564 keyname(pnode->key)
13565 );
13566 #else
13567 ckmakxmsg(buf,
13568 1024,
13569 "set terminal key ",
13570 ttkeytab[k].kwd,
13571 " /literal \\",
13572 ckitoa(mskkeys ?
13573 cktomsk(pnode->key) :
13574 pnode->key),
13575 " \\{",
13576 ckitoa(ISDG200(ttkeytab[k].kwval) ? 30 : 27),
13577 "}\\{",
13578 ckitoa(pnode->def.esc.key & ~F_ESC),
13579 "}\t; ",
13580 keyname(pnode->key),
13581 NULL,NULL
13582 );
13583 #endif /* COMMENT */
13584 zsoutl(ZMFILE,buf);
13585 break;
13586 case csi:
13587 #ifdef COMMENT
13588 sprintf(buf,
13589 "set terminal key %s /literal \\%d \\{27}[\\{%d}\t; %s",
13590 ttkeytab[k].kwd,
13591 mskkeys ? cktomsk(pnode->key) : pnode->key,
13592 pnode->def.csi.key & ~F_CSI,
13593 keyname(pnode->key)
13594 );
13595 #else
13596 ckmakxmsg(buf,
13597 1024,
13598 "set terminal key ",
13599 ttkeytab[k].kwd,
13600 " /literal \\",
13601 ckitoa(mskkeys ?
13602 cktomsk(pnode->key) :
13603 pnode->key),
13604 " \\{27}[\\{",
13605 ckitoa(pnode->def.csi.key & ~F_CSI),
13606 "}\t; ",
13607 keyname(pnode->key),
13608 NULL,NULL,NULL,NULL
13609 );
13610 #endif /* COMMENT */
13611 zsoutl(ZMFILE,buf);
13612 break;
13613 default:
13614 continue;
13615 }
13616 }
13617 }
13618 #endif /* OS2 */
13619
13620 zsoutl(ZMFILE,"");
13621 zsoutl(ZMFILE,"; End");
13622 zclose(ZMFILE);
13623 return(success = 1);
13624 } else {
13625 return(success = 0);
13626 }
13627 }
13628 #endif /* NOSETKEY */
13629
13630 #define SV_SCRL 0
13631 #define SV_HIST 1
13632
13633 #ifdef OS2
13634 #ifndef NOLOCAL
13635 static struct keytab trmtrmopt[] = {
13636 { "scrollback", SV_SCRL, 0 }
13637 };
13638 #endif /* NOLOCAL */
13639 #endif /* OS2 */
13640
13641 static struct keytab cmdtrmopt[] = {
13642 #ifdef CK_RECALL
13643 { "history", SV_HIST, 0 },
13644 #endif /* CK_RECALL */
13645 #ifdef OS2
13646 #ifndef NOLOCAL
13647 { "scrollback", SV_SCRL, 0 },
13648 #endif /* NOLOCAL */
13649 #endif /* OS2 */
13650 { "", 0, 0 }
13651 };
13652 static int ncmdtrmopt = (sizeof (cmdtrmopt) / sizeof (struct keytab)) - 1;
13653
13654 #ifdef OS2
13655 #ifndef NOLOCAL
13656 _PROTOTYP(int savscrbk, (int, char *, int));
13657 #endif /* NOLOCAL */
13658 #endif /* OS2 */
13659
13660 #ifdef CK_RECALL
13661 _PROTOTYP(int savhistory, (char *, int));
13662 #endif /* CK_RECALL */
13663
13664 int
dosave(xx)13665 dosave(xx) int xx; {
13666 int x, y = 0, disp;
13667 char * s = NULL;
13668 extern struct keytab disptb[];
13669 #ifdef ZFNQFP
13670 struct zfnfp * fnp;
13671 #endif /* ZFNQFP */
13672
13673 #ifndef NOSETKEY
13674 if (xx == XSKEY) { /* SAVE KEYMAP.. */
13675 z = cmofi("Name of Kermit command file","keymap.ksc",&s,xxstring);
13676 } else {
13677 #endif /* NOSETKEY */
13678 switch (xx) {
13679 case XSCMD: /* SAVE COMMAND.. */
13680 if ((y = cmkey(cmdtrmopt, ncmdtrmopt, "What to save",
13681 #ifdef OS2
13682 "scrollback",
13683 #else
13684 "history",
13685 #endif /* OS2 */
13686 xxstring)) < 0)
13687 return(y);
13688 break;
13689 #ifdef OS2
13690 #ifndef NOLOCAL
13691 case XSTERM: /* SAVE TERMINAL.. */
13692 if ((y = cmkey(trmtrmopt,1,
13693 "What to save","scrollback",xxstring)) < 0)
13694 return(y);
13695 break;
13696 #endif /* NOLOCAL */
13697 #endif /* OS2 */
13698 }
13699 z = cmofi("Filename",
13700 ((y == SV_SCRL) ? "scrollbk.txt" : "history.txt"),
13701 &s,
13702 xxstring
13703 );
13704 #ifndef NOSETKEY
13705 }
13706 #endif /* NOSETKEY */
13707 if (z < 0) /* Check output-file parse results */
13708 return(z);
13709 if (z == 2) {
13710 printf("?Sorry, %s is a directory name\n",s);
13711 return(-9);
13712 }
13713 #ifdef ZFNQFP
13714 if ((fnp = zfnqfp(s,TMPBUFSIZ - 1,tmpbuf))) {/* Convert to full pathname */
13715 if (fnp->fpath)
13716 if ((int) strlen(fnp->fpath) > 0)
13717 s = fnp->fpath;
13718 }
13719 #endif /* ZFNQFP */
13720
13721 ckstrncpy(line,s,LINBUFSIZ); /* Make safe copy of pathname */
13722 s = line;
13723 #ifdef MAC
13724 z = 0;
13725 #else
13726 /* Get NEW/APPEND disposition */
13727 if ((z = cmkey(disptb,2,"Disposition","new",xxstring)) < 0)
13728 return(z);
13729 #endif /* MAC */
13730 disp = z;
13731 if ((x = cmcfm()) < 0) /* Get confirmation */
13732 return(x);
13733
13734 switch (xx) { /* Do action.. */
13735 #ifndef NOSETKEY
13736 case XSKEY: /* SAVE KEYMAP */
13737 return (savkeys(s,disp));
13738 #endif /* NOSETKEY */
13739
13740 case XSCMD: /* SAVE COMMAND.. */
13741 #ifdef OS2
13742 #ifndef NOLOCAL
13743 if (y == SV_SCRL) /* .. SCROLLBACK */
13744 return(success = savscrbk(VCMD,s,disp));
13745 #endif /* NOLOCAL */
13746 #endif /* OS2 */
13747 #ifndef NORECALL
13748 if (y == SV_HIST) /* .. HISTORY */
13749 return(success = savhistory(s,disp));
13750 #endif /* NORECALL */
13751 break;
13752
13753 #ifdef OS2
13754 #ifndef NOLOCAL
13755 case XSTERM: /* SAVE TERMINAL SCROLLBACK */
13756 return(success = savscrbk(VTERM,s,disp));
13757 #endif /* NOLOCAL */
13758 #endif /* OS2 */
13759 }
13760 success = 0;
13761 return(-2);
13762 }
13763
13764 /*
13765 R E A D T E X T
13766
13767 Read text with a custom prompt into given buffer using command parser but
13768 with no echoing or entry into recall buffer.
13769 */
13770 int
readtext(prmpt,buffer,bufsiz)13771 readtext(prmpt, buffer, bufsiz) char * prmpt; char * buffer; int bufsiz; {
13772 #ifdef CK_RECALL
13773 extern int on_recall; /* Around Password prompting */
13774 #endif /* CK_RECALL */
13775 int rc;
13776 #ifndef NOLOCAL
13777 #ifdef OS2
13778 extern BYTE vmode;
13779 extern int startflags;
13780 int vmode_sav = vmode;
13781
13782 if (!prmpt) prmpt = "";
13783
13784 if (win95_popup && !(startflags & 96)
13785 #ifdef IKSD
13786 && !inserver
13787 #endif /* IKSD */
13788 )
13789 return(popup_readtext(vmode,NULL,prmpt,buffer,bufsiz,0));
13790
13791 if (vmode == VTERM) {
13792 vmode = VCMD;
13793 VscrnIsDirty(VTERM);
13794 VscrnIsDirty(VCMD);
13795 }
13796 #endif /* OS2 */
13797 #endif /* NOLOCAL */
13798
13799 #ifdef CK_RECALL
13800 on_recall = 0;
13801 #endif /* CK_RECALL */
13802 cmsavp(psave,PROMPTL); /* Save old prompt */
13803 cmsetp(prmpt); /* Make new prompt */
13804 concb((char)escape); /* Put console in cbreak mode */
13805 cmini(1); /* and echo mode */
13806 if (pflag) prompt(xxstring); /* Issue prompt if at top level */
13807 cmres(); /* Reset the parser */
13808 for (rc = -1; rc < 0; ) { /* Prompt till they answer */
13809 rc = cmtxt("","",&s,NULL); /* Get a literal line of text */
13810 cmres(); /* Reset the parser again */
13811 }
13812 ckstrncpy(buffer,s,bufsiz);
13813 cmsetp(psave); /* Restore original prompt */
13814
13815 #ifndef NOLOCAL
13816 #ifdef OS2
13817 if (vmode != vmode_sav) {
13818 vmode = VTERM;
13819 VscrnIsDirty(VCMD);
13820 VscrnIsDirty(VTERM);
13821 }
13822 #endif /* OS2 */
13823 #endif /* NOLOCAL */
13824 return(0);
13825 }
13826 #endif /* NOICP */
13827
13828 /* A general function to allow a Password or other information */
13829 /* to be read from the command prompt without it going into */
13830 /* the recall buffer or being echo'd. */
13831
13832 int
readpass(prmpt,buffer,bufsiz)13833 readpass(prmpt, buffer, bufsiz) char * prmpt; char * buffer; int bufsiz; {
13834 int x;
13835 #ifdef NOICP
13836 if (!prmpt) prmpt = "";
13837 printf("%s", prmpt);
13838 #ifdef COMMENT
13839 /* Some linkers won't allow this because it's unsafe */
13840 gets(buffer);
13841 #else /* COMMENT */
13842 {
13843 int c, i; char * p;
13844 p = buffer;
13845 for (i = 0; i < bufsiz-1; i++) {
13846 if ((c = getchar()) == EOF)
13847 break;
13848 if (c < SP)
13849 break;
13850 buffer[i] = c;
13851 }
13852 buffer[i] = NUL;
13853 }
13854 #endif /* COMMENT */
13855 return(1);
13856 #else /* NOICP */
13857 #ifdef CK_RECALL
13858 extern int on_recall; /* around Password prompting */
13859 #endif /* CK_RECALL */
13860 int rc;
13861 #ifndef NOLOCAL
13862 #ifdef OS2
13863 extern BYTE vmode;
13864 extern int startflags;
13865 int vmode_sav = vmode;
13866 #endif /* OS2 */
13867 #endif /* NOLOCAL */
13868 #ifdef CKSYSLOG
13869 int savlog;
13870 #endif /* CKSYSLOG */
13871 if (!prmpt) prmpt = "";
13872 #ifndef NOLOCAL
13873 debok = 0; /* Don't log */
13874 #ifdef OS2
13875 if (win95_popup && !(startflags & 96)
13876 #ifdef IKSD
13877 && !inserver
13878 #endif /* IKSD */
13879 ) {
13880 x = popup_readpass(vmode,NULL,prmpt,buffer,bufsiz,0);
13881 debok = 1;
13882 return(x);
13883 }
13884 #endif /* OS2 */
13885 #endif /* NOLOCAL */
13886
13887 #ifdef CKSYSLOG
13888 savlog = ckxsyslog; /* Save and turn off syslogging */
13889 ckxsyslog = 0;
13890 #endif /* CKSYSLOG */
13891 #ifndef NOLOCAL
13892 #ifdef OS2
13893 if (vmode == VTERM) {
13894 vmode = VCMD;
13895 VscrnIsDirty(VTERM);
13896 VscrnIsDirty(VCMD);
13897 }
13898 #endif /* OS2 */
13899 #endif /* NOLOCAL */
13900 #ifdef CK_RECALL
13901 on_recall = 0;
13902 #endif /* CK_RECALL */
13903 cmsavp(psave,PROMPTL); /* Save old prompt */
13904 cmsetp(prmpt); /* Make new prompt */
13905 concb((char)escape); /* Put console in cbreak mode */
13906 cmini(0); /* and no-echo mode */
13907 if (pflag) prompt(xxstring); /* Issue prompt if at top level */
13908 cmres(); /* Reset the parser */
13909 for (rc = -1; rc < 0; ) { /* Prompt till they answer */
13910 rc = cmtxt("","",&s,NULL); /* Get a literal line of text */
13911 cmres(); /* Reset the parser again */
13912 }
13913 ckstrncpy(buffer,s,bufsiz);
13914 printf("\r\n"); /* Echo a CRLF */
13915 cmsetp(psave); /* Restore original prompt */
13916 cmini(1); /* Restore echo mode */
13917 #ifndef NOLOCAL
13918 #ifdef OS2
13919 if (vmode != vmode_sav) {
13920 vmode = VTERM;
13921 VscrnIsDirty(VCMD);
13922 VscrnIsDirty(VTERM);
13923 }
13924 #endif /* OS2 */
13925 #endif /* NOLOCAL */
13926 #ifdef CKSYSLOG
13927 ckxsyslog = savlog; /* Restore syslogging */
13928 #endif /* CKSYSLOG */
13929 debok = 1;
13930 return(0);
13931 #endif /* NOICP */
13932 }
13933
13934 #ifndef NOICP
13935 struct keytab authtab[] = { /* Available authentication types */
13936 #ifdef CK_KERBEROS
13937 { "k4", AUTH_KRB4, CM_INV },
13938 { "k5", AUTH_KRB5, CM_INV },
13939 { "kerberos4", AUTH_KRB4, 0 },
13940 { "kerberos5", AUTH_KRB5, 0 },
13941 { "krb4", AUTH_KRB4, CM_INV },
13942 { "krb5", AUTH_KRB5, CM_INV },
13943 #endif /* CK_KERBEROS */
13944 #ifdef NT
13945 { "ntlm", AUTH_NTLM, 0 },
13946 #endif /* NT */
13947 #ifdef CK_SRP
13948 { "srp", AUTH_SRP, 0 },
13949 #endif /* CK_SRP */
13950 #ifdef CK_SSL
13951 { "ssl", AUTH_SSL, 0 },
13952 #endif /* CK_SSL */
13953 { "", 0, 0 }
13954 };
13955 int authtabn = sizeof(authtab)/sizeof(struct keytab)-1;
13956
13957 #ifdef CK_KERBEROS
13958 struct keytab kerbtab[] = { /* Kerberos authentication types */
13959 { "k4", AUTH_KRB4, CM_INV },
13960 { "k5", AUTH_KRB5, CM_INV },
13961 { "kerberos4", AUTH_KRB4, 0 },
13962 { "kerberos5", AUTH_KRB5, 0 },
13963 { "krb4", AUTH_KRB4, CM_INV },
13964 { "krb5", AUTH_KRB5, CM_INV }
13965 };
13966 int kerbtabn = sizeof(kerbtab)/sizeof(struct keytab);
13967
13968 static struct keytab krb_s_tbl[] = { /* AUTHENTICATE command switches: */
13969 { "/cache", KRB_S_CA, CM_ARG }
13970 };
13971 static int krb_s_n = sizeof(krb_s_tbl)/sizeof(struct keytab);
13972
13973 static struct keytab krb_v_tbl[] = { /* KERBEROS version values: */
13974 { "4", 4, 0 },
13975 { "5", 5, 0 }, /* (add others as needed...) */
13976 { "auto", 0, 0 } /* Note: 0 = auto */
13977 };
13978 static int krb_v_n = sizeof(krb_v_tbl)/sizeof(struct keytab);
13979
13980 static struct keytab krb_a_tbl[] = { /* KERBEROS actions: */
13981 { "destroy", KRB_A_DE, 0 },
13982 { "initialize", KRB_A_IN, 0 },
13983 { "list-credentials", KRB_A_LC, 0 }
13984 };
13985 static int krb_a_n = sizeof(krb_a_tbl)/sizeof(struct keytab);
13986
13987 static struct keytab krb4_i_tbl[] = { /* KERBEROS 4 INITIALIZE switches: */
13988 { "/brief", KRB_I_BR, 0 }, /* /BRIEF */
13989 { "/instance", KRB_I_IN, CM_ARG }, /* /INSTANCE: */
13990 { "/lifetime", KRB_I_LF, CM_ARG }, /* /LIFETIME: */
13991 { "/not-preauth", KRB_I_NPA, 0 }, /* /NOT-PREAUTH */
13992 { "/password", KRB_I_PW, CM_ARG }, /* /PASSWORD: */
13993 #ifdef OS2
13994 { "/popup", KRB_I_POP, 0 }, /* /POPUP */
13995 #endif /* OS2 */
13996 { "/preauth", KRB_I_PA, 0 }, /* /PREAUTH */
13997 { "/realm", KRB_I_RL, CM_ARG }, /* /REALM: */
13998 { "/verbose", KRB_I_VB, 0 }, /* /VERBOSE */
13999 { "", 0, 0 }
14000 };
14001 static int krb4_i_n = sizeof(krb4_i_tbl)/sizeof(struct keytab) - 1;
14002
14003 static struct keytab krb5_i_tbl[] = { /* KERBEROS 5 INITIALIZE switches: */
14004 { "/addresses", KRB_I_ADR, CM_ARG },
14005 { "/forwardable", KRB_I_FW, 0 }, /* /FORWARDABLE */
14006 { "/instance", KRB_I_IN, CM_ARG }, /* /INSTANCE: */
14007 { "/k4", KRB_I_K4, CM_INV }, /* /KERBEROS4 */
14008 { "/kerberos4", KRB_I_K4, 0 }, /* /KERBEROS4 */
14009 { "/krb4", KRB_I_K4, CM_INV }, /* /KERBEROS4 */
14010 { "/lifetime", KRB_I_LF, CM_ARG }, /* /LIFETIME: */
14011 { "/no-addresses", KRB_I_NAD, 0 }, /* /NO-ADDRESSES */
14012 { "/no-k4", KRB_I_NK4, CM_INV },/* /NO-KERBEROS4 */
14013 { "/no-kerberos4", KRB_I_NK4, 0 }, /* /NO-KERBEROS4 */
14014 { "/no-krb4", KRB_I_NK4, CM_INV },/* /NO-KERBEROS4 */
14015 { "/not-forwardable", KRB_I_NFW, 0 }, /* /NOT-FORWARDABLE */
14016 { "/not-proxiable", KRB_I_NPR, 0 }, /* /NOT-PROXIABLE */
14017 { "/password", KRB_I_PW, CM_ARG }, /* /PASSWORD: */
14018 #ifdef OS2
14019 { "/popup", KRB_I_POP, 0 }, /* /POPUP */
14020 #endif /* OS2 */
14021 { "/postdate", KRB_I_PD, CM_ARG }, /* /POSTDATE: */
14022 { "/pr", KRB_I_PR, CM_INV|CM_ABR }, /* to allow for */
14023 { "/pro", KRB_I_PR, CM_INV|CM_ABR }, /* different spellings */
14024 { "/prox", KRB_I_PR, CM_INV|CM_ABR },
14025 { "/proxiable", KRB_I_PR, 0 }, /* /PROXIABLE */
14026 { "/proxyable", KRB_I_PR, CM_INV }, /* /PROXYABLE */
14027 { "/realm", KRB_I_RL, CM_ARG }, /* /REALM: */
14028 { "/renew", KRB_I_RN, 0 }, /* /RENEW */
14029 { "/renewable", KRB_I_RB, CM_ARG }, /* /RENEWABLE: */
14030 { "/service", KRB_I_SR, CM_ARG }, /* /SERVICE: */
14031 { "/validate", KRB_I_VA, 0 }, /* /VALIDATE */
14032 { "", 0, 0 }
14033 };
14034 static int krb5_i_n = sizeof(krb5_i_tbl)/sizeof(struct keytab) - 1;
14035
14036 static struct keytab klctab[] = { /* List Credentials switches*/
14037 { "/addresses", XYKLCAD, 0 },
14038 { "/encryption", XYKLCEN, 0 },
14039 { "/flags", XYKLCFL, 0 }
14040 };
14041 static int nklctab = sizeof(klctab)/sizeof(struct keytab);
14042
14043 extern int krb_action;
14044 extern struct krb_op_data krb_op;
14045
14046 extern struct krb5_list_cred_data krb5_lc;
14047 extern struct krb5_init_data krb5_init;
14048 extern char * krb5_d_principal; /* Default principal */
14049 extern char * krb5_d_instance;
14050 extern char * krb5_d_realm; /* Default realm */
14051 extern char * krb5_d_cc; /* Default credentials cache */
14052 extern char * krb5_d_srv; /* Default service name */
14053 extern int krb5_d_lifetime; /* Default lifetime */
14054 extern int krb5_d_forwardable;
14055 extern int krb5_d_proxiable;
14056 extern int krb5_d_renewable;
14057 extern int krb5_autoget;
14058 extern int krb5_autodel;
14059 extern int krb5_d_getk4;
14060 extern int krb5_d_no_addresses;
14061 extern int krb5_checkaddrs;
14062 extern char * krb5_d_addrs[];
14063 extern char * k5_keytab; /* Keytab file */
14064
14065 extern struct krb4_init_data krb4_init;
14066 extern char * krb4_d_principal; /* Default principal */
14067 extern char * krb4_d_realm; /* Default realm */
14068 extern char * krb4_d_srv; /* Default service name */
14069 extern int krb4_d_lifetime; /* Default lifetime */
14070 extern int krb4_d_preauth;
14071 extern char * krb4_d_instance;
14072 extern int krb4_autoget;
14073 extern int krb4_autodel;
14074 extern int krb4_checkaddrs;
14075 extern char * k4_keytab; /* Keytab file */
14076 #endif /* CK_KERBEROS */
14077
14078 #ifndef NOSHOW
14079 int
sho_iks()14080 sho_iks() {
14081 #ifdef IKSDCONF
14082 #ifdef CK_LOGIN
14083 extern int ckxsyslog, ckxwtmp, ckxanon;
14084 #ifdef UNIX
14085 extern int ckxpriv;
14086 #endif /* UNIX */
14087 #ifdef CK_PERMS
14088 extern int ckxperms;
14089 #endif /* CK_PERMS */
14090 extern char * anonfile, * userfile, * anonroot;
14091 #ifdef OS2
14092 extern char * anonacct;
14093 #endif /* OS2 */
14094 #ifdef NT
14095 extern char * iks_domain;
14096 #endif /* NT */
14097 #endif /* CK_LOGIN */
14098 #ifdef CKWTMP
14099 extern char * wtmpfile;
14100 #endif /* CKWTMP */
14101 #ifdef IKSDB
14102 extern char * dbfile;
14103 extern int dbenabled;
14104 #endif /* IKSDB */
14105 #ifdef CK_LOGIN
14106 extern int logintimo;
14107 #endif /* CK_LOGIN */
14108 extern int srvcdmsg, success, iksdcf, noinit, arg_x;
14109 extern char * cdmsgfile[], * cdmsgstr, *kermrc;
14110 char * bannerfile = NULL;
14111 char * helpfile = NULL;
14112 extern int xferlog;
14113 extern char * xferfile;
14114 int i;
14115
14116 if (isguest) {
14117 printf("?Command disabled\r\n");
14118 return(success = 0);
14119 }
14120
14121 printf("IKS Settings\r\n");
14122 #ifdef CK_LOGIN
14123 #ifdef OS2
14124 printf(" Anonymous Account: %s\r\n",anonacct?anonacct:"<none>");
14125 #endif /* OS2 */
14126 printf(" Anonymous Initfile: %s\r\n",anonfile?anonfile:"<none>");
14127 printf(" Anonymous Login: %d\r\n",ckxanon);
14128 printf(" Anonymous Root: %s\r\n",anonroot?anonroot:"<none>");
14129 #endif /* CK_LOGIN */
14130 printf(" Bannerfile: %s\r\n",bannerfile?bannerfile:"<none>");
14131 printf(" CDfile: %s\r\n",cdmsgfile[0]?cdmsgfile[0]:"<none>");
14132 for ( i=1;i<16 && cdmsgfile[i];i++ )
14133 printf(" CDfile: %s\r\n",cdmsgfile[i]);
14134 printf(" CDMessage: %d\r\n",srvcdmsg);
14135 #ifdef IKSDB
14136 printf(" DBfile: %s\r\n",dbfile?dbfile:"<none>");
14137 printf(" DBenabled: %d\r\n",dbenabled);
14138 #endif /* IKSDB */
14139 #ifdef CK_LOGIN
14140 #ifdef NT
14141 printf(" Default-domain: %s\r\n",iks_domain?iks_domain:".");
14142 #endif /* NT */
14143 #endif /* CK_LOGIN */
14144 printf(" Helpfile: %s\r\n",helpfile?helpfile:"<none>");
14145 printf(" Initfile: %s\r\n",kermrc?kermrc:"<none>");
14146 printf(" No-Initfile: %d\r\n",noinit);
14147 #ifdef CK_LOGIN
14148 #ifdef CK_PERM
14149 printf(" Permission code: %0d\r\n",ckxperms);
14150 #endif /* CK_PERM */
14151 #ifdef UNIX
14152 printf(" Privileged Login: %d\r\n",ckxpriv);
14153 #endif /* UNIX */
14154 #endif /* CK_LOGIN */
14155 printf(" Server-only: %d\r\n",arg_x);
14156 printf(" Syslog: %d\r\n",ckxsyslog);
14157 printf(" Timeout (seconds): %d\r\n",logintimo);
14158 printf(" Userfile: %s\r\n",userfile?userfile:"<none>");
14159 #ifdef CK_LOGIN
14160 #ifdef CKWTMP
14161 printf(" Wtmplog: %d\r\n",ckxwtmp);
14162 printf(" Wtmpfile: %s\r\n",wtmpfile?wtmpfile:"<none>");
14163 #endif /* CKWTMP */
14164 #endif /* CK_LOGIN */
14165 printf(" Xferfile: %s\r\n",xferfile?xferfile:"<none>");
14166 printf(" Xferlog: %d\r\n",xferlog);
14167 #else /* IKSDCONF */
14168 printf("?Nothing to show.\r\n");
14169 #endif /* IKSDCONF */
14170 return(success = 1);
14171 }
14172
14173 #ifdef CK_AUTHENTICATION
14174 int
sho_auth(cx)14175 sho_auth(cx) int cx; {
14176 extern int auth_type_user[], cmd_rows;
14177 int i;
14178 char * p;
14179 int kv = 0, all = 0, n = 0;
14180
14181 #ifdef IKSD
14182 if (inserver && isguest) {
14183 printf("?Sorry, command disabled.\r\n");
14184 return(success = 0);
14185 }
14186 #endif /* IKSD */
14187 if (cx) {
14188 kv = cx;
14189 } else if (auth_type_user[0] != AUTHTYPE_AUTO) {
14190 kv = auth_type_user[0];
14191 } else {
14192 all = 1;
14193 kv = AUTHTYPE_KERBEROS_V4;
14194 }
14195 while (kv) {
14196 switch (kv) {
14197 case AUTHTYPE_KERBEROS_V4:
14198 kv = all ? AUTHTYPE_KERBEROS_V5 : 0;
14199 if (ck_krb4_is_installed()) {
14200 printf(" Authentication: Kerberos 4\n");
14201 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14202 } else {
14203 printf(" Authentication: Kerberos 4 (not installed)\n");
14204 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14205 continue;
14206 }
14207 #ifdef CK_KERBEROS
14208 printf(" Keytab file: %s\n",
14209 k4_keytab ? k4_keytab : "(none)");
14210 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14211 if (krb_action < 0) {
14212 p = "(none)";
14213 } else {
14214 for (p = "", i = 0; i < krb_a_n; i++) {
14215 if (krb_action == krb_a_tbl[i].kwval) {
14216 p = krb_a_tbl[i].kwd;
14217 break;
14218 }
14219 }
14220 }
14221 printf(" Action: %s\n", p);
14222 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14223 printf(" Default lifetime %d\n",krb4_d_lifetime);
14224 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14225 printf(" Lifetime: %d (minutes)\n",krb4_init.lifetime);
14226 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14227 printf(" Default preauth: %d\n",krb4_d_preauth);
14228 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14229 printf(" Preauth: %d\n",krb4_init.preauth);
14230 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14231 printf(" Default principal: \"%s\"\n",
14232 krb4_d_principal ? krb4_d_principal : "");
14233 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14234 printf(" Principal: \"%s\"\n",
14235 krb4_init.principal ? krb4_init.principal : "");
14236 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14237 printf(" Default realm: \"%s\"\n",
14238 krb4_d_realm ? krb4_d_realm : "");
14239 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14240 printf(" Realm: \"%s\"\n",
14241 krb4_init.realm ? krb4_init.realm : "");
14242 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14243 printf(" Default instance: \"%s\"\n",
14244 krb4_d_instance ? krb4_d_instance : "");
14245 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14246 printf(" Instance: \"%s\"\n",
14247 krb4_init.instance ? krb4_init.instance : "");
14248 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14249 printf(" Auto-Get TGTs: %d\n",krb4_autoget);
14250 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14251 printf(" Auto-Destroy TGTs: %s\n",
14252 krb4_autodel==KRB_DEL_NO?"never":
14253 krb4_autodel==KRB_DEL_CL?"on-close":"on-exit");
14254 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14255 printf(" Check IP Addresses: %d\n",krb4_checkaddrs);
14256 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14257 #ifdef COMMENT
14258 printf(" Password: \"%s\"\n",
14259 krb4_init.password ? krb4_init.password : "");
14260 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14261 #endif /* COMMENT */
14262 #endif /* CK_KERBEROS */
14263 printf("\n");
14264 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14265 break;
14266 case AUTHTYPE_KERBEROS_V5:
14267 kv = all ? AUTHTYPE_SSL : 0;
14268 if (ck_krb5_is_installed()) {
14269 if (ck_gssapi_is_installed())
14270 printf(" Authentication: Kerberos 5 plus GSSAPI\n");
14271 else
14272 printf(" Authentication: Kerberos 5\n");
14273 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14274 } else {
14275 printf(" Authentication: Kerberos 5 (not installed)\n");
14276 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14277 continue;
14278 }
14279
14280 #ifdef CK_KERBEROS
14281 printf(" Cache file: %s\n",
14282 krb_op.cache ? krb_op.cache : "(none)");
14283 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14284 printf(" Default cache: %s\n",
14285 krb5_d_cc ? krb5_d_cc : "(none)");
14286 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14287 printf(" Keytab file: %s\n",
14288 k5_keytab ? k5_keytab : "(none)");
14289 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14290 if (krb_action < 0) {
14291 p = "(none)";
14292 } else {
14293 for (p = "", i = 0; i < krb_a_n; i++) {
14294 if (krb_action == krb_a_tbl[i].kwval) {
14295 p = krb_a_tbl[i].kwd;
14296 break;
14297 }
14298 }
14299 }
14300 printf(" Action: %s\n", p);
14301 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14302
14303 printf(" Default forwardable %d\n",krb5_d_forwardable);
14304 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14305 printf(" Forwardable: %d\n",krb5_init.forwardable);
14306 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14307 printf(" Default lifetime %d\n",krb5_d_lifetime);
14308 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14309 printf(" Lifetime: %d (minutes)\n",krb5_init.lifetime);
14310 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14311 printf(" Postdate: \"%s\"\n",
14312 krb5_init.postdate ? krb5_init.postdate: "");
14313 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14314 printf(" Default proxiable: %d\n",krb5_d_proxiable);
14315 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14316 printf(" Proxiable: %d\n",krb5_init.proxiable);
14317 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14318 printf(" Renew: %d\n",krb5_init.renew);
14319 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14320 printf(" Default renewable: %d (minutes)\n",krb5_d_renewable);
14321 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14322 printf(" Renewable: %d (minutes)\n",krb5_init.renewable);
14323 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14324 printf(" Service: \"%s\"\n",
14325 krb5_init.service ? krb5_init.service : "");
14326 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14327 printf(" Validate: %d\n",krb5_init.validate);
14328 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14329 printf(" Default principal: \"%s\"\n",
14330 krb5_d_principal ? krb5_d_principal : "");
14331 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14332 printf(" Principal: \"%s\"\n",
14333 krb5_init.principal ? krb5_init.principal : "");
14334 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14335 printf(" Default instance: \"%s\"\n",
14336 krb5_d_instance ? krb5_d_instance : "");
14337 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14338 printf(" Default realm: \"%s\"\n",
14339 krb5_d_realm ? krb5_d_realm : "");
14340 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14341 printf(" Realm: \"%s\"\n",
14342 krb5_init.realm ? krb5_init.realm : "");
14343 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14344 printf(" Auto-Get TGTs: %d\n",krb5_autoget);
14345 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14346 printf(" Auto-Destroy TGTs: %s\n",
14347 krb5_autodel==KRB_DEL_NO?"never":
14348 krb5_autodel==KRB_DEL_CL?"on-close":"on-exit");
14349 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14350 printf(" Default get K4 TGTs: %d\n",krb5_d_getk4);
14351 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14352 printf(" Get K4 TGTs: %d\n",krb5_init.getk4);
14353 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14354 printf(" Check IP Addresses: %d\n",krb5_checkaddrs);
14355 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14356 printf(" No IP Addresses: %d\n",krb5_d_no_addresses);
14357 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14358 printf(" IP-Addresses: ");
14359 if (krb5_init.addrs && krb5_init.addrs[0]) {
14360 for (i = 0; krb5_init.addrs[i]; i++) {
14361 if (i)
14362 printf(",");
14363 printf("%s",krb5_init.addrs[i]);
14364 }
14365 } else if (krb5_d_addrs[0]) {
14366 for (i = 0;i < KRB5_NUM_OF_ADDRS && krb5_d_addrs[i];i++) {
14367 if (i)
14368 printf(",");
14369 printf("%s",krb5_d_addrs[i]);
14370 }
14371 } else {
14372 printf("(use default)");
14373 }
14374 printf("\n");
14375 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14376 #ifdef COMMENT
14377 printf(" Password: \"%s\"\n",
14378 krb5_init.password ? krb5_init.password : "");
14379 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14380 #endif /* COMMENT */
14381 #endif /* CK_KERBEROS */
14382 printf("\n");
14383 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14384 break;
14385 #ifdef CK_SSL
14386 case AUTHTYPE_SSL:
14387 kv = all ? AUTHTYPE_SRP : 0;
14388 if (ck_ssleay_is_installed()) {
14389 printf(" Authentication: SSL/TLS (%s)\n",
14390 SSLeay_version(SSLEAY_VERSION));
14391 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14392 } else {
14393 printf(" Authentication: SSL/TLS (not installed)\n");
14394 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14395 continue;
14396 }
14397 printf(" RSA Certs file: %s\n",ssl_rsa_cert_file?
14398 ssl_rsa_cert_file:"(none)");
14399 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14400 printf(" RSA Certs Chain file: %s\n",ssl_rsa_cert_chain_file?
14401 ssl_rsa_cert_chain_file:"(none)");
14402 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14403 printf(" RSA Key file: %s\n",ssl_rsa_key_file?
14404 ssl_rsa_key_file:"(none)");
14405 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14406 printf(" DSA Certs file: %s\n",ssl_dsa_cert_file?
14407 ssl_dsa_cert_file:"(none)");
14408 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14409 printf(" DSA Certs Chain file: %s\n",ssl_dsa_cert_chain_file?
14410 ssl_dsa_cert_chain_file:"(none)");
14411 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14412 printf(" DH Key file: %s\n",ssl_dh_key_file?
14413 ssl_dh_key_file:"(none)");
14414 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14415 printf(" DH Param file: %s\n",ssl_dh_param_file?
14416 ssl_dh_param_file:"(none)");
14417 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14418 printf(" CRL file: %s\n",ssl_crl_file?
14419 ssl_crl_file:"(none)");
14420 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14421 printf(" CRL dir: %s\n",ssl_crl_dir?
14422 ssl_crl_dir:"(none)");
14423 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14424 printf(" Random file: %s\n",ssl_rnd_file?
14425 ssl_rnd_file:"(none)");
14426 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14427 printf(" Verify file: %s\n",ssl_verify_file?
14428 ssl_verify_file:"(none)");
14429 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14430 printf(" Verify dir: %s\n",ssl_verify_dir?
14431 ssl_verify_dir:"(none)");
14432 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14433 printf(" Cipher list: %s\n",ssl_cipher_list ? ssl_cipher_list :
14434 DEFAULT_CIPHER_LIST);
14435 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14436 if (ssl_con == NULL) {
14437 SSL_library_init();
14438 ssl_ctx = (SSL_CTX *)
14439 /* old... SSL_CTX_new((SSL_METHOD *)TLSv1_method()); new below: */
14440 SSL_CTX_new((SSL_METHOD *)SSLv23_method());
14441 if (ssl_ctx != NULL)
14442 ssl_con= (SSL *) SSL_new(ssl_ctx);
14443 }
14444 if (ssl_con != NULL) {
14445 CHAR * p = NULL;
14446 int i;
14447
14448 for (i = 0; ; i++) {
14449 p = (CHAR *) SSL_get_cipher_list(ssl_con,i);
14450 if (p == NULL)
14451 break;
14452 printf(" %s\n",p);
14453 if (++n > cmd_rows - 3)
14454 if (!askmore()) return(0); else n = 0;
14455 }
14456 }
14457 printf(" Certs OK? %s\n",ssl_certsok_flag? "yes" : "no");
14458 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14459 printf(" Debug mode: %s\n", ssl_debug_flag ? "on" : "off");
14460 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14461 printf(" Verbose mode: %s\n", ssl_verbose_flag ? "on" : "off");
14462 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14463 printf(" Verify mode: %s\n",
14464 ssl_verify_flag == SSL_VERIFY_NONE ? "none" :
14465 ssl_verify_flag == SSL_VERIFY_PEER ? "peer-cert" :
14466 "fail-if-no-peer-cert");
14467 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14468 printf(" SSL only? %s\n", ssl_only_flag ? "yes" : "no");
14469 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14470 printf(" TLS only? %s\n", tls_only_flag ? "yes" : "no");
14471 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14472 #endif /* CK_SSL */
14473 break;
14474 case AUTHTYPE_NTLM:
14475 kv = 0;
14476 if (ck_ntlm_is_installed()) {
14477 printf(" Authentication: NTLM\n");
14478 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14479 printf(" No options\n");
14480 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14481 } else {
14482 printf(" Authentication: NTLM (not installed)\n");
14483 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14484 continue;
14485 }
14486 printf("\n");
14487 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14488 break;
14489 case AUTHTYPE_SRP:
14490 kv = all ? AUTHTYPE_NTLM : 0;
14491 if (ck_srp_is_installed()) {
14492 if (ck_krypto_is_installed())
14493 printf(" Authentication: SRP plus Krypto API\n");
14494 else
14495 printf(" Authentication: SRP\n");
14496 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14497 printf(" No options\n");
14498 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14499 } else {
14500 printf(" Authentication: SRP (not installed)\n");
14501 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14502 continue;
14503 }
14504 printf("\n");
14505 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14506 break;
14507 }
14508 }
14509 return(success = 1);
14510 }
14511 #endif /* CK_AUTHENTICATION */
14512 #endif /* NOSHOW */
14513
14514 #ifdef CK_KERBEROS
14515
14516 /* C P _ A U T H -- AUTHENTICATE command parsing */
14517
14518 int
cp_auth()14519 cp_auth() { /* Command_Parse AUTHENTICATE */
14520 int c, i, n; /* Workers */
14521 int rc = 0; /* Return code */
14522 int getval; /* Parsing helpers */
14523 int tmpauth = 0; /* Temporary authentication type */
14524 int kv = 0; /* Temporary Kerberos version */
14525 int tmp_action = -1; /* Temporary Kerberos action */
14526 int tmp_klc = 0; /* Temporary list-credentials */
14527 char tmphlp[256]; /* For building help message */
14528 char * p;
14529 char * tmppswd = NULL; /* Password */
14530 char * tmpprinz = NULL; /* Principal */
14531 char * tmprealm = NULL; /* Realm */
14532 char * tmpcache = NULL; /* Cache file */
14533 char * tmpinst = NULL; /* K4 Instance */
14534 char * tmpaddrs[KRB5_NUM_OF_ADDRS];
14535 #ifdef CK_RECALL
14536 extern int on_recall; /* around Password prompting */
14537 #endif /* CK_RECALL */
14538 struct stringint pv[KRB_I_MAX+1]; /* Temporary array for switch values */
14539 struct FDB kw, sw, fl; /* FDBs for each parse function */
14540
14541 krb_action = -1; /* Initialize Kerberos action. */
14542 tmp_action = -1; /* And our local copy. */
14543 for (i = 0; i < KRB5_NUM_OF_ADDRS; i++)
14544 tmpaddrs[i] = NULL;
14545
14546 if ((y = cmkey(kerbtab,kerbtabn,"authentication type","",xxstring)) < 0)
14547 {
14548 if (y == -3)
14549 printf("?Authentication type not specified - nothing happens\n");
14550 return(y);
14551 }
14552 tmpauth = y;
14553 debug(F101,"kerberos authentication","",tmpauth);
14554 switch (tmpauth) {
14555 case AUTH_KRB4: kv = 4; break; /* Don't assume values are the same */
14556 case AUTH_KRB5: kv = 5; break;
14557 default:
14558 printf("?Authentication type not supported: \"%s\"\n",atmbuf);
14559 return(-9);
14560 }
14561
14562 /* From here down is Kerberos */
14563 ini_kerb(); /* Reset Init data to defaults */
14564
14565 if (kv == 4) { /* Set K4 defaults */
14566 if (krb4_d_realm)
14567 makestr(&tmprealm,krb4_d_realm);
14568 if (krb4_d_principal)
14569 makestr(&tmpprinz,krb4_d_principal);
14570 if (krb4_d_instance)
14571 makestr(&tmpinst,krb4_d_instance);
14572 } else if (kv == 5) { /* Set K5 defaults */
14573 if (krb5_d_cc)
14574 makestr(&tmpcache,krb5_d_cc);
14575 if (krb5_d_realm)
14576 makestr(&tmprealm,krb5_d_realm);
14577 if (krb5_d_principal)
14578 makestr(&tmpprinz,krb5_d_principal);
14579 if (krb5_d_instance)
14580 makestr(&tmpinst,krb5_d_instance);
14581 }
14582 for (i = 0; i <= KRB_I_MAX; i++) { /* Initialize switch values */
14583 pv[i].sval = NULL; /* to null pointers */
14584 pv[i].ival = 0; /* and 0 int values */
14585 pv[i].wval = (CK_OFF_T)-1; /* and -1 wide values */
14586 }
14587 if (kv == 4) { /* Kerberos 4 */
14588 pv[KRB_I_LF].ival = krb4_d_lifetime;
14589 pv[KRB_I_PA].ival = krb4_d_preauth;
14590
14591 if ((n = cmkey(krb_a_tbl,krb_a_n,"Kerberos 4 action","",xxstring)) < 0)
14592 {
14593 if (n == -3)
14594 printf("?Action not specified - nothing happens.\n");
14595 return(n);
14596 }
14597 } else if (kv == 5) { /* Kerberos 5 */
14598 pv[KRB_I_FW].ival = krb5_d_forwardable;
14599 pv[KRB_I_PR].ival = krb5_d_proxiable;
14600 pv[KRB_I_LF].ival = krb5_d_lifetime;
14601 pv[KRB_I_RB].ival = krb5_d_renewable;
14602 pv[KRB_I_K4].ival = krb5_d_getk4;
14603 pv[KRB_I_NAD].ival = krb5_d_no_addresses;
14604
14605 /* Make help message that shows switches and action keywords */
14606 ckstrncpy(tmphlp,"Kerberos 5 action, one of the following:\n ",256);
14607 for (i = 0; i < krb_a_n; i++) {
14608 ckstrncat(tmphlp,krb_a_tbl[i].kwd,sizeof(tmphlp));
14609 if (i == krb_a_n - 1)
14610 ckstrncat(tmphlp,"\nor switch",sizeof(tmphlp));
14611 else
14612 ckstrncat(tmphlp," ",sizeof(tmphlp));
14613 }
14614 /* Set up first set of chained FDB's */
14615
14616 cmfdbi(&sw, /* First FDB - command switches */
14617 _CMKEY, /* fcode */
14618 tmphlp, /* hlpmsg */
14619 "", /* default (none) */
14620 "", /* addtl string data */
14621 krb_s_n, /* Switch table size */
14622 4, /* addtl numeric data 2: 4 = cmswi */
14623 xxstring, /* Processing function */
14624 krb_s_tbl, /* Switch table */
14625 &kw /* Pointer to next FDB */
14626 );
14627 cmfdbi(&kw, /* Second FDB - action keywords */
14628 _CMKEY, /* fcode */
14629 "Kerberos action", /* hlpmsg */
14630 "", /* default (none) */
14631 "", /* addtl string data */
14632 krb_a_n, /* Switch table size */
14633 0, /* addtl num data (0 = NOT switch) */
14634 xxstring, /* Processing function */
14635 krb_a_tbl, /* Keyword table */
14636 NULL /* Pointer to next FDB (none) */
14637 );
14638
14639 /* Parse */
14640
14641 while (1) { /* Parse 0 or more switches */
14642 rc = cmfdb(&sw); /* Parse something */
14643 debug(F101,"kerberos cmfdb 1 rc","",rc);
14644 if (rc < 0) { /* Error */
14645 if (rc == -3)
14646 printf("?Action not specified - nothing happens.\n");
14647 return(rc); /* or reparse needed */
14648 }
14649 if (cmresult.fdbaddr != &sw) /* Break out if not a switch */
14650 break;
14651 c = cmgbrk(); /* Have switch - get break character */
14652 getval = (c == ':' || c == '='); /* Must parse an agument? */
14653 if (getval && !(cmresult.kflags & CM_ARG)) {
14654 printf("?This switch does not take arguments\n");
14655 return(-9); /* OK because nothing malloc'd yet */
14656 }
14657 if (!getval && (cmgkwflgs() & CM_ARG)) {
14658 printf("?This switch requires an argument\n");
14659 return(-9);
14660 }
14661 n = cmresult.nresult; /* Numeric result = switch value */
14662 debug(F101,"kerberos command switch","",n);
14663
14664 switch (n) { /* Handle the switch */
14665 case KRB_S_CA: /* /CACHE:<filename> */
14666 p = krb5_d_cc ? krb5_d_cc : "";
14667 if ((y = cmofi("Name of cache file",p,&s,xxstring)) < 0) {
14668 if (y == -3)
14669 s = NULL;
14670 else
14671 return(y);
14672 }
14673 makestr(&tmpcache,s);
14674 break;
14675 default:
14676 printf("?Unexpected switch value - internal error\n");
14677 return(-9); /* (if) nothing malloc'd yet. */
14678 }
14679 }
14680 if (cmresult.fdbaddr != &kw) { /* Checking... */
14681 printf("?Unexpected result - internal error\n");
14682 return(-9); /* Nothing malloc'd yet. */
14683 }
14684 n = cmresult.nresult; /* Get keyword value */
14685 } else {
14686 printf("?Unexpected Kerberos version - Internal error\n");
14687 return(-9);
14688 }
14689 debug(F101,"kerberos action","",n);
14690 switch (n) {
14691 case KRB_A_IN: /* INITIALIZE */
14692 case KRB_A_DE: /* DESTROY */
14693 case KRB_A_LC: /* LIST-CREDENTIALS */
14694 tmp_action = n; /* OK, set */
14695 break;
14696 default: /* Not OK, punt. */
14697 printf("?Unexpected action - internal error\n");
14698 return(-9);
14699 }
14700 if (tmp_action == KRB_A_IN) { /* Action is INITIALIZE */
14701 int x;
14702 cmfdbi(&sw, /* INITIALIZE switches */
14703 _CMKEY, /* fcode */
14704 "Principal,\n or optional INITIALIZE switch(es)", /* hlpmsg */
14705 "", /* default (none) */
14706 "", /* addtl string data */
14707 kv == 4 ? krb4_i_n : krb5_i_n, /* Switch table size */
14708 4, /* addtl numeric data 2: 4 = cmswi */
14709 xxstring, /* Processing function */
14710 kv == 4 ? krb4_i_tbl : krb5_i_tbl, /* Switch table */
14711 &fl /* Pointer to next FDB */
14712 );
14713 cmfdbi(&fl, /* 3rd FDB - command to send from */
14714 _CMFLD, /* fcode */
14715 "Principal", /* hlpmsg */
14716 kv == 4 ? krb4_d_principal : krb5_d_principal, /* principal */
14717 "", /* addtl string data */
14718 0, /* addtl numeric data 1 */
14719 0, /* addtl numeric data 2 */
14720 xxstring,
14721 NULL,
14722 NULL
14723 );
14724 while (1) { /* Parse INIT switches or principal */
14725 rc = cmfdb(&sw);
14726 debug(F101,"kerberos cmfdb 2 rc","",rc);
14727 if (rc < 0) {
14728 if (rc == -3)
14729 printf("?Principal name required\n");
14730 goto kerbx;
14731 }
14732 debug(F101,"kerberos cmfdb 2 fcode","",cmresult.fcode);
14733 if (cmresult.fcode != _CMKEY) /* Not a switch, quit switch loop */
14734 break;
14735 c = cmgbrk(); /* Switch - get break character */
14736 debug(F101,"kerberos cmfdb 2 cmgbrk","",c);
14737 getval = (c == ':' || c == '=');
14738 if (getval && !(cmresult.kflags & CM_ARG)) {
14739 printf("?This switch does not take arguments\n");
14740 return(-9); /* OK because nothing malloc'd yet */
14741 }
14742 if (!getval && (cmgkwflgs() & CM_ARG)) {
14743 printf("?This switch requires an argument\n");
14744 return(-9);
14745 }
14746 n = cmresult.nresult; /* Numeric result = switch value */
14747 switch (n) {
14748 /* These don't take args... */
14749 case KRB_I_PA: /* /PREAUTH */
14750 case KRB_I_FW: /* /FORWARDABLE */
14751 case KRB_I_PR: /* /PROXIABLE */
14752 case KRB_I_RN: /* /RENEW */
14753 case KRB_I_VA: /* /VALIDATE */
14754 case KRB_I_NPA: /* /NOT-PREAUTH */
14755 case KRB_I_NFW: /* /NOT-FORWARDABLE */
14756 case KRB_I_NPR: /* /NOT-PROXIABLE */
14757 case KRB_I_VB: /* /VERBOSE */
14758 case KRB_I_BR: /* /BRIEF */
14759 case KRB_I_K4: /* /KERBEROS4 */
14760 case KRB_I_NK4: /* /NO-KERBEROS4 */
14761 case KRB_I_POP: /* /POPUP */
14762 case KRB_I_NAD: /* /NO-ADDRESSES */
14763 if (getval) {
14764 printf("?This switch does not take a value\n");
14765 rc = -9;
14766 goto kerbx;
14767 }
14768 switch (n) {
14769 case KRB_I_NPA:
14770 pv[KRB_I_PA].ival = 0;
14771 break;
14772 case KRB_I_NFW:
14773 pv[KRB_I_FW].ival = 0;
14774 break;
14775 case KRB_I_NPR:
14776 pv[KRB_I_PR].ival = 0;
14777 break;
14778 case KRB_I_VB:
14779 pv[KRB_I_BR].ival = 0;
14780 break;
14781 case KRB_I_NK4:
14782 pv[KRB_I_K4].ival = 0;
14783 break;
14784 default:
14785 pv[n].ival = 1;
14786 }
14787 break;
14788
14789 /* These do take arguments */
14790
14791 case KRB_I_RB: /* /RENEWABLE:<minutes> */
14792 pv[n].ival = 0;
14793 if (!getval) break;
14794 if ((rc = cmnum("Minutes",ckitoa(krb5_init.renewable),
14795 10,&y, xxstring)) < 0)
14796 goto kerbx;
14797 pv[n].ival = y;
14798 break;
14799
14800 case KRB_I_LF: /* /LIFETIME:<minutes> */
14801 pv[n].ival = 0;
14802 /* Default is previous value */
14803 sprintf(tmpbuf,"%d", /* SAFE */
14804 kv == 4 ?
14805 krb4_init.lifetime :
14806 krb5_init.lifetime
14807 );
14808 if (!getval) break;
14809 if ((rc = cmnum("Minutes",tmpbuf,10,&y, xxstring)) < 0)
14810 goto kerbx;
14811 pv[n].ival = y;
14812 break;
14813
14814 case KRB_I_PD: /* /POSTDATE:<timestamp> */
14815 if (pv[n].sval) {
14816 free(pv[n].sval);
14817 pv[n].sval = NULL;
14818 }
14819 if (!getval) break;
14820 if ((rc = cmdate("date-time","",&s,0,xxstring)) < 0)
14821 goto kerbx;
14822 makestr(&(pv[n].sval),s);
14823 break;
14824
14825 case KRB_I_SR: /* /SERVICE:<name> */
14826 if (pv[n].sval) {
14827 free(pv[n].sval);
14828 pv[n].sval = NULL;
14829 }
14830 if (!getval) break;
14831 if ((rc = cmfld("Service-name","",&s,xxstring)) < 0)
14832 goto kerbx;
14833 makestr(&(pv[n].sval),s);
14834 break;
14835
14836 case KRB_I_RL: /* /REALM:<name> */
14837 if (pv[n].sval) {
14838 free(pv[n].sval);
14839 pv[n].sval = NULL;
14840 }
14841 if (!getval) break;
14842 if (kv == 4)
14843 p = krb4_d_realm ? krb4_d_realm : "";
14844 else
14845 p = krb5_d_realm ? krb5_d_realm : "";
14846 if ((rc = cmfld("Realm",p,&s,xxstring)) < 0)
14847 goto kerbx;
14848 makestr(&(pv[n].sval),s);
14849 break;
14850
14851 case KRB_I_IN: /* /INSTANCE:<name> */
14852 if (pv[n].sval) {
14853 free(pv[n].sval);
14854 pv[n].sval = NULL;
14855 }
14856 if (!getval) break;
14857 if (kv == 4)
14858 p = krb4_d_instance ? krb4_d_instance : "";
14859 else
14860 p = krb5_d_instance ? krb5_d_instance : "";
14861 if ((rc = cmfld("Instance",p,&s,xxstring)) < 0)
14862 goto kerbx;
14863 makestr(&(pv[n].sval),s);
14864 break;
14865
14866 case KRB_I_PW: /* /PASSWORD:<password> */
14867 debok = 0;
14868 if (pv[n].sval) {
14869 free(pv[n].sval);
14870 pv[n].sval = NULL;
14871 }
14872 if (!getval) break;
14873 if ((rc = cmfld("Password","",&s,xxstring)) < 0)
14874 if (rc != -3)
14875 goto kerbx;
14876 makestr(&(pv[n].sval),s);
14877 break;
14878
14879 case KRB_I_ADR: /* /ADDRESSES:{<address-list>} */
14880 if (pv[n].sval) {
14881 free(pv[n].sval);
14882 pv[n].sval = NULL;
14883 }
14884 if (!getval) break;
14885 if ((rc = cmfld("List of IP addresses","",&s,xxstring)) < 0)
14886 goto kerbx;
14887 makelist(s,tmpaddrs,KRB5_NUM_OF_ADDRS);
14888 for (i = 0; i < KRB5_NUM_OF_ADDRS && tmpaddrs[i]; i++) {
14889 if (inet_addr(tmpaddrs[i]) == 0xffffffff) {
14890 printf("invalid ip address: %s\n",tmpaddrs[i]);
14891 rc = -9;
14892 goto kerbx;
14893 }
14894 }
14895 pv[KRB_I_NAD].ival = 0;
14896 break;
14897
14898 default:
14899 printf("?Unexpected switch value - internal error\n");
14900 rc = -9;
14901 goto kerbx;
14902 }
14903 }
14904 if (cmresult.fcode != _CMFLD) {
14905 printf("?Unexected result - internal error\n");
14906 rc = -9;
14907 goto kerbx;
14908 }
14909 /* cmresult.sresult may be of the form PRINCIPAL@REALM */
14910 i = ckindex("@",cmresult.sresult,0,0,0);
14911 if (i != 0) {
14912 makestr(&tmprealm,&cmresult.sresult[i]);
14913 cmresult.sresult[i-1] = '\0';
14914 }
14915 makestr(&tmpprinz,cmresult.sresult); /* Principal (user) */
14916
14917 if ((rc = cmcfm()) < 0) { /* Now get confirmation */
14918 if (rc == -3) {
14919 printf("?Principal name required\n");
14920 }
14921 goto kerbx;
14922 }
14923 if (!tmpprinz || !tmpprinz[0]) {
14924 printf("?Principal name required\n");
14925 goto kerbx;
14926 }
14927 if (!pv[KRB_I_RN].ival && !pv[KRB_I_VA].ival) {
14928 /* Don't use a password if Validating or Renewing */
14929 if (pv[KRB_I_PW].sval) { /* If they gave a /PASSWORD switch */
14930 makestr(&tmppswd,pv[KRB_I_PW].sval); /* use this value */
14931 }
14932 #ifdef COMMENT
14933 /* Password prompting has been moved to ck_krb[45]_initTGT() */
14934 else { /* Otherwise must prompt for it */
14935 char prmpt[80];
14936 if (pv[KRB_I_RL].sval)
14937 sprintf(prmpt,"%s@%s's Password: ",
14938 tmpprinz,pv[KRB_I_RL].sval);
14939 else if (tmprealm)
14940 sprintf(prmpt,"%s@%s's Password: ",
14941 tmpprinz,tmprealm);
14942 else
14943 sprintf(prmpt,"%s's Password: ",tmpprinz);
14944 #ifdef OS2
14945 if (pv[KRB_I_POP].ival) {
14946 char passwd[80]="";
14947 readpass(prmpt,passwd,80);
14948 makestr(&tmppswd,passwd);
14949 memset(passwd,0,80);
14950 } else
14951 #endif /* OS2 */
14952 {
14953 #ifdef CK_RECALL
14954 on_recall = 0;
14955 #endif /* CK_RECALL */
14956 cmsavp(psave,PROMPTL); /* Save old prompt */
14957 cmsetp(prmpt); /* Make new prompt */
14958 concb((char)escape); /* Put console in cbreak mode */
14959 cmini(0); /* and no-echo mode */
14960 /* Issue prompt if at top level */
14961 if (pflag) prompt(xxstring);
14962 cmres(); /* Reset the parser */
14963 for (rc = -1; rc < 0; ) { /* Prompt till they answer */
14964 /* Get a literal line of text */
14965 rc = cmtxt("","",&s,NULL);
14966 cmres(); /* Reset the parser again */
14967 }
14968 makestr(&tmppswd,s);
14969 printf("\n"); /* Echo a CRLF */
14970 cmsetp(psave); /* Restore original prompt */
14971 }
14972 }
14973 x = 0; /* Check for password */
14974 if (tmppswd)
14975 if (*tmppswd)
14976 x = 1;
14977 if (!x) {
14978 printf("?Password required\n");
14979 goto kerbx;
14980 }
14981 #endif /* COMMENT */
14982 }
14983 } else if (kv == 5 && tmp_action == KRB_A_LC) { /* LIST-CREDENTIALS */
14984 tmp_klc = 0;
14985 while (1) {
14986 if ((x = cmkey(klctab,nklctab,"Switch","",xxstring)) < 0) {
14987 if (x == -3) {
14988 if ((rc = cmcfm()) < 0)
14989 goto kerbx;
14990 else
14991 break;
14992 } else {
14993 rc = x;
14994 goto kerbx;
14995 }
14996 }
14997 tmp_klc |= x;
14998 }
14999 } else if ((rc = cmcfm()) < 0) /* DESTROY, just confirm */
15000 goto kerbx;
15001
15002 /* Done - Move confirmed data to final locations */
15003
15004 krb_action = tmp_action; /* Action requested */
15005 krb_op.version = kv; /* Kerberos version */
15006 krb_op.cache = tmpcache; /* Cache file */
15007 tmpcache = NULL; /* So we don't free it */
15008
15009 switch (krb_action) {
15010 case KRB_A_IN: /* INITIALIZE */
15011 if (kv == 5) {
15012 krb5_init.forwardable = pv[KRB_I_FW].ival;
15013 krb5_init.proxiable = pv[KRB_I_PR].ival;
15014 krb5_init.lifetime = pv[KRB_I_LF].ival;
15015 krb5_init.renew = pv[KRB_I_RN].ival;
15016 krb5_init.renewable = pv[KRB_I_RB].ival;
15017 krb5_init.validate = pv[KRB_I_VA].ival;
15018
15019 /* Here we just reassign the pointers and then set them to NULL */
15020 /* so they won't be freed below. */
15021
15022 krb5_init.postdate = pv[KRB_I_PD].sval; pv[KRB_I_PD].sval = NULL;
15023 krb5_init.service = pv[KRB_I_SR].sval; pv[KRB_I_SR].sval = NULL;
15024 if (pv[KRB_I_RL].sval) {
15025 krb5_init.realm = pv[KRB_I_RL].sval; pv[KRB_I_RL].sval = NULL;
15026 } else if (tmprealm) {
15027 krb5_init.realm = tmprealm; tmprealm = NULL;
15028 }
15029 if (pv[KRB_I_IN].sval) {
15030 krb5_init.instance = pv[KRB_I_IN].sval;
15031 pv[KRB_I_IN].sval = NULL;
15032 } else if ( tmpinst ) {
15033 krb5_init.instance = tmpinst;
15034 tmpinst = NULL;
15035 }
15036 if (tmpprinz) {
15037 krb5_init.principal = tmpprinz;
15038 tmpprinz = NULL;
15039 }
15040 krb5_init.password = tmppswd;
15041 tmppswd = NULL;
15042
15043 krb5_init.getk4 = pv[KRB_I_K4].ival;
15044 if (krb5_init.getk4) {
15045 krb4_init.lifetime = pv[KRB_I_LF].ival;
15046 if (krb5_init.realm)
15047 makestr(&krb4_init.realm,krb5_init.realm);
15048 krb4_init.preauth = krb4_d_preauth;
15049 krb4_init.verbose = pv[KRB_I_BR].ival ? 0 : 1;
15050 if (krb5_init.principal)
15051 makestr(&krb4_init.principal,krb5_init.principal);
15052 if (krb5_init.principal)
15053 makestr(&krb4_init.password,krb5_init.password);
15054 }
15055 krb5_init.no_addresses = pv[KRB_I_NAD].ival;
15056 if (tmpaddrs[0]) {
15057 for (i = 0; i < KRB5_NUM_OF_ADDRS; i++) {
15058 if (krb5_init.addrs[i]) {
15059 free(krb5_init.addrs[i]);
15060 krb5_init.addrs[i] = NULL;
15061 }
15062 krb5_init.addrs[i] = tmpaddrs[i];
15063 tmpaddrs[i] = NULL;
15064 }
15065 }
15066 } else if (kv == 4) { /* Same deal for Kerberos 4 */
15067 krb4_init.lifetime = pv[KRB_I_LF].ival;
15068 if (pv[KRB_I_RL].sval) {
15069 krb4_init.realm = pv[KRB_I_RL].sval;
15070 pv[KRB_I_RL].sval = NULL;
15071 } else if ( tmprealm ) {
15072 krb4_init.realm = tmprealm;
15073 tmprealm = NULL;
15074 }
15075 if (pv[KRB_I_IN].sval) {
15076 krb4_init.instance = pv[KRB_I_IN].sval;
15077 pv[KRB_I_IN].sval = NULL;
15078 } else if ( tmpinst ) {
15079 krb4_init.instance = tmpinst;
15080 tmpinst = NULL;
15081 }
15082 krb4_init.preauth = pv[KRB_I_PA].ival;
15083 krb4_init.verbose = pv[KRB_I_BR].ival ? 0 : 1;
15084
15085 if (tmpprinz) {
15086 krb4_init.principal = tmpprinz;
15087 tmpprinz = NULL;
15088 }
15089 krb4_init.password = tmppswd;
15090 tmppswd = NULL;
15091 }
15092 break;
15093 case KRB_A_LC: /* List Credentials */
15094 krb5_lc.encryption = tmp_klc & XYKLCEN;
15095 krb5_lc.flags = tmp_klc & XYKLCFL;
15096 krb5_lc.addr = tmp_klc & XYKLCAD;
15097 break;
15098 }
15099
15100 /* Common exit - Free temporary storage */
15101
15102 kerbx:
15103 for (i = 0; i <= KRB_I_MAX; i++) { /* Free malloc'd switch data */
15104 if (pv[i].sval)
15105 free(pv[i].sval);
15106 }
15107 for (i = 0; i < KRB5_NUM_OF_ADDRS; i++) {
15108 if (tmpaddrs[i])
15109 free(tmpaddrs[i]);
15110 }
15111 if (tmpprinz) free(tmpprinz); /* And these too. */
15112 if (tmppswd) free(tmppswd);
15113 if (tmpcache) free(tmpcache);
15114 if (tmprealm) free(tmprealm);
15115 if (tmpinst) free(tmpinst);
15116
15117 return(rc); /* Return the return code */
15118 }
15119 #endif /* CK_KERBEROS */
15120
15121 #ifdef CK_LOGIN
15122 int
15123 #ifdef CK_ANSIC
ckxlogin(CHAR * userid,CHAR * passwd,CHAR * acct,int promptok)15124 ckxlogin(CHAR * userid, CHAR * passwd, CHAR * acct, int promptok)
15125 #else /* CK_ANSIC */
15126 ckxlogin(userid, passwd, acct, promptok)
15127 CHAR * userid; CHAR * passwd; CHAR * acct; int promptok;
15128 #endif /* CK_ANSIC */
15129 /* ckxlogin */ {
15130 #ifdef CK_RECALL
15131 extern int on_recall; /* around Password prompting */
15132 #endif /* CK_RECALL */
15133 #ifdef COMMENT
15134 extern int guest;
15135 #endif /* COMMENT */
15136 int rprompt = 0; /* Restore prompt */
15137 #ifdef CKSYSLOG
15138 int savlog;
15139 #endif /* CKSYSLOG */
15140
15141 extern int what, srvcdmsg;
15142
15143 int x = 0, ok = 0, rc = 0;
15144 CHAR * _u = NULL, * _p = NULL, * _a = NULL;
15145
15146 debug(F111,"ckxlogin userid",userid,promptok);
15147 debug(F110,"ckxlogin passwd",passwd,0);
15148
15149 isguest = 0; /* Global "anonymous" flag */
15150
15151 if (!userid) userid = (CHAR *)"";
15152 if (!passwd) passwd = (CHAR *)"";
15153
15154 debug(F111,"ckxlogin userid",userid,what);
15155
15156 #ifdef CK_RECALL
15157 on_recall = 0;
15158 #endif /* CK_RECALL */
15159
15160 #ifdef CKSYSLOG
15161 savlog = ckxsyslog; /* Save and turn off syslogging */
15162 #endif /* CKSYSLOG */
15163
15164 if ((!*userid || !*passwd) && /* Need to prompt for missing info */
15165 promptok) {
15166 cmsavp(psave,PROMPTL); /* Save old prompt */
15167 debug(F110,"ckxlogin saved",psave,0);
15168 rprompt = 1;
15169 }
15170 if (!*userid) {
15171 if (!promptok)
15172 return(0);
15173 cmsetp("Username: "); /* Make new prompt */
15174 concb((char)escape); /* Put console in cbreak mode */
15175 cmini(1);
15176
15177 /* Flush typeahead */
15178
15179 #ifdef IKS_OPTION
15180 debug(F101,
15181 "ckxlogin TELOPT_SB(TELOPT_KERMIT).kermit.me_start",
15182 "",
15183 TELOPT_SB(TELOPT_KERMIT).kermit.me_start
15184 );
15185 #endif /* IKS_OPTION */
15186
15187 while (ttchk() > 0) {
15188 x = ttinc(0);
15189 debug(F101,"ckxlogin flush user x","",x);
15190 if (x < 0)
15191 doexit(GOOD_EXIT,0); /* Connection lost */
15192 #ifdef TNCODE
15193 if (sstelnet) {
15194 if (x == IAC) {
15195 x = tn_doop((CHAR)(x & 0xff),ckxech,ttinc);
15196 debug(F101,"ckxlogin user tn_doop","",x);
15197 #ifdef IKS_OPTION
15198 debug(F101,
15199 "ckxlogin user TELOPT_SB(TELOPT_KERMIT).kermit.me_start",
15200 "",
15201 TELOPT_SB(TELOPT_KERMIT).kermit.me_start
15202 );
15203 #endif /* IKS_OPTION */
15204
15205 if (x < 0)
15206 goto XCKXLOG;
15207 switch (x) {
15208 case 1: ckxech = 1; break; /* Turn on echoing */
15209 case 2: ckxech = 0; break; /* Turn off echoing */
15210 #ifdef IKS_OPTION
15211 case 4: /* IKS event */
15212 if (!TELOPT_SB(TELOPT_KERMIT).kermit.me_start)
15213 break; /* else fall thru... */
15214 #endif /* IKS_OPTION */
15215 case 6: /* Logout */
15216 goto XCKXLOG;
15217 }
15218 }
15219 }
15220 #endif /* TNCODE */
15221 }
15222 if (pflag) prompt(xxstring); /* Issue prompt if at top level */
15223 cmres(); /* Reset the parser */
15224 for (x = -1; x < 0;) { /* Prompt till they answer */
15225 /* Get a literal line of text */
15226 x=cmtxt("Your username, or \"ftp\", or \"anonymous\"","",&s,NULL);
15227 if (x == -4 || x == -10) {
15228 printf("\r\n%sLogin cancelled\n",
15229 x == -10 ? "Timed out: " : "");
15230 #ifdef CKSYSLOG
15231 ckxsyslog = savlog;
15232 #endif /* CKSYSLOG */
15233 doexit(GOOD_EXIT,0);
15234 }
15235 if (sstate) /* Did a packet come instead? */
15236 goto XCKXLOG;
15237 cmres(); /* Reset the parser again */
15238 }
15239 if ((_u = (CHAR *)malloc((int)strlen(s) + 1)) == NULL) {
15240 printf("?Internal error: malloc\n");
15241 goto XCKXLOG;
15242 } else {
15243 strcpy((char *)_u,s); /* safe */
15244 userid = _u;
15245 }
15246 }
15247 ok = zvuser((char *)userid); /* Verify username */
15248 debug(F111,"ckxlogin zvuser",userid,ok);
15249
15250 if (!*passwd && promptok
15251 #ifdef COMMENT
15252 && guest
15253 #endif /* COMMENT */
15254 ) {
15255 char prmpt[80];
15256
15257 #ifdef CKSYSLOG
15258 savlog = ckxsyslog; /* Save and turn off syslogging */
15259 ckxsyslog = 0;
15260 #endif /* CKSYSLOG */
15261
15262 /* Flush typeahead again */
15263
15264 while (ttchk() > 0) {
15265 x = ttinc(0);
15266 debug(F101,"ckxlogin flush user x","",x);
15267 #ifdef TNCODE
15268 if (sstelnet) {
15269 if (x == IAC) {
15270 x = tn_doop((CHAR)(x & 0xff),ckxech,ttinc);
15271 debug(F101,"ckxlogin pass tn_doop","",x);
15272 #ifdef IKS_OPTION
15273 debug(F101,
15274 "ckxlogin pass TELOPT_SB(TELOPT_KERMIT).kermit.me_start",
15275 "",
15276 TELOPT_SB(TELOPT_KERMIT).kermit.me_start
15277 );
15278 #endif /* IKS_OPTION */
15279 if (x < 0)
15280 goto XCKXLOG;
15281 switch (x) {
15282 case 1: ckxech = 1; break; /* Turn on echoing */
15283 case 2: ckxech = 0; break; /* Turn off echoing */
15284 case 4: /* IKS event */
15285 if (!TELOPT_SB(TELOPT_KERMIT).kermit.me_start)
15286 break; /* else fall thru... */
15287 case 6: /* Logout */
15288 goto XCKXLOG;
15289 }
15290 }
15291 }
15292 #endif /* TNCODE */
15293 }
15294 if (!strcmp((char *)userid,"anonymous") ||
15295 !strcmp((char *)userid,"ftp")) {
15296 if (!ok)
15297 goto XCKXLOG;
15298 ckstrncpy(prmpt,"Enter e-mail address as Password: ",80);
15299 } else if (*userid && strlen((char *)userid) < 60) {
15300 #ifdef NT
15301 extern CHAR * pReferenceDomainName;
15302 if (pReferenceDomainName)
15303 ckmakxmsg(prmpt,
15304 80,
15305 "Enter ",
15306 pReferenceDomainName,
15307 "\\\\",
15308 userid,
15309 "'s Password: ",
15310 NULL,NULL,NULL,NULL,NULL,NULL,NULL
15311 );
15312 else
15313 #endif /* NT */
15314 ckmakmsg(prmpt,80,"Enter ",(char *)userid,"'s Password: ",NULL);
15315 } else
15316 ckstrncpy(prmpt,"Enter Password: ",80);
15317 cmsetp(prmpt); /* Make new prompt */
15318 concb((char)escape); /* Put console in cbreak mode */
15319 if (strcmp((char *)userid,"anonymous") &&
15320 strcmp((char *)userid,"ftp")) { /* and if not anonymous */
15321 debok = 0;
15322 cmini(0); /* and no-echo mode */
15323 } else {
15324 cmini(1);
15325 }
15326 if (pflag) prompt(xxstring); /* Issue prompt if at top level */
15327 cmres(); /* Reset the parser */
15328 for (x = -1; x < 0;) { /* Prompt till they answer */
15329 #ifdef CK_PAM
15330 gotemptypasswd=0;
15331 #endif /* CK_PAM */
15332 x = cmtxt("","",&s,NULL); /* Get a literal line of text */
15333 if (x == -4 || x == -10) {
15334 printf("\r\n%sLogin cancelled\n",
15335 x == -10 ? "Timed out: " : "");
15336 #ifdef CKSYSLOG
15337 ckxsyslog = savlog;
15338 #endif /* CKSYSLOG */
15339 doexit(GOOD_EXIT,0);
15340 }
15341 #ifdef CK_PAM
15342 if (!*s)
15343 gotemptypasswd = 1;
15344 #endif /* CK_PAM */
15345 if (sstate) /* In case of a Kermit packet */
15346 goto XCKXLOG;
15347 cmres(); /* Reset the parser again */
15348 }
15349 printf("\r\n"); /* Echo a CRLF */
15350 if ((_p = (CHAR *)malloc((int)strlen(s) + 1)) == NULL) {
15351 printf("?Internal error: malloc\n");
15352 goto XCKXLOG;
15353 } else {
15354 strcpy((char *)_p,s); /* safe */
15355 passwd = _p;
15356 }
15357 }
15358 #ifdef CK_PAM
15359 else {
15360 cmres(); /* Reset the parser */
15361
15362 /* We restore the prompt now because the PAM engine will call */
15363 /* readpass() which will overwrite psave. */
15364 if (rprompt) {
15365 cmsetp(psave); /* Restore original prompt */
15366 debug(F110,"ckxlogin restored",psave,0);
15367 rprompt = 0;
15368 }
15369 }
15370 #endif /* CK_PAM */
15371
15372 #ifdef CKSYSLOG
15373 ckxsyslog = savlog;
15374 #endif /* CKSYSLOG */
15375
15376 if (ok) {
15377 ok = zvpass((char *)passwd); /* Check password */
15378 debug(F101,"ckxlogin zvpass","",ok);
15379 #ifdef CK_PAM
15380 } else {
15381 /* Fake pam password failure for nonexistent users */
15382 sleep(1);
15383 printf("Authentication failure\n");
15384 #endif /* CK_PAM */
15385 }
15386
15387 if (ok > 0 && isguest) {
15388 #ifndef NOPUSH
15389 nopush = 1;
15390 #endif /* NOPUSH */
15391 srvcdmsg = 1;
15392 }
15393 rc = ok; /* Set the return code */
15394 if ((char *)uidbuf != (char *)userid)
15395 ckstrncpy(uidbuf,(char *)userid,UIDBUFLEN); /* Remember username */
15396
15397 XCKXLOG: /* Common exit */
15398 #ifdef CKSYSLOG
15399 ckxsyslog = savlog; /* In case of GOTO above */
15400 #endif /* CKSYSLOG */
15401 if (rprompt) {
15402 cmsetp(psave); /* Restore original prompt */
15403 debug(F110,"ckxlogin restored",psave,0);
15404 }
15405 if (_u || _p || _a) {
15406 if (_u) free(_u);
15407 if (_p) free(_p);
15408 if (_a) free(_a);
15409 }
15410 return(rc);
15411 }
15412
15413 int
ckxlogout()15414 ckxlogout() {
15415 doexit(GOOD_EXIT,0); /* doexit calls zvlogout */
15416 return(0); /* not reached */
15417 }
15418 #endif /* CK_LOGIN */
15419
15420 #endif /* NOICP */
15421