3 /* C K U U S 7 -- "User Interface" for C-Kermit, part 7 */
7 Frank da Cruz <fdc@columbia.edu>,
8 The Kermit Project, Columbia University, New York City
9 Jeffrey E Altman <jaltman@secure-endpoints.com>
10 Secure Endpoints Inc., New York City
12 Copyright (C) 1985, 2011,
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.
19 This file created from parts of ckuus3.c, which became too big for
20 Mark Williams Coherent compiler to handle.
24 Definitions here supersede those from system include files.
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 */
38 #endif /* TCPSOCKET */
44 #define INCL_VIO /* Needed for ckocon.h */
45 #define INCL_DOSMODULEMGR
67 #define putchar(x) conoc(x)
72 #ifdef CK_AUTHENTICATION
74 #endif /* CK_AUTHENTICATION */
80 #endif /* SSHBUILTIN */
81 #ifdef STRATUS /* Stratus Computer, Inc. VOS */
85 #define putchar(x) conoc(x)
89 #define getchar(x) coninc(0)
94 static int x, y = 0, z;
98 extern int g_matchdot, hints, xcmdsrc, rcdactive;
100 extern char * k_info_dir;
104 int gotemptypasswd = 0; /* distinguish empty passwd from none given */
106 #endif /* CK_LOGIN */
110 extern struct mtab *mactab;
115 extern short ctlp[]; /* Control-char prefixing table */
116 #endif /* CK_SPEED */
119 extern char * sndfilter, * g_sfilter;
120 extern char * rcvfilter, * g_rfilter;
121 #endif /* PIPESEND */
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;
133 extern char *binpatterns[], *txtpatterns[];
135 #endif /* PATTERNS */
137 extern char * remdest;
140 #endif /* CK_TMPDIR */
142 extern struct ck_p ptab[];
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;
153 extern int atfrmi, atfrmo;
155 extern int atcrei, atcreo, atacti, atacto;
158 extern int atlpri, atlpro, atgpri, atgpro;
159 #endif /* CK_PERMS */
162 sstate, eol, seol, stchr, mystch, mypadc, padch, ctlq, myctlq;
168 #endif /* IKSDCONF */
171 extern char *cmarg, *cmarg2;
174 extern char optbuf[]; /* Buffer for MAIL or PRINT options */
175 extern int rprintf; /* REMOTE PRINT flag */
176 #endif /* NOFRILLS */
180 extern char * tt_trigger[];
181 #endif /* CK_TRIGGER */
183 extern int tcs_transp;
185 extern int tt_pcterm;
193 int sl_ssh_xfw_saved = 0;
195 int sl_ssh_ver_saved = 0;
196 #endif /* SSHBUILTIN */
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 */
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;
228 extern int tn_wait_flg;
233 #ifdef CK_AUTHENTICATION
236 for (x = 0; x < AUTHTYPLSTSZ; x++)
237 auth_type_user[x] = sl_auth_type_user[x];
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;
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;
248 #endif /* CK_AUTHENTICATION */
251 cx_type = sl_cx_type;
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;
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;
264 #endif /* CK_ENCRYPTION */
266 ckstrncpy(uidbuf,sl_uidbuf,UIDBUFLEN);
271 tn_wait_flg = sl_tn_wait;
276 if (sl_ssh_xfw_saved) {
277 ssh_xfw = sl_ssh_xfw;
278 sl_ssh_xfw_saved = 0;
280 if (sl_ssh_ver_saved) {
281 ssh_ver = sl_ssh_ver;
282 sl_ssh_ver_saved = 0;
284 #endif /* SSHBUILTIN */
287 int oldplex = -1; /* Duplex holder around network */
291 extern int locus, autolocus;
297 /* Note: gcc -Wall wants braces around each keyword table entry. */
299 static struct keytab psltab[] = { /* SET LINE/PORT command options */
300 { "/connect", SL_CNX, 0 },
302 { "/noshare", SL_NSH, 0 },
303 #endif /* OS2ORVMS */
304 { "/server", SL_SRV, 0 },
306 { "/share", SL_SHR, 0 },
307 #endif /* OS2ORVMS */
310 static int npsltab = sizeof(psltab)/sizeof(struct keytab) - 1;
313 static struct keytab shtab[] = { /* SET HOST command options */
315 /* (COMMAND is also a network type) */
316 { "/command", SL_CMD, CM_INV },
318 { "/connect", SL_CNX, 0 },
319 { "/network-type", SL_NET, CM_ARG },
320 { "/nowait", SL_NOWAIT, 0 },
322 #ifdef CK_AUTHENTICATION
323 { "/password", SL_PSW, CM_ARG },
324 #endif /* CK_AUTHENTICATION */
327 { "/pipe", SL_CMD, 0 },
330 { "/pty", SL_PTY, 0 },
332 { "/server", SL_SRV, 0 },
333 { "/timeout", SL_TMO, CM_ARG },
334 { "/userid", SL_UID, CM_ARG },
335 { "/wait", SL_WAIT, 0 },
338 static int nshtab = sizeof(shtab)/sizeof(struct keytab) - 1;
340 static struct keytab shteltab[] = { /* TELNET command options */
341 #ifdef CK_AUTHENTICATION
342 { "/auth", SL_AUTH, CM_ARG },
343 #endif /* CK_AUTHENTICATION */
345 { "/encrypt", SL_ENC, CM_ARG },
346 #endif /* CK_ENCRYPTION */
347 { "/nowait", SL_NOWAIT, 0 },
349 #ifdef CK_AUTHENTICATION
350 { "/password", SL_PSW, CM_ARG },
351 #endif /* CK_AUTHENTICATION */
353 { "/timeout", SL_TMO, CM_ARG },
354 { "/userid", SL_UID, CM_ARG },
355 { "/wait", SL_WAIT, 0 },
358 static int nshteltab = sizeof(shteltab)/sizeof(struct keytab) - 1;
361 static struct keytab shrlgtab[] = { /* SET HOST RLOGIN command options */
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 */
377 static int nshrlgtab = sizeof(shrlgtab)/sizeof(struct keytab)-1;
378 #endif /* RLOGCODE */
380 extern struct keytab netcmd[];
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... */
393 char * n_name = NULL; /* Network name pointer */
396 _PROTOTYP(int remtxt, (char **) );
397 _PROTOTYP(VOID rmsg, (void) );
398 _PROTOTYP(static int remcfm, (void) );
402 int mdmsav = -1; /* Save modem type around network */
403 extern int isguest; /* Global flag for anonymous login */
405 extern xx_strp xxstring;
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;
413 extern struct cmdptr *cmdstk; /* The command stack itself */
415 extern struct cmdptr cmdstk[]; /* The command stack itself */
417 extern FILE * tfile[];
418 extern char * macp[];
420 extern char psave[]; /* For saving & restoring prompt */
421 extern int sprmlen, rprmlen;
424 static struct keytab strmkeytab[] = {
428 static int nstrmkeytab = sizeof(strmkeytab)/sizeof(struct keytab);
430 static struct keytab strmswitab[] = {
433 static int nstrmswitab = sizeof(strmswitab)/sizeof(struct keytab);
435 static struct keytab normrev[] = {
436 { "dark-display", 0, 0 },
437 { "light-display", 1, 0 },
442 static struct keytab prnmtab[] = {
446 { "on", 1, CM_INV }, /* Compatibility with XPRINT version */
448 { "transparent", 3, CM_INV } /* not really transparent */
450 static int nprnmtab = sizeof(prnmtab)/sizeof(struct keytab);
452 extern int tt_diff_upd;
455 #define stricmp _stricmp
456 extern int tt_attr_bug;
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];
466 int send_c1_usr = FALSE;
467 extern int sgrcolors;
468 extern int marginbell, marginbellcol;
469 extern int autoscroll, wy_autopage;
471 extern int dec_nrc, dec_lang, dec_kbd;
473 extern int tt_rows, tt_cols;
476 extern int tt_escape;
481 extern char *tp, *lp; /* Temporary buffer & pointers */
482 extern char ttname[];
485 int tttapi = 0; /* is Line TAPI? */
486 struct keytab * tapilinetab = NULL;
487 struct keytab * _tapilinetab = NULL;
491 #ifdef NETCONN /* Network items */
494 extern int revcall, closgr, cudata, nx25;
496 extern struct keytab x25tab[];
499 extern CHAR padparms[];
500 extern struct keytab padx3tab[];
507 extern bool ttslip,ttppp;
511 extern char pipename[];
515 static struct keytab tcprawtab[] = { /* SET HOST options */
516 { "/default", NP_DEFAULT, CM_INV },
517 #ifdef CK_AUTHENTICATION
520 { "/ek4login", NP_EK4LOGIN, 0 },
521 { "/ek5login", NP_EK5LOGIN, 0 },
522 { "/k4login", NP_K4LOGIN, 0 },
523 { "/k5login", NP_K5LOGIN, 0 },
524 #endif /* RLOGCODE */
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 },
534 { "/rlogin", NP_RLOGIN, 0 },
535 #endif /* RLOGCODE */
537 { "/ssl", NP_SSL, 0 },
538 { "/ssl-raw", NP_SSL_RAW, 0 },
539 { "/ssl-telnet", NP_SSL_TELNET, 0 },
541 { "/telnet", NP_TELNET, 0 },
543 { "/tls", NP_TLS, 0 },
544 { "/tls-raw", NP_TLS_RAW, 0 },
545 { "/tls-telnet", NP_TLS_TELNET, 0 },
549 static int ntcpraw = (sizeof(tcprawtab) / sizeof(struct keytab)) - 1;
552 _PROTOTYP( int rlog_naws, (void) );
553 #endif /* RLOGCODE */
554 #endif /* TCPSOCKET */
557 extern char slat_pwd[18];
558 #endif /* SUPERLAT */
565 #define mapkey(x) keymap[x]
567 extern MACRO *macrotab;
569 extern struct keytab kverbs[];
571 #endif /* NOKVERBS */
572 #endif /* NOSETKEY */
576 extern MACRO *macrotab;
578 extern struct keytab kverbs[];
580 #endif /* NOKVERBS */
581 #endif /* NOSETKEY */
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 */
591 /* Keyword tables ... */
593 extern struct keytab onoff[], rltab[];
597 static struct keytab fdfltab[] = {
598 { "7bit-character-set", 7, 0 },
599 { "8bit-character-set", 8, 0 }
601 static int nfdflt = (sizeof(fdfltab) / sizeof(struct keytab));
604 /* SET FILE parameters */
606 static struct keytab filtab[] = {
609 { "binary-patterns", XYFIBP, 0 },
610 #endif /* PATTERNS */
611 { "bytesize", XYFILS, 0 },
613 { "character-set", XYFILC, 0 },
615 { "collision", XYFILX, 0 },
616 { "default", XYF_DFLT, 0 },
617 { "destination", XYFILY, 0 },
618 { "display", XYFILD, CM_INV },
620 { "download-directory", XYFILG, 0 },
621 #endif /* CK_TMPDIR */
623 { "end-of-line", XYFILA, 0 },
624 { "eol", XYFILA, CM_INV },
626 { "eof", XYFILV, 0 },
627 #endif /* CK_CTRLZ */
629 { "fastlookups", 9997, CM_INV },
630 { "incomplete", XYFILI, 0 },
632 { "inspection", XYF_INSP, CM_INV },
633 #endif /* datageneral */
635 { "label", XYFILL, 0 },
636 #endif /* CK_LABELED */
640 { "listsize", XYF_LSIZ, 0 },
644 { "names", XYFILN, 0 },
646 { "output", XYFILH, 0 },
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 },
656 { "record-length", XYFILR, 0 },
659 { "scan", XYF_INSP, 0 },
660 #endif /* datageneral */
664 { "stringspace", XYF_SSPA, 0 },
669 { "t", XYFILT, CM_INV|CM_ABR },
670 { "text-patterns", XYFITP, 0 },
671 #endif /* PATTERNS */
673 { "type", XYFILT, 0 },
675 { "ucs", XYFILU, 0 },
678 { "warning", XYFILW, CM_INV }
681 static int nfilp = (sizeof(filtab) / sizeof(struct keytab));
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 }
690 int npathtab = (sizeof(pathtab) / sizeof(struct keytab));
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 }
700 int nrpathtab = (sizeof(rpathtab) / sizeof(struct keytab));
703 struct keytab eoftab[] = { /* EOF detection method */
706 { "noctrl-z", 0, CM_INV }
708 #endif /* CK_CTRLZ */
710 struct keytab fttab[] = { /* File types for SET FILE TYPE */
711 { "ascii", XYFT_T, CM_INV },
713 { "b", XYFT_B, CM_INV|CM_ABR },
715 { "binary", XYFT_B, 0 },
717 { "block", XYFT_I, CM_INV },
718 { "image", XYFT_I, 0 },
721 { "labeled", XYFT_L, 0 },
722 #endif /* CK_LABELED */
724 { "macbinary", XYFT_M, 0 },
726 { "text", XYFT_T, 0 }
728 int nfttyp = (sizeof(fttab) / sizeof(struct keytab));
730 static struct keytab rfttab[] = { /* File types for REMOTE SET FILE */
731 { "ascii", XYFT_T, CM_INV },
732 { "binary", XYFT_B, 0 },
734 { "labeled", XYFT_L, 0 },
737 { "labeled", XYFT_L, 0 },
740 { "text", XYFT_T, 0 }
742 static int nrfttyp = (sizeof(rfttab) / sizeof(struct keytab));
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 }
755 static int nzoftab = (sizeof(zoftab) / sizeof(struct keytab));
756 #endif /* OS2ORUNIX */
758 extern int query; /* Global flag for QUERY active */
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 }
768 static int nvartyp = (sizeof(vartyp) / sizeof(struct keytab));
773 static struct keytab timotab[] = { /* Timer types */
777 #endif /* CK_TIMERS */
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 */
785 #else /* Not DCMDBUF ... */
787 extern char atxbuf[], atmbuf[]; /* Atom buffer */
788 extern char cmdbuf[]; /* Command buffer */
789 extern char line[], tmpbuf[]; /* Character buffer for anything */
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;
803 _PROTOTYP( int os2setcp, (int) );
804 _PROTOTYP( int os2getcp, (void) );
805 _PROTOTYP( void os2debugoff, (void) );
809 extern int cmdlvl; /* Overall command level */
813 extern int *inpcas; /* INPUT CASE setting on cmd stack */
821 _PROTOTYP(int tgetent,(char *, char *));
824 _PROTOTYP(int tgetent,(char *, char *));
827 #endif /* CK_CURSES */
830 #define XMITF 0 /* SET TRANSMIT values */
831 #define XMITL 1 /* (Local to this module) */
840 extern int xmitf, xmitl, xmitp, xmitx, xmits, xmitw, xmitt;
841 char xmitbuf[XMBUFL+1] = { NUL }; /* TRANSMIT eof string */
843 struct keytab xmitab[] = { /* SET TRANSMIT */
844 { "echo", XMITX, 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 }
853 int nxmit = (sizeof(xmitab) / sizeof(struct keytab));
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. */
861 struct keytab colxtab[] = { /* SET FILE COLLISION options */
863 { "append", XYFX_A, 0 }, /* append to old file */
866 { "ask", XYFX_Q, 0 }, /* ask what to do (not implemented) */
868 { "backup", XYFX_B, 0 }, /* rename old file */
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) */
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 */
882 int ncolx = (sizeof(colxtab) / sizeof(struct keytab)) - 1;
884 static struct keytab rfiltab[] = { /* for REMOTE SET FILE */
886 { "character-set", XYFILC, 0 },
888 { "collision", XYFILX, 0 },
889 { "incomplete", XYFILI, 0 },
890 { "names", XYFILN, 0 },
891 { "record-length", XYFILR, 0 },
892 { "type", XYFILT, 0 }
894 int nrfilp = (sizeof(rfiltab) / sizeof(struct keytab));
896 struct keytab eoltab[] = { /* File eof delimiters */
898 { "crlf", XYFA_2, 0 },
901 static int neoltab = (sizeof(eoltab) / sizeof(struct keytab));
903 struct keytab fntab[] = { /* File naming */
904 { "converted", XYFN_C, 0 },
905 { "literal", XYFN_L, 0 },
906 { "standard", XYFN_C, CM_INV }
908 int nfntab = (sizeof(fntab) / sizeof(struct keytab));
911 /* Terminal parameters table */
912 static struct keytab trmtab[] = {
914 { "answerback", XYTANS, 0 },
917 { "apc", XYTAPC, 0 },
920 { "arrow-keys", XYTARR, 0 },
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 },
929 { "attribute", XYTATTR, 0 },
933 { "autodownload", XYTAUTODL, 0, },
934 #endif /* CK_AUTODL */
937 { "autopage", XYTAPAGE, 0 },
938 { "autoscroll", XYTASCRL, 0 },
939 { "bell", XYTBEL, CM_INV },
941 { "bytesize", XYTBYT, 0 },
943 { "character-set", XYTCS, 0 },
946 { "code-page", XYTCPG, 0 },
947 { "color", XYTCOL, 0 },
948 { "controls", XYTCTRL, 0 },
950 { "cr-display", XYTCRD, 0 },
952 { "cursor", XYTCUR, 0 },
954 { "debug", XYTDEB, 0 },
956 { "dg-unix-mode", XYTUNX, 0 },
958 { "echo", XYTEC, 0 },
959 { "escape-character", XYTESC, 0 },
962 { "font", XYTFON, 0 },
965 { "font", XYTFON, 0 },
969 { "height", XYTHIG, 0 },
971 { "idle-action", XYTIACT, 0 },
972 { "idle-limit", XYTITMO, CM_INV },
973 { "idle-send", XYTIDLE, CM_INV },
974 { "idle-timeout", XYTITMO, 0 },
978 { "kbd-follows-gl/gr", XYTKBDGL, 0 },
980 { "key", XYTKEY, 0 },
981 { "keyboard-mode", XYTKBMOD, 0 },
982 { "keypad-mode", XYTKPD, 0 },
984 { "lf-display", XYTLFD, 0 },
988 { "line-spacing", XYTLSP, CM_INV },
989 { "local-character-set", XYTLCS, 0 },
991 { "line-spacing", XYTLSP, 0 },
992 { "local-character-set", XYTLCS, CM_INV },
995 { "local-character-set", XYTLCS, CM_INV },
998 { "locking-shift", XYTSO, 0 },
1000 { "margin-bell", XYTMBEL, 0 },
1003 { "mouse", XYTMOU, CM_INV },
1004 #endif /* OS2MOUSE */
1005 { "newline-mode", XYTNL, 0 },
1007 { "output-pacing", XYTPAC, 0 },
1009 { "pcterm", XYTPCTERM, 0 },
1013 { "print", XYTPRN, 0 },
1014 #endif /* OS2ORUNIX */
1017 { "remote-character-set", XYTRCS, 0 },
1019 { "remote-character-set", XYTRCS, CM_INV },
1021 #endif /* NOCSETS */
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 },
1049 { "transparent-print", XYTPRN, CM_INV },
1050 #endif /* OS2ORUNIX */
1053 { "trigger", XYTRIGGER,0 },
1054 #endif /* CK_TRIGGER */
1056 { "type", XYTTYP, 0 },
1058 { "type", XYTTYP, CM_INV },
1064 { "unicode", XYTUNI, CM_INV },
1066 #endif /* UNICODE */
1067 #endif /* NOCSETS */
1069 { "unix-mode", XYTUNX, CM_INV },
1070 { "url-highlight", XYTURLHI, 0 },
1072 { "video-change", XYTVCH, 0 },
1074 { "vt-language", XYTVTLNG, 0 },
1075 { "vt-nrc-mode", XYTVTNRC, 0 },
1077 { "width", XYTWID, 0 },
1079 { "wrap", XYTWRP, 0 },
1083 int ntrm = (sizeof(trmtab) / sizeof(struct keytab)) - 1;
1086 struct keytab termctrl[] = { /* SET TERM CONTROLS */
1090 int ntermctrl = (sizeof(termctrl) / sizeof(struct keytab));
1092 struct keytab curontab[] = { /* SET TERM CURSOR */
1094 { "noblink", 2, 0 },
1096 { "noblink", 2, CM_INV },
1101 int ncuron = (sizeof(curontab) / sizeof(struct keytab));
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 }
1110 int nroll = (sizeof(rolltab) / sizeof(struct keytab));
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 }
1117 int nrollkey = (sizeof(rollkeytab) / sizeof(struct keytab));
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 }
1133 int ngraphset = (sizeof(graphsettab) / sizeof(struct keytab));
1136 struct keytab adltab[] = { /* Autodownload Options */
1137 { "ask", TAD_ASK, 0 },
1138 { "error", TAD_ERR, 0 },
1140 { "kermit", TAD_K, 0 },
1142 { "off", TAD_OFF, 0 },
1143 { "on", TAD_ON, 0 },
1145 { "zmodem", TAD_Z, 0 },
1149 int nadltab = (sizeof(adltab) / sizeof(struct keytab)) - 1;
1151 struct keytab adlerrtab[] = { /* Autodownload Error Options */
1152 { "continue", 0, 0 },
1153 { "go", 0, CM_INV },
1156 int nadlerrtab = (sizeof(adlerrtab) / sizeof(struct keytab));
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 }
1164 int nadlxtab = (sizeof(adlxtab) / sizeof(struct keytab));
1166 struct keytab adldtab[] = { /* Auto-dl Detection Methods */
1167 { "packet", ADL_PACK, 0 },
1168 { "string", ADL_STR, 0 }
1170 int nadldtab = (sizeof(adldtab) / sizeof(struct keytab));
1172 struct keytab adlc0tab[] = { /* Auto-dl Detection Methods */
1173 { "ignored-by-emulator", 0, 0 },
1174 { "processed-by-emulator", 1, 0 }
1176 int nadlc0tab = (sizeof(adlc0tab) / sizeof(struct keytab));
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 }
1210 int nvtlangtab = (sizeof(vtlangtab) / sizeof(struct keytab));
1211 #endif /* NOCSETS */
1214 struct keytab crdtab[] = { /* Carriage-return display */
1218 extern int tt_crd; /* Carriage-return display variable */
1219 extern int tt_lfd; /* Linefeed display variable */
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 }
1230 int napctab = (sizeof(apctab) / sizeof(struct keytab));
1232 #endif /* NOLOCAL */
1234 extern int autodl, adl_err, adl_ask;
1236 struct keytab beltab[] = { /* Terminal bell mode */
1238 { "audible", XYB_AUD, 0 },
1239 { "none", XYB_NONE, 0 },
1241 { "audible", XYB_AUD, CM_INV },
1242 { "none", XYB_NONE, CM_INV },
1245 { "off", XYB_NONE, CM_INV },
1246 { "on", XYB_AUD, CM_INV },
1248 { "off", XYB_NONE, 0 },
1249 { "on", XYB_AUD, 0 },
1252 { "visible", XYB_VIS, 0 },
1256 int nbeltab = sizeof(beltab)/sizeof(struct keytab) - 1;
1258 int tt_unicode = 1; /* Use Unicode if possible */
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 */
1269 OS/2 serial communication devices.
1271 struct keytab os2devtab[] = {
1272 { "1", 1, CM_INV }, /* Invisible synonyms, like */
1273 { "2", 2, CM_INV }, /* "set port 1" */
1280 { "com1", 1, 0 }, /* Real device names */
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 },
1305 #endif /* OS2ONLY */
1307 int nos2dev = (sizeof(os2devtab) / sizeof(struct keytab)) - 1;
1310 struct keytab os2ppptab[] = {
1312 { "1", 1, CM_INV }, /* Invisible synonyms, like */
1313 { "2", 2, CM_INV }, /* "set port 1" */
1322 { "ppp1", 1, 0 }, /* For use with PPP driver */
1323 { "ppp2", 2, 0 }, /* shared access */
1332 int nos2ppp = (sizeof(os2ppptab) / sizeof(struct keytab));
1333 #endif /* OS2ONLY */
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.
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 */
1361 int tt_status[VNUM] = {1,1,0,0}; /* Terminal status line displayed */
1362 int tt_status_usr[VNUM] = {1,1,0,0};
1364 extern CKFLOAT floatval;
1365 CKFLOAT tt_linespacing[VNUM] = {1.0,1.0,1.0,1.0};
1367 int tt_status[VNUM] = {1,1,0,0}; /* Terminal status line displayed */
1368 int tt_status_usr[VNUM] = {1,1,0,0};
1370 int tt_status[VNUM] = {0,0,0,0}; /* Terminal status line displayed */
1371 int tt_status_usr[VNUM] = {0,0,0,0};
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 */
1378 extern unsigned char colornormal, colorselect,
1379 colorunderline, colorstatus, colorhelp, colorborder,
1380 colorgraphic, colordebug, colorreverse, coloritalic;
1382 extern int trueblink, trueunderline, truereverse, trueitalic, truedim;
1384 extern int bgi, fgi;
1385 extern int scrninitialized[];
1387 struct keytab audibletab[] = { /* Terminal Bell Audible mode */
1388 { "beep", XYB_BEEP, 0 }, /* Values ORd with bell mode */
1389 { "system-sounds", XYB_SYS, 0 }
1391 int naudibletab = sizeof(audibletab)/sizeof(struct keytab);
1393 struct keytab akmtab[] = { /* Arrow key mode */
1394 { "application", TTK_APPL, 0 },
1395 { "cursor", TTK_NORM, 0 }
1397 struct keytab kpmtab[] = { /* Keypad mode */
1398 { "application", TTK_APPL, 0 },
1399 { "numeric", TTK_NORM, 0 }
1402 struct keytab ttcolmodetab[] = {
1403 { "current-color", 0, 0 },
1404 { "default-color", 1, 0 }
1406 int ncolmode = sizeof(ttcolmodetab)/sizeof(struct keytab);
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 */
1436 int ncolors = (sizeof(ttycoltab) / sizeof(struct keytab));
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 }
1457 int nattrib = (sizeof(ttyattrtab) / sizeof(struct keytab));
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 }
1471 int nprotect = (sizeof(ttyprotab) / sizeof(struct keytab));
1473 struct keytab ttyseobtab[] = {
1474 { "crlf_etx", 1, 0 },
1478 struct keytab ttyclrtab[] = { /* Colors */
1483 { "darkgray", 8, CM_INV },
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 },
1503 int nclrs = (sizeof (ttyclrtab) / sizeof (struct keytab));
1505 struct keytab ttycurtab[] = {
1506 { "full", TTC_BLOCK, 0 },
1507 { "half", TTC_HALF, 0 },
1508 { "underline", TTC_ULINE, 0 }
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 */
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.
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.
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.
1567 { "tek4014", TT_TEK40, 0 },
1568 #endif /* COMMENT */
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 },
1585 { "vtnt", TT_VTNT, 0 },
1587 { "vtnt", TT_VTNT, CM_INV },
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 }
1599 int nttyp = (sizeof(ttyptab) / sizeof(struct keytab));
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 */
1638 { "tek4014", TT_TEK40, 0 },
1639 #endif /* COMMENT */
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 }
1667 int nttkey = (sizeof(ttkeytab) / sizeof(struct keytab));
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 },
1679 int nkbmodtab = (sizeof(kbmodtab) / sizeof(struct keytab));
1680 #endif /* NOSETKEY */
1681 #endif /* NOLOCAL */
1683 int tt_inpacing = 0; /* input-pacing (none) */
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 }
1691 int nprty = (sizeof(prtytab) / sizeof(struct keytab));
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 }
1705 int nwin95 = (sizeof(win95tab) / sizeof(struct keytab));
1709 extern int wideresult;
1710 int tt_mouse = 1; /* Terminal mouse on/off */
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 }
1718 int nmtab = (sizeof(mousetab)/sizeof(struct keytab));
1720 struct keytab mousebuttontab[] = { /* event button */
1724 { "one", XYM_B1, CM_INV },
1725 { "three", XYM_B3, CM_INV },
1726 { "two", XYM_B2, CM_INV }
1728 int nmbtab = (sizeof(mousebuttontab) / sizeof(struct keytab));
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 },
1738 { "shift", XYM_SHIFT, 0 }
1740 int nmmtab = (sizeof(mousemodtab) / sizeof(struct keytab));
1742 struct keytab mclicktab[] = { /* event button click modifier */
1743 { "click", XYM_C1, 0 },
1744 { "drag", XYM_DRAG, 0 },
1745 { "double-click", XYM_C2, 0 }
1747 int nmctab = (sizeof(mclicktab) / sizeof(struct keytab));
1751 extern struct keytab kverbs[];
1752 #endif /* NOKVERBS */
1753 #endif /* OS2MOUSE */
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 */
1760 int nfbtyp = (sizeof(fbtab) / sizeof(struct keytab));
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 }
1771 int nlblp = (sizeof(lbltab) / sizeof(struct keytab));
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 }
1781 int nlblp = (sizeof(lbltab) / sizeof(struct keytab));
1787 static struct keytab fdftab[] = { /* SET FILE DISPLAY FULL options */
1788 { "thermometer", 1, 0, },
1789 { "no-thermometer", 0, 0 }
1791 extern int thermometer;
1792 #endif /* CK_PCT_BAR */
1793 #endif /* CK_CURSES */
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 },
1803 { "brief", XYFD_B, 0 }, /* Brief */
1804 { "crt", XYFD_S, 0 }, /* CRT display */
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 */
1812 { "gui", XYFD_G, 0 }, /* GUI */
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 */
1822 int nfdtab = (sizeof(fdtab) / sizeof(struct keytab)) - 1;
1824 struct keytab rsrtab[] = { /* For REMOTE SET RECEIVE */
1825 { "packet-length", XYLEN, 0 },
1826 { "timeout", XYTIMO, 0 }
1828 int nrsrtab = (sizeof(rsrtab) / sizeof(struct keytab));
1830 /* Send/Receive Parameters */
1832 struct keytab srtab[] = {
1833 { "backup", XYBUP, 0 },
1835 { "character-set-selection", XYCSET, 0 },
1836 #endif /* NOCSETS */
1837 { "control-prefix", XYQCTL, 0 },
1839 { "double-character", XYDBL, 0 },
1840 #endif /* CKXXCHAR */
1841 { "end-of-packet", XYEOL, 0 },
1843 { "filter", XYFLTR, 0 },
1844 #endif /* PIPESEND */
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 },
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 },
1864 { "version-numbers", 887, 0 }, /* VMS version numbers */
1868 int nsrtab = (sizeof(srtab) / sizeof(struct keytab)) - 1;
1873 static struct keytab ucstab[] = {
1874 { "bom", UCS_BOM, 0 },
1875 { "byte-order", UCS_BYT, 0 },
1878 int nucstab = (sizeof(ucstab) / sizeof(struct keytab)) - 1;
1880 static struct keytab botab[] = {
1881 { "big-endian", 0, 0 },
1882 { "little-endian", 1, 0 }
1884 static int nbotab = 2;
1885 #endif /* UNICODE */
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 }
1902 int nrms = (sizeof(rmstab) / sizeof(struct keytab));
1904 struct keytab attrtab[] = {
1906 { "account", AT_ACCT, 0 },
1907 #endif /* STRATUS */
1908 { "all", AT_XALL, 0 },
1910 { "blocksize", AT_BLKS, 0 }, /* (not used) */
1911 #endif /* COMMENT */
1913 { "character-set", AT_ENCO, 0 },
1914 #endif /* NOCSETS */
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 },
1926 { "os-specific", AT_SYSP, 0 }, /* (not used by UNIX or VMS) */
1927 #endif /* COMMENT */
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 }
1936 int natr = (sizeof(attrtab) / sizeof(struct keytab)); /* how many attributes */
1939 struct keytab idlacts[] = {
1940 { "exit", IDLE_EXIT, 0 },
1941 { "hangup", IDLE_HANG, 0 },
1942 { "output", IDLE_OUT, 0 },
1943 { "return", IDLE_RET, 0 },
1945 { "telnet-nop", IDLE_TNOP, 0 },
1946 { "telnet-ayt", IDLE_TAYT, 0 },
1950 int nidlacts = (sizeof(idlacts) / sizeof(struct keytab)) - 1;
1951 #endif /* CKTIDLE */
1954 extern int indef, inecho, insilence, inbufsize, inautodl, inintr;
1956 extern CKFLOAT inscale;
1957 #endif /* CKFLOAT */
1958 extern char * inpbuf, * inpbp;
1962 struct keytab inptab[] = { /* SET INPUT parameters */
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 },
1972 { "pacing", IN_PAC, CM_INV },
1974 { "scale-factor", IN_SCA, 0 },
1975 { "silence", IN_SIL, 0 },
1977 { "terminal", IN_TRM, 0 },
1979 { "timeout-action", IN_TIM, 0 }
1981 int ninp = (sizeof(inptab) / sizeof(struct keytab));
1983 struct keytab intimt[] = { /* SET INPUT TIMEOUT parameters */
1984 { "proceed", 0, 0 }, /* 0 = proceed */
1985 { "quit", 1, 0 } /* 1 = quit */
1988 struct keytab incast[] = { /* SET INPUT CASE parameters */
1989 { "ignore", 0, 0 }, /* 0 = ignore */
1990 { "observe", 1, 0 } /* 1 = observe */
1994 struct keytab nabltab[] = { /* For any command that needs */
1995 { "disabled", 0, 0 },
1996 { "enabled", 1, 0 },
1997 { "off", 0, CM_INV }, /* these keywords... */
2000 int nnabltab = sizeof(nabltab) / sizeof(struct keytab);
2003 struct keytab tvctab[] = { /* SET TERM VIDEO-CHANGE */
2004 { "disabled", TVC_DIS, 0 },
2005 { "enabled", TVC_ENA, 0 },
2007 { "win95-safe", TVC_W95, 0 },
2011 int ntvctab = (sizeof(tvctab) / sizeof(struct keytab)) - 1;
2013 struct keytab msktab[] = { /* SET MS-DOS KERMIT compatibilities */
2015 { "color", MSK_COLOR, 0 },
2016 #endif /* COMMENT */
2017 { "file-renaming", MSK_REN, 0 },
2018 { "keycodes", MSK_KEYS, 0 }
2020 int nmsk = (sizeof(msktab) / sizeof(struct keytab));
2022 struct keytab scrnupd[] = { /* SET TERMINAL SCREEN-UPDATE */
2023 { "fast", TTU_FAST, 0 },
2024 { "smooth", TTU_SMOOTH, 0 }
2026 int nscrnupd = (sizeof(scrnupd) / sizeof(struct keytab));
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 */
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 },
2040 { "cp851", TTF_851, 0 },
2041 #endif /* COMMENT */
2042 { "cp852", TTF_852, 0 },
2044 { "cp853", TTF_853, 0 },
2045 { "cp860", TTF_860, 0 },
2046 { "cp861", TTF_861, 0 },
2047 #endif /* COMMENT */
2048 { "cp862", TTF_862, 0 },
2050 { "cp863", TTF_863, 0 },
2051 { "cp864", TTF_864, 0 },
2052 { "cp865", TTF_865, 0 },
2053 #endif /* COMMENT */
2054 { "cp866", TTF_866, 0 },
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 }
2065 int ntermfont = (sizeof(term_font) / sizeof(struct keytab));
2066 int tt_font = TTF_ROM; /* Terminal screen font */
2070 struct keytab * term_font = NULL;
2071 struct keytab * _term_font = NULL;
2072 char * tt_facename = NULL;
2075 int tt_font_size = 0;
2078 #endif /* PCFONTS */
2080 struct keytab anbktab[] = { /* For any command that needs */
2081 { "message", 2, 0 }, /* these keywords... */
2084 { "unsafe-messag0", 99, CM_INV },
2085 { "unsafe-message", 3, CM_INV }
2087 int nansbk = (sizeof(anbktab) / sizeof(struct keytab));
2089 int win95_popup = 1;
2092 int win95lucida = 0;
2095 int win95lucida = 1;
2099 int win95lucida = 0;
2104 extern int win95selectbug;
2105 extern int win95_8_3;
2108 extern CHAR (*xlr[MAXTCSETS+1][MAXFCSETS+1])(CHAR);
2109 extern struct keytab tcstab[];
2111 #endif /* COMMENT */
2112 extern int maxow, maxow_usr; owwait; /* Overlapped I/O variables */
2117 /* The following routines broken out of doprm() to give compilers a break. */
2119 /* S E T O N -- Parse on/off (default on), set parameter to result */
2122 seton(prm) int *prm; {
2124 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
2125 if ((x = cmcfm()) < 0) return(x);
2130 /* S E T O N A U T O -- Parse on/off/auto (default auto) & set result */
2132 struct keytab onoffaut[] = {
2133 { "auto", SET_AUTO, 0 }, /* 2 */
2134 { "off", SET_OFF, 0 }, /* 0 */
2135 { "on", SET_ON, 0 } /* 1 */
2139 setonaut(prm) int *prm; {
2141 if ((y = cmkey(onoffaut,3,"","auto",xxstring)) < 0) return(y);
2142 if ((x = cmcfm()) < 0) return(x);
2147 /* S E T N U M -- Set parameter to result of cmnum() parse. */
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.
2155 setnum(prm,x,y,max) int x, y, *prm, max; {
2156 debug(F101,"setnum","",y);
2158 printf("\n?Value required\n");
2162 printf("%s?Not a number: %s\n",cmflgs == 1 ? "" : "\n", atxbuf);
2165 if (y < 0) return(y);
2166 if (max > -1 && x > max) {
2167 printf("?Sorry, %d is the maximum\n",max);
2170 if ((y = cmcfm()) < 0) return(y);
2175 /* S E T C C -- Set parameter var to an ASCII control character value. */
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.
2183 setcc(dflt,var) char *dflt; int *var; {
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";
2191 /* This is a hack to turn off complaints from expression evaluator. */
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 */
2199 /* Real control character or literal 8-bit character... */
2201 for (c = strlen(atmbuf) - 1; c > 0; c--) /* Trim */
2202 if (atmbuf[c] == SP) atmbuf[c] = NUL;
2204 if (y < 0) { /* It was not a number */
2205 if (((c = atmbuf[0])) && !atmbuf[1]) { /* Literal character? */
2207 if (((c > 31) && (c < 127)) || (c > 255)) {
2208 printf("\n?%d: Out of range - must be 0-31 or 127-255\n",c);
2211 if ((y = cmcfm()) < 0) /* Confirm */
2213 *var = c; /* Set the variable */
2216 } else if (atmbuf[0] == '^' && !atmbuf[2]) { /* Or ^X notation? */
2218 if (islower((char) c)) /* Uppercase lowercase letters */
2220 if (c > 62 && c < 96) { /* Check range */
2221 if ((y = cmcfm()) < 0)
2223 *var = ctl(c); /* OK */
2226 printf("?Not a control character - %s\n", atmbuf);
2229 } else { /* Something illegal was typed */
2230 printf("?Invalid - %s\n", atmbuf);
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);
2238 if ((y = cmcfm()) < 0) /* In range, confirm */
2240 *var = x; /* Set variable */
2244 #ifndef NOSPL /* The SORT command... */
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 }
2253 static int nsrtswtab = sizeof(srtswtab)/sizeof(struct keytab);
2255 extern char **a_ptr[]; /* Array pointers */
2256 extern int a_dim[]; /* Array dimensions */
2259 dosort() { /* Do the SORT command */
2260 char c, *p = NULL, ** ap, ** xp = NULL;
2261 struct FDB sw, fl, cm;
2263 int xn = 0, xr = -1, xk = -1, xc = -1, xs = 0;
2264 int getval = 0, range[2], confirmed = 0;
2266 cmfdbi(&sw, /* First FDB - command switches */
2268 "Array name or switch",
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 */
2277 cmfdbi(&fl, /* Anything that doesn't match */
2279 "Array name", /* hlpmsg */
2281 "", /* addtl string data */
2282 0, /* addtl numeric data 1 */
2283 0, /* addtl numeric data 2 */
2288 cmfdbi(&cm, /* Or premature confirmation */
2292 "", /* addtl string data */
2293 0, /* addtl numeric data 1 */
2294 0, /* addtl numeric data 2 */
2303 while (1) { /* Parse 0 or more switches */
2307 if (cmresult.fcode != _CMKEY) /* Break out if not a switch */
2310 getval = (c == ':' || c == '=');
2311 if (getval && !(cmresult.kflags & CM_ARG)) {
2312 printf("?This switch does not take arguments\n");
2315 switch (cmresult.nresult) {
2321 if ((y = cmnum("Column for comparison (1-based)",
2322 "1",10,&x,xxstring)) < 0)
2330 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0)
2336 case SRT_RNG: /* /RANGE */
2342 if ((y = cmfld("low:high element","1",&s,NULL)) < 0)
2345 ckstrncpy(buf,s,32);
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 */
2357 y = 15; /* Evaluate this piece */
2361 if (s) if (*s) ckstrncpy(buf2,s,16);
2362 if (!rdigits(buf2)) {
2363 printf("?Not numeric: %s\n",buf2);
2366 range[i] = atoi(buf2);
2370 case SRT_NUM: /* /NUMERIC */
2377 switch (cmresult.fcode) {
2382 ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Safe copy of name */
2386 printf("?Unexpected function code: %d\n",cmresult.fcode);
2390 printf("?Array name required\n");
2393 ckmakmsg(tmpbuf,TMPBUFSIZ,
2394 "Second array to sort according to ",s,NULL,NULL);
2395 if ((x = cmfld(tmpbuf,"",&p,NULL)) < 0)
2399 ckstrncpy(tmpbuf,p,TMPBUFSIZ);
2401 if ((x = cmcfm()) < 0) /* Get confirmation */
2404 x = arraybounds(s,&lo,&hi); /* Get array index & bounds */
2405 if (x < 0) { /* Check */
2406 printf("?Bad array name: %s\n",s);
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);
2416 if (range[0] < 0) /* Starting element */
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]
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]);
2432 if (xk < 0) xk = 0; /* Key position */
2433 if (xr < 0) xr = 0; /* Reverse flag */
2434 if (xn) /* Numeric flag */
2436 else if (xc < 0) /* Not numeric */
2437 xc = inpcas[cmdlvl]; /* so alpha case option */
2439 if (*p) { /* Parallel array given? */
2440 y = xarray(p); /* Yes, get its index. */
2442 printf("?Bad array name: %s\n", p);
2445 if (y != x) { /* If the 2 arrays are different */
2446 xp = a_ptr[y]; /* Pointer to 2nd array element list */
2448 printf("?Array not declared: %s\n", p);
2451 if (a_dim[y] < range[1]) {
2452 printf("?Array %s smaller than %s\n", p, s);
2455 xp += range[0]; /* Set base to same as 1st array */
2458 sh_sort(ap,xp,xs,xk,xr,xc); /* Sort the array(s) */
2459 return(success = 1); /* Always succeeds */
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 },
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 },
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 },
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 },
2493 { "/page", PU_PAGE, 0 },
2494 #endif /* CK_TTGWSIZ */
2495 { "/quiet", PU_QUIE, CM_INV },
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 }
2504 static int npurgtab = sizeof(purgtab)/sizeof(struct keytab);
2511 bkupnum(s,i) char * s; int *i; {
2513 char * p = NULL, *q;
2518 if ((k = strlen(s)) < 5)
2525 while (q >= s && isdigit(*q)) {
2533 if (*q != '~' || *(q-1) != '.')
2537 debug(F111,"bkupnum",s+pos,pos);
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. */
2545 #define MAXKEEP 32 /* Biggest /KEEP: value */
2548 pu_keep = 0, pu_list = 0, pu_dot = 0, pu_ask = 0, pu_hdg = 0;
2551 static int pu_page = -1;
2553 static int pu_page = 0;
2554 #endif /* CK_TTGWSIZ */
2558 showpurgopts() { /* SHOW PURGE command options */
2560 extern int optlines;
2561 prtopt(&optlines,"PURGE");
2564 prtopt(&optlines, pu_ask ? "/ASK" : "/NOASK");
2569 prtopt(&optlines, pu_dot ? "/DOTFILES" : "/NODOTFILES");
2571 #endif /* UNIXOROSK */
2574 ckmakmsg(tmpbuf,TMPBUFSIZ,"/KEEP:",ckitoa(pu_keep),NULL,NULL);
2575 prtopt(&optlines,tmpbuf);
2579 prtopt(&optlines, pu_list ? "/LIST" : "/NOLIST");
2583 prtopt(&optlines, pu_hdg ? "/HEADING" : "/NOHEADING");
2588 prtopt(&optlines, pu_page ? "/PAGE" : "/NOPAGE");
2590 #endif /* CK_TTGWSIZ */
2591 if (!x) prtopt(&optlines,"(no options set)");
2592 prtopt(&optlines,"");
2597 setpurgopts() { /* Set PURGE command options */
2598 int c, z, getval = 0;
2600 x_keep = -1, x_list = -1, x_page = -1,
2601 x_hdg = -1, x_ask = -1, x_dot = -1;
2604 if ((y = cmswi(purgtab,npurgtab,"Switch","",xxstring)) < 0) {
2611 if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
2612 printf("?This switch does not take an argument\n");
2615 if (!getval && (cmgkwflgs() & CM_ARG)) {
2616 printf("?This switch requires an argument\n");
2622 if (c == ':' || c == '=')
2623 if ((y = cmnum("How many backup files to keep",
2624 "1",10,&z,xxstring)) < 0)
2626 if (z < 0 || z > MAXKEEP) {
2627 printf("?Please specify a number between 0 and %d\n",
2649 #endif /* CK_TTGWSIZ */
2669 #endif /* UNIXOROSK */
2671 printf("?This option can not be set\n");
2675 if ((x = cmcfm()) < 0) /* Get confirmation */
2677 if (x_keep > -1) /* Set PURGE defaults. */
2684 #endif /* CK_TTGWSIZ */
2691 return(success = 1);
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 */
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];
2715 char * pxlist[8]; /* Exception list */
2717 if (pu_keep > -1) /* Set PURGE defaults. */
2724 #endif /* CK_TTGWSIZ */
2726 for (i = 0; i <= MAXKEEP; i++) /* Clear this number buffer */
2728 for (i = 0; i < 8; i++) /* Initialize these... */
2731 g_matchdot = matchdot; /* Save these... */
2733 cmfdbi(&sw, /* 1st FDB - PURGE switches */
2735 "Filename or switch", /* hlpmsg */
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 */
2744 cmfdbi(&sf, /* 2nd FDB - filespec to purge */
2748 "", /* addtl string data */
2749 0, /* addtl numeric data 1 */
2750 0, /* addtl numeric data 2 */
2755 cmfdbi(&cm, /* Or premature confirmation */
2759 "", /* addtl string data */
2760 0, /* addtl numeric data 1 */
2761 0, /* addtl numeric data 2 */
2767 while (!havename && !confirmed) {
2768 x = cmfdb(&sw); /* Parse something */
2769 if (x < 0) { /* Error */
2772 } else if (cmresult.fcode == _CMKEY) {
2775 if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
2776 printf("?This switch does not take an argument\n");
2780 if (!getval && (cmgkwflgs() & CM_ARG)) {
2781 printf("?This switch requires an argument\n");
2785 switch (k = cmresult.nresult) {
2788 if (c == ':' || c == '=') {
2789 if ((y = cmnum("How many backup files to keep",
2790 "1",10,&z,xxstring)) < 0) {
2795 if (z < 0 || z > MAXKEEP) {
2796 printf("?Please specify a number between 0 and %d\n",
2817 #endif /* CK_TTGWSIZ */
2836 if ((x = cmdate("File-time","",&s,0,xxstring)) < 0) {
2838 printf("?Date-time required\n");
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;
2854 if ((x = cmnum("File size in bytes","0",10,&y,xxstring)) < 0) {
2859 switch (cmresult.nresult) {
2860 case PU_SMA: minsize = y; break;
2861 case PU_LAR: maxsize = y; break;
2871 if ((x = cmfld("Pattern","",&s,xxstring)) < 0) {
2873 printf("?Pattern required\n");
2886 case PU_RECU: /* /RECURSIVE */
2889 #endif /* RECURSIVE */
2891 printf("?Not implemented yet - \"%s\"\n",atmbuf);
2895 } else if (cmresult.fcode == _CMIFI) {
2897 } else if (cmresult.fcode == _CMCFM) {
2906 ckmakmsg(line,LINBUFSIZ,cmresult.sresult,".~[1-9]*~",NULL,NULL);
2908 ckmakmsg(line,LINBUFSIZ,cmresult.sresult,".~*~",NULL,NULL);
2909 #endif /* CKREGEX */
2912 ckstrncpy(line,"*.~[1-9]*~",LINBUFSIZ);
2914 ckstrncpy(line,"*.~*~",LINBUFSIZ);
2915 #endif /* CKREGEX */
2918 if ((x = cmcfm()) < 0) {
2923 /* Parse finished - now action */
2927 printf("?File deletion by guests not permitted.\n");
2931 #endif /* CK_LOGIN */
2934 if (paging < 0) /* /[NO]PAGE not given */
2935 paging = xaskmore; /* so use prevailing */
2936 #endif /* CK_TTGWSIZ */
2940 printf("Purging %s, keeping %d...%s\n",
2943 simulate ? " (SIMULATION)" : "");
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) {
2955 printf(" %s (SKIPPED)\n",mtchs[i]);
2958 if (++lines > cmd_rows - 3) {
2959 if (!askmore()) goto xpurge; else lines = 0;
2961 #endif /* CK_TTGWSIZ */
2967 ckmakmsg(tmpbuf,TMPBUFSIZ," Delete ",mtchs[i],"?",NULL);
2968 x = getyesno(tmpbuf,1);
2972 case 2: goto xpurge;
2975 x = deleting ? zdelet(mtchs[i]) : 0;
2978 printf(" %s (%s)\n", mtchs[i],deleting ? "OK" : "SELECTED");
2983 printf(" %s (FAILED)\n", mtchs[i]);
2986 if (listing && paging)
2987 if (++lines > cmd_rows - 3) {
2988 if (!askmore()) goto xpurge; else lines = 0;
2990 #endif /* CK_TTGWSIZ */
2994 if (n < tokeep) { /* Not deleting any */
2997 printf(" Matches = %d: Not enough to purge.\n",n);
3001 /* General case - delete some but not others */
3003 sh_sort(mtchs,NULL,n,0,0,filecase); /* Alphabetize the list (ESSENTIAL) */
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) {
3014 printf(" %s (SKIPPED)\n",namebuf);
3015 if (++lines > cmd_rows - 3)
3016 if (!askmore()) goto xpurge; else lines = 0;
3021 if ((m = bkupnum(namebuf,&z)) < 0) /* This file's backup number. */
3023 for (j = 0; j < tokeep; j++) { /* Insert in list. */
3025 for (k = tokeep - 1; k > j; k--)
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++;
3042 printf(" %s (%s)\n",
3044 ((x < 0) ? "ERROR" :
3045 (deleting ? "DELETED" : "SELECTED"))
3048 } else if (listing) /* Not below minimum - keep this one */
3049 printf(" %s (KEPT)\n",mtchs[j]);
3051 if (listing && paging)
3052 if (++lines > cmd_rows - 3) {
3053 if (!askmore()) goto xpurge; else lines = 0;
3055 #endif /* CK_TTGWSIZ */
3057 } else if (listing && paging) { /* Not enough to purge */
3058 printf(" %s.~*~ (KEPT)\n",basebuf);
3060 if (++lines > cmd_rows - 3) {
3061 if (!askmore()) goto xpurge; else lines = 0;
3063 #endif /* CK_TTGWSIZ */
3065 for (j = 0; j < tokeep; j++) /* Clear the backup number list */
3067 g = i; /* Reset the group pointer */
3069 if (done) /* No more files, done. */
3071 strncpy(basebuf,namebuf,z); /* Set basename of this file */
3074 xpurge: /* Common exit point */
3075 if (g_matchdot > -1) {
3076 matchdot = g_matchdot; /* Restore these... */
3079 if (rc < 0) return(rc); /* Parse error */
3081 printf("Files purged: %d%s\n",
3083 deleting ? "" : " (not really)"
3085 return(success = count > 0 ? 1 : (errors > 0) ? 0 : 1);
3087 #endif /* CKPURGE */
3092 doxdis(which) int which; { /* 1 = Kermit, 2 = FTP */
3101 #endif /* COMMENT */
3103 if ((x = cmkey(fdtab,nfdtab,"file transfer display style","",
3107 if ((y = cmkey(fdftab,2,"","thermometer",xxstring)) < 0)
3109 #endif /* CK_PCT_BAR */
3110 if ((z = cmcfm()) < 0) return(z);
3112 if (x == XYFD_C) { /* FULLSCREEN */
3115 extern char * trmbuf; /* Real curses */
3117 #endif /* MYCURSES */
3118 #endif /* COMMENT */
3120 if (nolocal) /* Nothing to do in this case */
3121 return(success = 1);
3127 debug(F110,"doxdis TERM",s,0);
3130 if (*s && trmbuf) { /* Don't call tgetent */
3131 z = tgetent(trmbuf,s); /* if trmbuf not allocated */
3132 debug(F111,"doxdis tgetent",s,z);
3135 debug(F110,"doxdis tgetent skipped",s,0);
3138 printf("Sorry, terminal type unknown: \"%s\"\n",s);
3139 return(success = 0);
3142 #endif /* MYCURSES */
3145 #endif /* COMMENT */
3149 #endif /* CK_PCT_BAR */
3151 line[0] = '\0'; /* (What's this for?) */
3153 #endif /* CK_CURSES */
3154 if (which == 1) /* It's OK. */
3157 else if (which == 2)
3160 return(success = 1);
3162 #endif /* NOLOCAL */
3166 setfil(rmsflg) int rmsflg; {
3169 #endif /* COMMENT */
3172 if ((y = cmkey(rfiltab,nrfilp,"Remote file parameter","",
3175 printf("?Remote file parameter required\n");
3181 if ((y = cmkey(filtab,nfilp,"File parameter","",xxstring)) < 0)
3187 #ifdef COMMENT /* Not needed */
3188 case XYFILB: /* Blocksize */
3189 if ((y = cmnum("file block size",ckitoa(DBLKSIZ),10,&z,xxstring)) < 0)
3191 if ((x = cmcfm()) < 0) return(x);
3193 sstate = setgen('S', "311", ckitoa(z), "");
3194 return((int) sstate);
3197 return(success = 1);
3199 #endif /* COMMENT */
3202 case XYFILS: /* Byte size */
3203 if ((y = cmnum("file byte size (7 or 8)","8",10,&z,xxstring)) < 0)
3205 if (z != 7 && z != 8) {
3206 printf("\n?The choices are 7 and 8\n");
3209 if ((y = cmcfm()) < 0) return(y);
3210 if (z == 7) fmask = 0177;
3211 else if (z == 8) fmask = 0377;
3212 return(success = 1);
3215 case XYFILC: { /* Character set */
3216 char * csetname = NULL;
3218 r_cset, s_cset, afcset[]; /* SEND CHARACTER-SET AUTO or MANUAL */
3221 cmfdbi(&kw, /* First FDB - command switches */
3223 rmsflg ? "server character-set name" : "", /* help */
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 */
3232 cmfdbi(&fl, /* Anything that doesn't match */
3236 "", /* addtl string data */
3237 0, /* addtl numeric data 1 */
3238 0, /* addtl numeric data 2 */
3243 if ((x = cmfdb(&kw)) < 0)
3245 if (cmresult.fcode == _CMKEY) {
3246 x = cmresult.nresult;
3247 csetname = fcsinfo[x].keyword;
3249 ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
3252 if ((z = cmcfm()) < 0) return(z);
3254 sstate = setgen('S', "320", csetname, "");
3255 return((int) sstate);
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... */
3268 else if (x == 256) /* 8-bit... */
3270 return(success = 1);
3272 #endif /* NOCSETS */
3275 case XYFILD: /* Display */
3276 return(doxdis(1)); /* 1 == kermit */
3277 #endif /* NOLOCAL */
3280 case XYFILA: /* End-of-line */
3285 else if (NLCHAR == 012)
3287 if ((x = cmkey(eoltab, neoltab,
3288 "local text-file line terminator",s,xxstring)) < 0)
3291 if ((x = cmkey(eoltab, neoltab,
3292 "local text-file line terminator","crlf",xxstring)) < 0)
3295 if ((z = cmcfm()) < 0) return(z);
3297 return(success = 1);
3300 case XYFILN: /* Names */
3301 if ((x = cmkey(fntab,nfntab,"how to handle filenames","converted",
3304 if ((z = cmcfm()) < 0) return(z);
3306 sstate = setgen('S', "301", ckitoa(1 - x), "");
3307 return((int) sstate);
3309 ptab[protocol].fncn = x; /* Set structure */
3310 fncnv = x; /* Set variable */
3311 f_save = x; /* And set "permanent" variable */
3312 return(success = 1);
3315 case XYFILR: /* Record length */
3316 if ((y = cmnum("file record length",
3317 ckitoa(DLRECL),10,&z,xxstring)) < 0)
3319 if ((x = cmcfm()) < 0) return(x);
3321 sstate = setgen('S', "312", ckitoa(z), "");
3322 return((int) sstate);
3325 return(success = 1);
3329 case XYFILO: /* Organization */
3330 if ((x = cmkey(forgtab,nforg,"file organization","sequential",
3333 if ((y = cmcfm()) < 0) return(y);
3335 sstate = setgen('S', "314", ckitoa(x), "");
3336 return((int) sstate);
3339 return(success = 1);
3341 #endif /* COMMENT */
3343 #ifdef COMMENT /* Not needed */
3344 case XYFILF: /* Format */
3345 if ((x = cmkey(frectab,nfrec,"file record format","stream",
3348 if ((y = cmcfm()) < 0) return(y);
3350 sstate = setgen('S', "313", ckitoa(x), "");
3351 return((int) sstate);
3354 return(success = 1);
3356 #endif /* COMMENT */
3359 case XYFILP: /* Printer carriage control */
3360 if ((x = cmkey(fcctab,nfcc,"file carriage control","newline",
3363 if ((y = cmcfm()) < 0) return(y);
3365 sstate = setgen('S', "315", ckitoa(x), "");
3366 return((int) sstate);
3369 return(success = 1);
3371 #endif /* COMMENT */
3374 case XYFILT: /* Type */
3375 if ((x = cmkey(rmsflg ? rfttab : fttab,
3376 rmsflg ? nrfttyp : nfttyp,
3377 "type of file transfer","text",xxstring)) < 0)
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",
3388 if ((y = cmcfm()) < 0) return(y);
3392 (void) mac_setfildflg(binary);
3396 /* Allow for LABELED in VMS & OS/2 */
3397 sstate = setgen('S', "300", ckitoa(x), "");
3398 return((int) sstate);
3401 return(success = 1);
3407 case XYFILX: /* Collision Action */
3408 if ((x = cmkey(colxtab,ncolx,"Filename collision action","backup",
3411 if ((y = cmcfm()) < 0) return(y);
3414 /* Don't let guests change existing files */
3415 printf("?This command not valid for guests\n");
3418 #endif /* CK_LOGIN */
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");
3426 #endif /* COMMENT */
3428 ptab[protocol].fnca = x;
3430 sstate = setgen('S', "302", ckitoa(fncact), "");
3431 return((int) sstate);
3433 if (fncact == XYFX_R) ckwarn = 1; /* FILE WARNING implications */
3434 if (fncact == XYFX_X) ckwarn = 0; /* ... */
3435 return(success = 1);
3438 case XYFILW: /* Warning/Write-Protect */
3439 if ((x = seton(&ckwarn)) < 0) return(x);
3444 return(success = 1);
3447 case XYFILL: /* LABELED FILE parameters */
3448 if ((x = cmkey(lbltab,nlblp,"Labeled file feature","",
3451 if ((success = seton(&y)) < 0)
3453 if (y) /* Set or reset the selected bit */
3454 lf_opts |= x; /* in the options bitmask. */
3458 #endif /* CK_LABELED */
3460 case XYFILI: { /* INCOMPLETE */
3461 extern struct keytab ifdatab[];
3463 if ((y = cmkey(ifdatab,3,"","auto",xxstring)) < 0) return(y);
3464 if ((x = cmcfm()) < 0) return(x);
3466 sstate = setgen('S',
3468 y == 0 ? "0" : (y == 1 ? "1" : "2"),
3471 return((int) sstate);
3474 return(success = 1);
3479 case XYFILG: { /* Download directory */
3490 if ((x = cmdir("Name of local directory, or carriage return",
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 ) {
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 )
3513 if ((x = cmdir("Name of local directory, or carriage return",
3514 "", &s, xxstring)) < 0 ) {
3521 debug(F110,"download dir",s,0);
3525 printf("?Wildcards not allowed in directory name\n");
3531 if ((fnp = zfnqfp(s,TMPBUFSIZ - 1,tmpbuf))) {
3533 if ((int) strlen(fnp->fpath) > 0)
3536 debug(F110,"download zfnqfp",s,0);
3539 ckstrncpy(line,s,LINBUFSIZ); /* Make a safe copy */
3541 if ((x = cmcfm()) < 0) /* Get confirmation */
3547 /* Don't let guests change existing files */
3548 printf("?This command not valid for guests\n");
3551 #endif /* CK_LOGIN */
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... */
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 */
3569 makestr(&dldir,NULL); /* dldir is NULL when not assigned */
3571 return(success = 1);
3573 #endif /* CK_TMPDIR */
3579 case XYFILV: { /* EOF */
3580 extern int eofmethod;
3581 if ((x = cmkey(eoftab,3,"end-of-file detection method","",
3584 if ((y = cmcfm()) < 0)
3587 return(success = 1);
3589 #endif /* CK_CTRLZ */
3593 case XYFILH: { /* OUTPUT */
3594 extern int zofbuffer, zobufsize, zofblock;
3596 extern char * zoutbuffer;
3597 #endif /* DYNAMIC */
3599 if ((x = cmkey(zoftab,nzoftab,"output file writing method","",
3602 if (x == ZOF_BUF || x == ZOF_NBUF) {
3603 if ((y = cmnum("output buffer size","32768",10,&z,xxstring)) < 0)
3606 printf("?Bad size - %d\n", z);
3610 if ((y = cmcfm()) < 0) return(y);
3614 zofbuffer = (x == ZOF_BUF);
3619 zofblock = (x == ZOF_BLK);
3623 if (zoutbuffer) free(zoutbuffer);
3624 if (!(zoutbuffer = (char *)malloc(z))) {
3625 printf("MEMORY ALLOCATION ERROR - FATAL\n");
3626 doexit(BAD_EXIT,-1);
3630 if (z <= OBUFSIZE) {
3633 printf("?Sorry, %d is too big - %d is the maximum\n",z,OBUFSIZE);
3636 #endif /* DYNAMIC */
3637 return(success = 1);
3642 case XYFIBP: /* BINARY-PATTERN */
3643 case XYFITP: { /* TEXT-PATTERN */
3644 char * tmp[FTPATTERNS];
3646 while (n < FTPATTERNS) {
3648 if ((x = cmfld("Pattern","",&s,xxstring)) < 0)
3650 ckstrncpy(line,s,LINBUFSIZ);
3652 makestr(&(tmp[n++]),s);
3654 if (x == -3) x = cmcfm();
3655 for (i = 0; i <= n; i++) {
3658 makestr(&(binpatterns[i]),tmp[i]);
3660 makestr(&(txtpatterns[i]),tmp[i]);
3664 if (y == XYFIBP) /* Null-terminate the list */
3665 makestr(&(binpatterns[i]),NULL);
3667 makestr(&(txtpatterns[i]),NULL);
3671 case XYFIPA: /* PATTERNS */
3672 if ((x = setonaut(&patterns)) < 0)
3674 return(success = 1);
3675 #endif /* PATTERNS */
3679 case XYFILU: { /* UCS */
3680 extern int ucsorder, ucsbom, byteorder;
3681 if ((x = cmkey(ucstab,nucstab,"","",xxstring)) < 0)
3685 if ((y = cmkey(botab,nbotab,
3687 byteorder ? "little-endian" : "big-endian",
3692 if ((x = cmcfm()) < 0)
3695 return(success = 1);
3697 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0)
3699 if ((x = cmcfm()) < 0)
3702 return(success = 1);
3707 #endif /* UNICODE */
3710 case XYF_INSP: { /* SCAN (INSPECTION) */
3711 extern int filepeek, nscanfile;
3712 if ((x = cmkey(onoff,2,"","on",xxstring)) < 0)
3715 if ((y = cmnum("How much to scan",ckitoa(SCANFILEBUF),
3716 10,&z,xxstring)) < 0)
3719 if ((y = cmcfm()) < 0)
3724 return(success = 0);
3728 return(success = 1);
3731 #endif /* datageneral */
3736 if ((y = cmkey(fdfltab,nfdflt,"","",xxstring)) < 0)
3738 if (y == 7 || y == 8) {
3740 s = fcsinfo[dcset7].keyword;
3742 s = fcsinfo[dcset8].keyword;
3743 if ((x = cmkey(fcstab,nfilc,"character-set",s,xxstring)) < 0)
3746 ckstrncpy(line,fcsinfo[x].keyword,LINBUFSIZ);
3748 #endif /* NOCSETS */
3749 if ((z = cmcfm()) < 0)
3754 if (fcsinfo[x].size != 128) {
3755 printf("%s - Not a 7-bit set\n",s);
3761 if (fcsinfo[x].size != 256) {
3762 printf("%s - Not an 8-bit set\n",s);
3767 #endif /* NOCSETS */
3771 return(success = 1);
3774 case 9997: /* FASTLOOKUPS */
3775 return(success = seton(&stathack));
3780 case XYF_LSIZ: { /* LISTSIZE */
3782 y = cmnum("Maximum number of filenames","",10,&x,xxstring);
3783 if ((x = setnum(&zz,x,y,-1)) < 0)
3785 if (zsetfil(zz,3) < 0) {
3786 printf("?Memory allocation failure\n");
3789 return(success = 1);
3791 case XYF_SSPA: { /* STRINGSPACE */
3793 y = cmnum("Number of characters for filename list",
3795 if ((x = setnum(&zz,x,y,-1)) < 0)
3797 if (zsetfil(zz,1) < 0) {
3798 printf("?Memory allocation failure\n");
3801 return(success = 1);
3804 #endif /* DYNAMIC */
3808 printf("?unexpected file parameter\n");
3816 #define NPUTENVS 4096
3818 #define NPUTENVS 128
3819 #endif /* BIGBUFOK */
3820 /* environment variables must be static, not automatic */
3822 static char * putenvs[NPUTENVS]; /* Array of environment var strings */
3823 static int nputenvs = -1; /* Pointer into array */
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.
3829 doputenv(s1, s2) char * s1; char * s2; {
3830 char * s, * t = tmpbuf; /* Create or alter environment var */
3832 if (nputenvs == -1) { /* Table not used yet */
3833 int i; /* Initialize the pointers */
3834 for (i = 0; i < NPUTENVS; i++)
3838 if (!s1) return(1); /* Nothing to do */
3839 if (!*s1) return(1); /* ditto */
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");
3847 nputenvs++; /* Point to next free string */
3849 debug(F111,"doputenv s1",s1,nputenvs);
3850 debug(F111,"doputenv s2",s2,nputenvs);
3852 if (nputenvs > NPUTENVS - 1) { /* Notice the end */
3853 printf("?PUTENV - static buffer space exhausted\n");
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 */
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");
3871 if (putenv(putenvs[nputenvs])) {
3872 printf("?PUTENV - %s\n",ck_errstr());
3874 } else return(success = 1);
3876 #endif /* NOPUTENV */
3883 extern int ttnum; /* Last Telnet Terminal Type sent */
3884 extern int ttnumend; /* Has end of list been found */
3886 if ((x = cmkey(ttyptab,nttyp,"","vt220",xxstring)) < 0)
3888 if ((y = cmcfm()) < 0)
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 */
3896 return(success = 1);
3899 extern int fxd_inited;
3900 x = cmtxt("Terminal type name, case sensitive","",&s,NULL);
3904 success = doputenv("TERM",s); /* Set the TERM variable */
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 */
3914 "\n Sorry, this version of C-Kermit does not support the SET TERMINAL TYPE\n");
3916 " command. Type \"help set terminal\" for further information.\n");
3917 return(success = 0);
3924 /* MS-DOS KERMIT compatibility modes */
3927 if ((y = cmkey(msktab,nmsk,"MS-DOS Kermit compatibility mode",
3928 "keycodes",xxstring)) < 0) return(y);
3933 return(seton(&mskcolors));
3934 #endif /* COMMENT */
3936 return(seton(&mskkeys));
3938 return(seton(&mskrename));
3939 default: /* Shouldn't get here. */
3946 static char iactbuf[132];
3950 switch (tt_idleact) {
3951 case IDLE_RET: return("return");
3952 case IDLE_EXIT: return("exit");
3953 case IDLE_HANG: return("hangup");
3955 case IDLE_TNOP: return("Telnet NOP");
3956 case IDLE_TAYT: return("Telnet AYT");
3962 k = ckstrncpy(iactbuf,"output ",132);
3967 if (!*p) return("output NUL");
3968 while ((c = *p++) && n < 131) {
3976 } else if ((c > 32 && c < 127) || c > 159) {
3983 sprintf(q,"\\{%d}",c);
4004 default: return("unknown");
4007 #endif /* CKTIDLE */
4011 setlclcharset(x) int x; {
4013 tcsl = y; /* Local character set */
4015 for (i = 0; i < 4; i++) {
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);
4026 setremcharset(x, z) int x, z; {
4030 KuiSetProperty( KUI_TERM_REMCHARSET, (long) x, (long) z ) ;
4036 #endif /* UNICODE */
4037 { /* TRANSPARENT? */
4039 tcsr = tcsl; /* Make both sets the same */
4042 tt_utf8 = 0; /* Turn off UTF8 flag */
4043 tcsr = tcsl = dec_kbd = TX_TRANSP; /* No translation */
4046 if (!cs_is_nrc(tcsl)) {
4047 G[0].def_designation = G[0].designation = TX_ASCII;
4049 G[0].def_c1 = G[0].c1 = FALSE;
4051 G[0].national = FALSE;
4053 for (i = cs_is_nrc(tcsl) ? 0 : 1; i < 4; i++) {
4054 G[i].def_designation = G[i].designation = tcsl;
4056 G[i].def_c1 = G[i].c1 = FALSE;
4057 switch (cs_size(G[i].designation)) { /* 94, 96, or 128 */
4060 G[i].size = G[i].def_size = cs96;
4063 G[i].size = G[i].def_size = cs94;
4066 G[i].size = G[i].def_size = csmb;
4069 G[i].national = cs_is_nrc(x);
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;
4076 G[i].size = G[i].def_size = cs96;
4077 G[i].c1 = G[i].def_c1 = FALSE;
4082 G[i].national = FALSE;
4090 else if (x == TX_UTF8) {
4092 tt_utf8 = 1; /* Turn it on if we are UTF8 */
4098 tcsr = x; /* Remote character set */
4100 tt_utf8 = 0; /* Turn off UTF8 flag */
4103 if (z == TT_GR_ALL) {
4107 #endif /* UNICODE */
4108 for (i = 0; i < 4; i++) {
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;
4115 G[i].def_designation = G[i].designation = x;
4116 switch (cs_size(x)) { /* 94, 96, or 128 */
4119 G[i].size = G[i].def_size = cs96;
4122 G[i].size = G[i].def_size = cs94;
4125 G[i].size = G[i].def_size = csmb;
4128 G[i].national = cs_is_nrc(x);
4130 G[i].c1 = G[i].def_c1 = x != tcsl && cs_is_std(x);
4133 } else if (z == TT_GR_KBD) { /* Keyboard only */
4135 #endif /* UNICODE */
4136 } else { /* Specific Gn */
4137 G[z].def_designation = G[z].designation = x;
4139 switch (cs_size(x)) { /* 94, 96, or 128 */
4142 G[z].size = G[z].def_size = cs96;
4145 G[z].size = G[z].def_size = cs94;
4148 G[z].size = G[z].def_size = csmb;
4151 G[z].c1 = G[z].def_c1 = x != tcsl && cs_is_std(x);
4152 G[z].national = cs_is_nrc(x);
4156 tcsr = x; /* Remote character set */
4159 #endif /* NOCSETS */
4162 setcmask(x) int x; {
4165 } else if (x == 8) {
4170 KuiSetProperty(KUI_TERM_CMASK,x,0);
4176 setautodl(x,y) int x,y; {
4180 KuiSetProperty(KUI_TERM_AUTODOWNLOAD,x?(y?2:1):0,0);
4183 #endif /* CK_AUTODL */
4190 KuiSetProperty(KUI_TERM_URL_HIGHLIGHT,x,0);
4199 KuiSetProperty(KUI_TERM_PRINTERCOPY,x,0);
4208 extern int colorreset, user_erasemode;
4210 if ((y = cmkey(trmtab,ntrm,"", "",xxstring)) < 0) return(y);
4212 printf("\n?Sorry, not implemented yet. Please use the Settings menu.\n");
4217 if ((y = cmcfm()) < 0) return(y);
4218 printf("?Sorry, command disabled.\r\n");
4219 return(success = 0);
4224 case XYTBYT: /* SET TERMINAL BYTESIZE */
4225 if ((y = cmnum("bytesize for terminal connection","8",10,&x,
4228 if (x != 7 && x != 8) {
4229 printf("\n?The choices are 7 and 8\n");
4230 return(success = 0);
4232 if ((y = cmcfm()) < 0) return(y);
4235 if (IS97801(tt_type_mode))
4238 return(success = 1);
4240 case XYTSO: /* SET TERMINAL LOCKING-SHIFT */
4241 return(seton(&sosi));
4243 case XYTNL: /* SET TERMINAL NEWLINE-MODE */
4244 return(seton(&tnlm));
4248 if ((x = cmkey(ttycoltab,ncolors,"","terminal",xxstring)) < 0)
4250 else if (x == TTCOLRES) {
4251 if ((y = cmkey(ttcolmodetab,ncolmode,
4252 "","default-color",xxstring)) < 0)
4254 if ((z = cmcfm()) < 0)
4257 return(success = 1);
4258 } else if (x == TTCOLERA) {
4259 if ((y = cmkey(ttcolmodetab,ncolmode,"",
4260 "current-color",xxstring)) < 0)
4262 if ((z = cmcfm()) < 0)
4266 } else { /* No parse error */
4268 fg = cmkey(ttyclrtab, nclrs,
4270 "color for screen border" :
4271 "foreground color and then background color"),
4275 if (x != TTCOLBOR) {
4276 if ((bg = cmkey(ttyclrtab,nclrs,
4277 "background color","blue",xxstring)) < 0)
4280 if ((y = cmcfm()) < 0)
4284 colornormal = fg | bg << 4;
4289 colorreverse = fg | bg << 4;
4292 coloritalic = fg | bg << 4;
4295 colorunderline = fg | bg << 4;
4298 colorgraphic = fg | bg << 4;
4301 colordebug = fg | bg << 4;
4304 colorstatus = fg | bg << 4;
4307 colorhelp = fg | bg << 4;
4313 colorselect = fg | bg << 4;
4316 printf("%s - invalid\n",cmdbuf);
4320 scrninitialized[VTERM] = 0;
4323 return(success = 1);
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)
4330 if ((z = cmkey(curontab,ncuron,"","on",xxstring)) < 0)
4332 if ((y = cmcfm()) < 0) return(y);
4333 tt_cursor = tt_cursor_usr = x;
4335 cursorena[VTERM] = tt_cursorena_usr = 1;
4336 tt_cursor_blink = 0;
4338 cursorena[VTERM] = tt_cursorena_usr = z;/* turn cursor on/off */
4339 tt_cursor_blink = 1;
4341 cursoron[VTERM] = FALSE; /* Force newcursor to restore the cursor */
4342 return(success = 1);
4346 case XYTTYP: /* SET TERMINAL TYPE */
4347 return(settrmtyp());
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);
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);
4362 case XYTUNX: { /* SET TERM UNIX-MODE (DG) */
4363 extern int dgunix,dgunix_usr;
4365 dgunix_usr = dgunix;
4368 case XYTKBMOD: { /* SET TERM KEYBOARD MODE */
4369 extern int tt_kb_mode;
4370 if ((x = cmkey(kbmodtab,
4373 "special keyboard mode for terminal emulation",
4377 if ((y = cmcfm()) < 0) return(y);
4379 return(success = 1);
4382 case XYTWRP: /* SET TERMINAL WRAP */
4383 return(seton(&tt_wrap));
4386 if ((y = cmnum("CONNECT scrollback buffer size, lines","2000",10,&x,
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);
4397 if ((y = cmcfm()) < 0) return(y);
4398 tt_scrsize[VTERM] = x;
4400 return(success = 1);
4404 case XYTCS: { /* SET TERMINAL CHARACTER-SET */
4406 /* set terminal character-set <remote> <local> */
4413 "remote terminal character-set","",xxstring)) < 0)
4422 if ((y = cmcfm()) < 0) /* Confirm the command */
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.
4437 if (x == FC_TRANSP) {
4438 if ((y = cmcfm()) < 0) /* Confirm the command */
4442 #endif /* UNICODE */
4444 /* Not transparent or UTF8, so get local set to translate it into */
4447 y = os2getcp(); /* Default is current code page */
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;
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.
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;
4480 #endif /* PCFONTS */
4481 #else /* Not K95... */
4482 s = fcsinfo[fcharset].keyword;
4491 "local character-set",s,xxstring)) < 0)
4496 printf("?UTF8 may not be used as a local character set.\r\n");
4499 #endif /* UNICODE */
4501 if ((z = cmkey(graphsettab,ngraphset,
4502 "DEC VT intermediate graphic set","all",xxstring)) < 0)
4505 if ((eol = cmcfm()) < 0)
4506 return(eol); /* Confirm the command */
4508 /* End of command parsing - actions begin */
4511 return(success = 1);
4513 #endif /* NOCSETS */
4516 case XYTLCS: /* SET TERMINAL LOCAL-CHARACTER-SET */
4517 /* set terminal character-set <local> */
4518 s = getdcset(); /* Get display character-set name */
4525 "local character-set",s,xxstring)) < 0)
4530 printf("?UTF8 may not be used as a local character set.\r\n");
4533 #endif /* UNICODE */
4534 if ((z = cmcfm()) < 0) return(z); /* Confirm the command */
4536 /* End of command parsing - action begins */
4539 return(success = 1);
4540 #endif /* NOCSETS */
4544 case XYTUNI: /* SET TERMINAL UNICODE */
4545 return(seton(&tt_unicode));
4546 #endif /* UNICODE */
4548 case XYTRCS: /* SET TERMINAL REMOTE-CHARACTER-SET */
4549 /* set terminal character-set <remote> <Graphic-set> */
4556 "remote terminal character-set","",xxstring)) < 0)
4565 if ((y = cmcfm()) < 0) /* Confirm the command */
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.
4579 if (x == FC_TRANSP) {
4580 if ((y = cmcfm()) < 0) /* Confirm the command */
4583 #endif /* UNICODE */
4586 if ((z = cmkey(graphsettab,ngraphset,
4587 "DEC VT intermediate graphic set","all",xxstring)) < 0)
4590 if ((y = cmcfm()) < 0) /* Confirm the command */
4593 /* Command parsing ends here */
4596 return(success = 1);
4597 #endif /* NOCSETS */
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);
4605 #endif /* NETCONN */
4607 return(success = 1);
4609 case XYTESC: /* SET TERM ESC */
4610 if ((x = cmkey(nabltab,nnabltab,"","enabled",xxstring)) < 0)
4612 if ((y = cmcfm()) < 0) return(y);
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);
4620 return(success = 1);
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);
4626 return(success = 1);
4629 case XYTANS: { /* SET TERMINAL ANSWERBACK */
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.
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.
4640 if ((x = cmkey(anbktab,nansbk,"", "off", xxstring)) < 0)
4643 if ((y = cmcfm()) < 0)
4646 return(success = 1);
4647 } else if ( x == 2 || x == 3) {
4649 extern int safeanswerbk;
4650 extern char useranswerbk[];
4651 if ((y = cmtxt("Answerback extension","",&s,xxstring)) < 0)
4653 if (apcactive == APC_LOCAL ||
4654 (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH)))
4655 return(success = 0);
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] = '_';
4663 useranswerbk[z] = s[z];
4665 useranswerbk[z] = '\0';
4666 safeanswerbk = 1 ; /* TRUE */
4668 ckstrncpy(useranswerbk,s,60); /* (see ckocon.c) */
4669 safeanswerbk = 0; /* FALSE */
4672 return(success = 1);
4674 return(success = 0);
4680 if ((y = cmkey(apctab,napctab,
4681 "application program command execution","",
4684 if ((x = cmcfm()) < 0)
4686 if (apcactive == APC_LOCAL ||
4687 (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH)))
4688 return(success = 0);
4690 return(success = 1);
4693 case XYTAUTODL: /* AUTODOWNLOAD */
4694 if ((y = cmkey(adltab,nadltab,"Auto-download options","",
4700 if ((x = cmcfm()) < 0)
4705 if ((x = cmcfm()) < 0)
4707 setautodl(TAD_ON,1);
4710 if ((y = cmkey(adlerrtab,nadlerrtab,"","", xxstring)) < 0)
4712 if ((x = cmcfm()) < 0)
4718 if ((y = cmkey(adlxtab,nadlxtab,"","", xxstring)) < 0)
4722 if ((y = cmkey(adlc0tab,nadlc0tab,"",
4723 "processed-by-emulator",xxstring)) < 0)
4725 if ((x = cmcfm()) < 0)
4730 if ((y = cmkey(adldtab,nadldtab,"","packet",xxstring)) < 0)
4732 if ((x = cmcfm()) < 0)
4737 if ((y = cmtxt("Kermit start string","KERMIT READY TO SEND...",
4741 adl_kstr = strdup(s);
4747 if ((y = cmkey(adlxtab,nadlxtab,"","",xxstring)) < 0)
4751 if ((y = cmkey(adlc0tab,nadlc0tab,"",
4752 "processed-by-emulator",xxstring)) < 0)
4754 if ((x = cmcfm()) < 0)
4759 if ((y = cmkey(adldtab,nadldtab,"","packet",xxstring)) < 0)
4761 if ((x = cmcfm()) < 0)
4766 if ((y = cmtxt("","rz\\{13}",&s,xxstring)) < 0)
4769 adl_zstr = strdup(s);
4775 return(success = 1);
4777 #endif /* CK_AUTODL */
4782 return(success = setbell());
4784 case XYTMBEL: /* MARGIN-BELL */
4785 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
4787 if ((z = cmnum("Column at which to set margin bell",
4788 "72",10,&x,xxstring)) < 0)
4791 if ((z = cmcfm()) < 0) return(z);
4794 return(success = 1);
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)
4804 if ((y = cmtxt("string to send, may contain kverbs and variables",
4805 "\\v(newline)",&s,xxstring)) < 0)
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) */
4813 if ((y = cmcfm()) < 0)
4820 return(success = 1);
4822 case XYTIACT: { /* SET TERM IDLE-ACTION */
4823 if ((y = cmkey(idlacts,nidlacts,"","",xxstring)) < 0)
4825 if (y == IDLE_OUT) {
4826 if ((x = cmtxt("string to send, may contain kverbs and variables"
4827 , "",&s,xxstring)) < 0)
4829 makestr(&tt_idlestr,brstrip(s)); /* (new) */
4830 tt_idlesnd_str = tt_idlestr; /* (old) */
4832 if ((x = cmcfm()) < 0)
4836 return(success = 1);
4838 #endif /* CKTIDLE */
4840 case XYTDEB: /* TERMINAL DEBUG */
4841 y = seton(&x); /* Go parse ON or OFF */
4842 if (y > 0) /* Command succeeded? */
4847 case XYTASCRL: /* SET TERMINAL AUTOSCROLL */
4848 y = seton(&autoscroll);
4851 case XYTAPAGE: /* SET TERMINAL AUTOPAGE */
4852 y = seton(&wy_autopage);
4855 case XYTROL: /* SET TERMINAL ROLL */
4856 if ((y = cmkey(rolltab,nroll,"scrollback mode","insert",xxstring))<0)
4858 if (y == TTR_KEYS) {
4859 if ((x = cmkey(rollkeytab,nrollkey,"","send",xxstring))<0)
4861 if ((z = cmcfm()) < 0) return(z);
4862 tt_rkeys[VTERM] = x;
4864 if ((x = cmcfm()) < 0) return(x);
4867 return(success = 1);
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));
4874 case XYTCPG: { /* SET TERMINAL CODE-PAGE */
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) {
4884 "Sorry, Windows 95 does not support code page switching\n");
4888 "Sorry, %d is not a valid code page for this system.\n",cp);
4891 /* Force the terminal character-sets conversions to be updated */
4892 for ( i = 0; i < 4; i++ )
4897 case XYTPAC: /* SET TERMINAL OUTPUT-PACING */
4899 "Pause between sending each character during CONNECT, milliseconds",
4900 "-1",10,&x,xxstring);
4901 return(setnum(&tt_pacing,x,y,10000));
4904 case XYTMOU: { /* SET TERMINAL MOUSE */
4905 int old_mou = tt_mouse;
4906 if ((x = seton(&tt_mouse)) < 0)
4908 if (tt_mouse != old_mou)
4915 #endif /* OS2MOUSE */
4921 "number of columns in display window during CONNECT",
4923 "number of columns on your screen",
4925 "80",10,&x,xxstring)) < 0)
4927 if ((y = cmcfm()) < 0) return(y);
4929 return(success = os2_settermwidth(x));
4930 #else /* Not OS/2 */
4932 return(success = 1);
4939 "number of rows in display window during CONNECT, not including status line",
4940 tt_status[VTERM]?"24":"25",
4942 "24","number of rows on your screen",
4944 10,&x,xxstring)) < 0)
4946 if ((y = cmcfm()) < 0) return(y);
4949 return (success = os2_settermheight(x));
4950 #else /* Not OS/2 */
4952 return(success = 1);
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);
4962 if (cprint || uprint || aprint || xprint)
4964 cprint = xprint = uprint = 0;
4968 if (!(cprint || uprint || aprint || xprint))
4971 cprint = xprint = uprint = 0;
4974 if (!(cprint || uprint || aprint || xprint))
4978 xprint = uprint = 0;
4981 if (!(cprint || uprint || aprint || xprint))
4985 xprint = cprint = 0;
4993 extern int tt_print;
4994 if ((x = seton(&tt_print)) < 0)
4996 return(success = 1);
5003 extern int decscnm, decscnm_usr;
5004 if ((y = cmkey(normrev,4,"",
5005 decscnm_usr?"reverse":"normal",
5009 if ((x = cmcfm()) < 0) return(x);
5011 if (decscnm != decscnm_usr)
5016 if ((y = cmkey(onoff,2,"",tt_diff_upd?"on":"off",
5017 xxstring)) < 0) return(y);
5018 if ((x = cmcfm()) < 0) return(x);
5023 if ((mode = cmkey(scrnupd,nscrnupd,"","fast",xxstring)) < 0) {
5027 "Pause between FAST screen updates in CONNECT mode, milliseconds",
5028 "100",10,&x,xxstring
5030 if (x < 0 || x > 1000 ) {
5032 "\n?The update rate must be between 0 and 1000 milliseconds.\n"
5034 return(success = 0);
5036 if ((y = cmcfm()) < 0) return(y);
5038 updmode = tt_updmode = mode;
5039 return(setnum(&tt_update,x,y,10000));
5043 if ((x = cmkey(termctrl,ntermctrl,"","7",xxstring)) < 0) {
5046 if ((y = cmcfm()) < 0)
5050 send_c1 = send_c1_usr = TRUE;
5054 send_c1 = send_c1_usr = FALSE;
5058 return(success = TRUE);
5063 if ( !IsOS2FullScreen() ) {
5065 "\n?SET TERMINAL FONT is only supported in Full Screen sessions.\n");
5066 return(success = FALSE);
5069 if ((x = cmkey(term_font,ntermfont,"","default",xxstring)) < 0) {
5072 if ((y = cmcfm()) < 0) return(y);
5073 if ( !os2LoadPCFonts() ) {
5075 return(success = TRUE);
5078 "\n?PCFONTS.DLL is not available in CKERMIT executable directory.\n");
5079 return(success = FALSE);
5087 return(setguifont()); /* ckuus3.c */
5090 #endif /* PCFONTS */
5093 extern int pheight, marginbot, cmd_rows, cmd_cols;
5094 if ((x = cmkey(tvctab,ntvctab,"",isWin95()?"win95-safe":"enabled",
5097 if ((y = cmcfm()) < 0) return(y);
5099 if (x != tt_modechg) {
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;
5115 tt_szchng[VTERM] = 2 ;
5116 tt_rows[VTERM] = pheight - (tt_status[VTERM]?1:0);
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. */
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) {
5136 else if (pheight < 43)
5143 tt_modechg = TVC_ENA; /* Temporary */
5145 tt_szchng[VCMD] = 1;
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;
5162 return(success = 1);
5164 return(success = 0);
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) )
5179 tt_status_usr[VTERM] = tt_status[VTERM] = y;
5181 tt_szchng[VTERM] = 2;
5183 VscrnInit(VTERM); /* Height set here */
5185 if (TELOPT_ME(TELOPT_NAWS))
5189 if (TELOPT_ME(TELOPT_NAWS))
5191 #endif /* RLOGCODE */
5193 if (TELOPT_ME(TELOPT_NAWS))
5195 #endif /* SSHBUILTIN */
5197 tt_szchng[VTERM] = 1;
5199 VscrnInit(VTERM); /* Height set here */
5201 if (TELOPT_ME(TELOPT_NAWS))
5205 if (TELOPT_ME(TELOPT_NAWS))
5207 #endif /* RLOGCODE */
5209 if (TELOPT_ME(TELOPT_NAWS))
5211 #endif /* SSHBUILTIN */
5220 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5221 if ((x = cmcfm()) < 0) return(x);
5228 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5229 if ((x = cmcfm()) < 0) return(x);
5234 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5235 if ((x = cmcfm()) < 0) return(x);
5240 if ((y = cmkey(ttyseobtab,2,"","us_cr",xxstring)) < 0) return(y);
5241 if ((x = cmcfm()) < 0) return(x);
5246 int done = 0, attr = VT_CHAR_ATTR_NORMAL;
5248 if ((x = cmkey(onoff,2,"","on",xxstring)) < 0)
5253 if ((y = cmkey(ttyprotab,nprotect,"",
5254 z?"done":"reverse",xxstring)) < 0)
5261 attr |= VT_CHAR_ATTR_BLINK;
5264 attr |= VT_CHAR_ATTR_REVERSE;
5267 attr |= VT_CHAR_ATTR_ITALIC;
5270 attr |= VT_CHAR_ATTR_UNDERLINE;
5273 attr |= VT_CHAR_ATTR_BOLD;
5276 attr |= VT_CHAR_ATTR_DIM;
5279 attr |= VT_CHAR_ATTR_INVISIBLE;
5284 z = 1; /* One attribute has been chosen */
5287 if ((z = cmcfm()) < 0) return(z);
5290 tt_url_hilite_attr = attr;
5294 if ((x = cmkey(ttyattrtab,nattrib,"","underline",xxstring)) < 0)
5298 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5299 if ((x = cmcfm()) < 0) return(x);
5302 if ( !trueblink && trueunderline ) {
5304 printf("Warning: Underline being simulated by color.\n");
5311 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5312 if ((x = cmcfm()) < 0) return(x);
5317 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5318 if ((x = cmcfm()) < 0) return(x);
5323 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5324 if ((x = cmcfm()) < 0) return(x);
5327 if (!trueblink && trueunderline) {
5329 printf("Warning: True blink mode is active.\n");
5335 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5336 if ((x = cmcfm()) < 0) return(x);
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 */
5348 if ((y = cmkey(ttyprotab,nprotect,"",
5349 x?"done":"dim",xxstring)) < 0)
5354 case TTATTBLI: /* Blinking doesn't work */
5355 wpa.blinking = TRUE;
5358 wpa.reversed = TRUE;
5364 wpa.underlined = TRUE;
5373 wpa.invisible = TRUE ;
5379 x = 1; /* One attribute has been chosen */
5381 if ((x = cmcfm()) < 0) return(x);
5382 WPattrib = defWPattrib = wpa;
5388 case XYTKEY: { /* SET TERMINAL KEY */
5390 int clear = 0, deflt = 0;
5393 int kc = -1; /* Key code */
5394 int litstr = 0; /* Literal String? */
5395 char *s = NULL; /* Key binding */
5397 char *p = NULL; /* Worker */
5398 #endif /* NOKVERBS */
5403 struct FDB kw,sw,nu,cm;
5405 defevt.type = error;
5407 if ((t = cmkey(ttkeytab,nttkey,"","",xxstring)) < 0)
5409 cmfdbi(&nu, /* First FDB - command switches */
5411 "/literal, keycode, or action",
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 */
5420 cmfdbi(&sw, /* Second FDB - switches */
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 */
5431 cmfdbi(&kw, /* Third FDB - command switches */
5433 "/literal, keycode, or action",
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 */
5442 cmfdbi(&cm, /* Final FDB - Confirmation */
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 */
5454 x = cmfdb(&nu); /* Parse something */
5458 switch (cmresult.fcode) {
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");
5470 shokeycode(kc,t); /* Show current definition */
5471 flag = 1; /* Remember it's a multiline command */
5474 kc = cmresult.nresult;
5477 if (cmresult.fdbaddr == &sw) { /* Switch */
5478 if (cmresult.nresult == 0)
5480 } else if (cmresult.fdbaddr == &kw) { /* Keyword */
5481 if (cmresult.nresult == 0)
5485 if ((x = cmcfm()) < 0)
5497 /* Normal SET TERMINAL KEY <terminal> <scancode> <value> command... */
5502 if (kc < 0 || kc >= KMSIZE) {
5503 printf("?key code must be between 0 and %d\n", KMSIZE - 1);
5507 printf("Sorry, %d is the CONNECT-mode escape character\n",kc);
5512 cmsavp(psave,PROMPTL);
5513 cmsetp(" Enter new definition: ");
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",
5522 if (flag) /* Handle parse errors */
5529 p = s; /* Save this place */
5530 #endif /* NOKVERBS */
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
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
5541 for (x = 0, y = 0; s[x]; x++, y++) { /* Convert \K to \\K */
5543 (s[x] == 'K' || s[x] == 'k')
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 */
5550 if (x > 1 && s[x-1] == '{' && s[x-2] == CMDQ) {
5551 line[y-1] = CMDQ; /* Have \{K */
5552 line[y++] = '{'; /* Make it \\{K */
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);
5566 s = line + y + 1; /* Point to result. */
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.
5576 p = (*p == 'k' || *p == 'K') ? p + 1 : NULL;
5578 #endif /* NOKVERBS */
5580 switch (strlen(s)) { /* Action depends on length */
5581 case 0: /* Clear individual key def */
5586 defevt.type = key; /* Single character */
5587 defevt.key.scancode = *s;
5590 default: /* Character string */
5593 y = xlookup(kverbs,p,nkverbs,&x); /* Look it up */
5594 /* Need exact match */
5595 debug(F101,"set key kverb lookup",0,y);
5597 defevt.type = kverb;
5598 defevt.kverb.id = y;
5602 #endif /* NOKVERBS */
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 */
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 */
5616 insertkeymap(t, kc, defevt);
5619 initvik = 1; /* Update VIK table */
5624 case XYTPCTERM: /* PCTERM Keyboard Mode */
5625 if ((x = seton(&tt_pcterm)) < 0) return(x);
5626 return(success = 1);
5632 if ((y = cmtxt("String to trigger automatic return to command mode",
5633 "",&s,xxstring)) < 0)
5635 makelist(s,tt_trigger,TRIGGERS);
5637 #endif /* CK_TRIGGER */
5641 if ((y = cmnum("ASCII value to use for spacing attributes",
5642 "32",10,&x,xxstring)) < 0)
5644 if ((y = cmcfm()) < 0) return(y);
5646 return(success = 1);
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)
5652 return(success = 1);
5655 case XYTVTLNG: /* SET TERM DEC-LANGUAGE */
5656 if ((y = cmkey(vtlangtab,nvtlangtab,"VT language",
5657 IS97801(tt_type_mode)?"german":"north-american",
5660 if ((x = cmcfm()) < 0) return(x);
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 */
5669 case VTL_NORTH_AM: /* North American */
5670 /* Multinational: Latin-1 */
5671 /* National: US_ASCII */
5674 dec_kbd = TX_8859_1;
5677 /* Multinational: Latin-1 */
5678 /* National: UK_ASCII */
5680 dec_nrc = TX_BRITISH;
5681 dec_kbd = TX_8859_1;
5686 /* Multinational: Latin-1 */
5687 /* National: FR_ASCII */
5689 dec_nrc = TX_FRENCH;
5690 dec_kbd = TX_8859_1;
5693 /* Multinational: Latin-1 */
5694 /* National: FC_ASCII */
5696 dec_nrc = TX_CN_FRENCH;
5697 dec_kbd = TX_8859_1;
5701 /* Multinational: Latin-1 */
5702 /* National: NO_ASCII */
5704 dec_nrc = TX_NORWEGIAN;
5705 dec_kbd = TX_8859_1;
5708 /* Multinational: Latin-1 */
5709 /* National: FI_ASCII */
5711 dec_nrc = TX_FINNISH;
5712 dec_kbd = TX_8859_1;
5715 /* Multinational: Latin-1 */
5716 /* National: GR_ASCII */
5718 dec_nrc = TX_GERMAN;
5719 dec_kbd = TX_8859_1;
5722 /* Multinational: Latin-1 */
5723 /* National: DU_ASCII */
5726 dec_kbd = TX_8859_1;
5729 /* Multinational: Latin-1 */
5730 /* National: IT_ASCII */
5732 dec_nrc = TX_ITALIAN;
5733 dec_kbd = TX_8859_1;
5737 /* Multinational: Latin-1 */
5738 /* National: CH_ASCII */
5741 dec_kbd = TX_8859_1;
5744 /* Multinational: Latin-1 */
5745 /* National: SW_ASCII */
5747 dec_nrc = TX_SWEDISH;
5748 dec_kbd = TX_8859_1;
5751 /* Multinational: Latin-1 */
5752 /* National: SP_ASCII */
5754 dec_nrc = TX_SPANISH;
5755 dec_kbd = TX_8859_1;
5758 /* Multinational: Latin-1 */
5759 /* National: Portugese ASCII */
5761 dec_nrc = TX_PORTUGUESE;
5762 dec_kbd = TX_8859_1;
5765 /* Multinational: Latin-Hebrew / DEC-Hebrew */
5766 /* National: DEC 7-bit Hebrew */
5769 dec_kbd = TX_8859_8;
5772 /* Multinational: Latin-Greek / DEC-Greek */
5773 /* National: DEC Greek NRC */
5774 /* is ELOT927 equivalent to DEC Greek???? */
5776 dec_nrc = TX_ELOT927;
5777 dec_kbd = TX_8859_7;
5782 /* Multinational: Latin-Turkish / DEC-Turkish */
5783 /* National: DEC 7-bit Turkish */
5785 #endif /* COMMENT */
5787 /* Multinational: Latin-2 */
5788 /* National: no national mode */
5790 dec_nrc = TX_HUNGARIAN;
5791 dec_kbd = TX_8859_2;
5797 /* Multinational: Latin-2 */
5798 /* National: no national mode */
5801 dec_kbd = TX_8859_2;
5804 /* Multinational: Latin-Cyrillic / KOI-8 */
5805 /* National: DEC Russian NRC */
5808 dec_kbd = TX_8859_5;
5811 /* Multinational: not listed in table */
5812 /* National: not listed in table */
5815 dec_kbd = TX_8859_1;
5819 /* Multinational: Latin-2 */
5820 /* National: SCS NRC */
5822 #endif /* COMMENT */
5824 return(success = 0);
5826 if (IS97801(tt_type_mode)) {
5827 SNI_bitmode(cmask == 0377 ? 8 : 7);
5829 return(success = 1);
5830 #endif /* NOCSETS */
5832 case XYTVTNRC: { /* SET TERM DEC-NRC-MODE */
5833 extern int decnrcm_usr, decnrcm; /* from ckoco3.c */
5834 if ((x = seton(&decnrcm_usr)) < 0)
5836 decnrcm = decnrcm_usr;
5837 return(success = 1);
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);
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);
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);
5859 return(success = 1);
5861 case XYTSNIFV: { /* SET TERM SNI-FIRMWARE-VERSIONS */
5862 extern CHAR sni_kbd_firmware[], sni_term_firmware[];
5863 CHAR kbd[7],term[7];
5865 if ((x = cmfld("Keyboard Firmware Version",sni_kbd_firmware,
5868 if ((int)strlen(s) != 6) {
5869 printf("?Sorry - the firmware version must be 6 digits long\n");
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");
5880 if ((x = cmfld("Terminal Firmware Version",sni_term_firmware,
5883 if ((int)strlen(s) != 6) {
5884 printf("?Sorry - the firmware version must be 6 digits long\n");
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");
5893 ckstrncpy(term,s,7);
5894 if ((x = cmcfm()) < 0) return(x);
5896 ckstrncpy(sni_kbd_firmware,kbd,7);
5897 ckstrncpy(sni_term_firmware,term,7);
5898 return(success = 1);
5901 case XYTLSP: { /* SET TERM LINE-SPACING */
5902 if ((x = cmfld("Line Spacing","1",&s, xxstring)) < 0)
5904 if (isfloat(s,0) < 1) { /* (sets floatval) */
5905 printf("?Integer or floating-point number required\n");
5908 if (floatval < 1.0 || floatval > 3.0) {
5909 printf("?Value must within the range 1.0 and 3.0 (inclusive)\n");
5912 if ((x = cmcfm()) < 0) return(x);
5914 tt_linespacing[VCMD] = tt_linespacing[VTERM] = floatval;
5915 return(success = 1);
5917 printf("?Sorry, Line-spacing is only supported in K95G.EXE.\n");
5918 return(success = 0);
5923 default: /* Shouldn't get here. */
5929 This was supposed to shut up picky compilers but instead it makes
5930 most compilers complain about "statement not reached".
5933 #endif /* COMMENT */
5942 extern char usertitle[];
5943 if ((y = cmtxt("title text","",&s,xxstring)) < 0)
5947 printf("?Sorry, command disabled.\r\n");
5948 return(success = 0);
5952 ckstrncpy(usertitle,s,64);
5957 static struct keytab dialertab[] = { /* K95 Dialer types */
5961 static int ndialer = 2;
5966 int clear = 0, deflt = 0;
5967 int kc; /* Key code */
5968 char *s = NULL; /* Key binding */
5970 char *p = NULL; /* Worker */
5971 #endif /* NOKVERBS */
5977 defevt.type = error;
5979 if (( x = cmkey(dialertab, ndialer,
5980 "Kermit-95 dialer work-arounds",
5981 "", xxstring)) < 0 )
5984 case 0: /* Backspace */
5991 printf("Illegal value in setdialer()\n");
5994 if ((y = cmtxt("Key definition","",&s,xxstring)) < 0)
5999 printf("?Sorry, command disabled.\r\n");
6000 return(success = 0);
6005 p = s; /* Save this place */
6006 #endif /* NOKVERBS */
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
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
6017 for (x = 0, y = 0; s[x]; x++, y++) { /* Convert \K to \\K */
6019 (s[x] == 'K' || s[x] == 'k')
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 */
6026 if (x > 1 && s[x-1] == '{' && s[x-2] == CMDQ) {
6027 line[y-1] = CMDQ; /* Have \{K */
6028 line[y++] = '{'; /* Make it \\{K */
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");
6041 s = line + y + 1; /* Point to result. */
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.
6051 p = (*p == 'k' || *p == 'K') ? p + 1 : NULL;
6053 #endif /* NOKVERBS */
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;
6060 keymap[kc] = (KEY) kc;
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 */
6071 udkfkeys[83] = strdup(s);
6073 } else if (ISWYSE(t) || ISTVI(t)) {
6074 extern char * udkfkeys[] ;
6075 if (kc == 264) { /* \Kwybs or \Ktvibs */
6078 udkfkeys[32] = strdup(s);
6080 if (kc == 269) { /* \Kwyenter and \Kwyreturn */
6081 if (udkfkeys[39]) /* \Ktvienter and \Ktvireturn */
6083 udkfkeys[39] = strdup(s);
6086 udkfkeys[49] = strdup(s);
6089 switch (strlen(s)) { /* Action depends on length */
6090 case 0: /* Clear individual key def */
6094 defevt.type = key; /* Single character */
6095 defevt.key.scancode = *s;
6097 default: /* Character string */
6100 y = xlookup(kverbs,p,nkverbs,&x); /* Look it up */
6101 /* Exact match req'd */
6102 debug(F101,"set key kverb lookup",0,y);
6104 defevt.type = kverb;
6105 defevt.kverb.id = y;
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 */
6116 insertkeymap( t, kc, defevt ) ;
6117 initvik = 1; /* Update VIK table */
6129 if (( y = cmkey(win95tab, nwin95,
6130 "Windows 95 specific work-arounds",
6131 "keyboard-translation",
6136 if ((y = cmkey(onoff,2,"popups are used to prompt the user for data",
6137 "on",xxstring)) < 0)
6139 if ((x = cmcfm()) < 0) return(x);
6144 if ((y = cmkey(onoff,2,"8.3 FAT file names","off",xxstring)) < 0)
6146 if ((x = cmcfm()) < 0) return(x);
6151 if ((y = cmkey(onoff,2,"\"select()\" fails on write","off",
6154 if ((x = cmcfm()) < 0) return(x);
6159 if ((y = cmkey(onoff,2,"Right-Alt is Alt-Gr","off",xxstring)) < 0)
6161 if ((x = cmcfm()) < 0) return(x);
6166 if ((y = cmkey(onoff,2,"Use Overlapped I/O","on",xxstring)) < 0)
6169 if ((x = cmnum("Maximum number of outstanding I/O requests",
6170 "10",10,&z,xxstring)) < 0)
6172 if (z < 1 || z > 7) {
6174 "?Maximum outstanding I/O requests must be between 1 and 7.\n");
6179 if ((x = cmcfm()) < 0) return(x);
6181 maxow = maxow_usr = z;
6186 printf("\n?\"Keyboard-Translation\" is no longer required.\n");
6189 if (( z = cmkey(tcstab, ntcs,
6190 "Keyboard Character Set",
6194 if ((x = cmcfm()) < 0)
6198 win95kl2 = (win95kcsi == TC_2LATIN);
6200 if (win95kcsi == TC_TRANSP) {
6204 win95kcs = xlr[win95kcsi][tx2fc(tcsl)];
6206 win95kcs = xlr[win95kcsi][tcsl];
6207 #endif /* UNICODE */
6210 #endif /* COMMENT */
6213 if ((y = cmkey(onoff,2,"Unicode-to-Lucida-Console substitutions",
6214 "on",xxstring)) < 0)
6216 if ((x = cmcfm()) < 0) return(x);
6221 if ((y = cmkey(onoff,2,"Horizontal Scan Line substitutions",
6222 "on",xxstring)) < 0)
6224 if ((x = cmcfm()) < 0) return(x);
6229 printf("Illegal value in setwin95()\n");
6240 #endif /* CK_ANSIC */
6244 if (( y = cmkey(prtytab, nprty,
6245 "priority level of terminal and communication threads",
6246 "foreground-server",
6250 if ((x = cmcfm()) < 0)
6258 #endif /* IKSDCONF */
6260 if ((y = cmcfm()) < 0) return(y);
6261 printf("?Sorry, command disabled.\r\n");
6262 return(success = 0);
6277 if ((y = cmkey(beltab,nbeltab,
6279 "how console and terminal bells should\nbe generated", "audible",
6281 "Whether Kermit should ring the terminal bell (beep)", "on",
6288 if ((y = cmcfm()) < 0) return(y);
6289 printf("?Sorry, command disabled.\r\n");
6290 return(success = 0);
6294 switch (y) { /* SET BELL */
6299 if ((x = cmcfm()) < 0)
6310 if ((x = cmkey(audibletab, naudibletab,
6311 "how audible console and terminal\nbells should be generated",
6312 "beep",xxstring))<0)
6314 if ((z = cmcfm()) < 0)
6318 /* This lets C-Kermit accept but ignore trailing K95 keywords */
6319 if ((x = cmtxt("Confirm with carriage return","",&s,xxstring)) < 0)
6333 #endif /* CK_ANSIC */
6336 int button = 0, event = 0;
6339 if ((y = cmkey(mousetab,nmtab,"","",xxstring)) < 0)
6344 if ((y = cmcfm()) < 0) return(y);
6345 printf("?Sorry, command disabled.\r\n");
6346 return(success = 0);
6350 if (y == XYM_ON) { /* MOUSE ACTIVATION */
6351 int old_mou = tt_mouse;
6352 if ((x = seton(&tt_mouse)) < 0)
6354 if (tt_mouse != old_mou)
6362 if (y == XYM_DEBUG) { /* MOUSE DEBUG */
6363 extern int MouseDebug;
6364 if ((x = seton(&MouseDebug)) < 0)
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 */
6375 if (y != XYM_BUTTON) { /* Shouldn't happen. */
6376 printf("Internal parsing error\n");
6380 /* MOUSE EVENT ... */
6382 if ((button = cmkey(mousebuttontab,nmbtab,
6383 "Button number","1",
6387 if ((y = cmkey(mousemodtab,nmmtab,
6388 "Keyboard modifier","none",
6392 event |= y; /* OR in the bits */
6394 if ((y = cmkey(mclicktab,nmctab,"","click",xxstring)) < 0)
6397 /* Two bits are assigned, if neither are set then it is button one */
6399 event |= y; /* OR in the bit */
6403 if ((y = cmtxt("definition,\n\
6404 or Ctrl-C to cancel this command,\n\
6405 or Enter to restore default definition",
6410 p = s; /* Save this place */
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.
6417 for (x = 0, y = 0; s[x]; x++, y++) { /* Convert \K to \\K */
6419 (s[x] == 'K' || s[x] == 'k')
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 */
6426 if (x > 1 && s[x-1] == '{' && s[x-2] == CMDQ) {
6427 line[y-1] = CMDQ; /* Have \{K */
6428 line[y++] = '{'; /* Make it \\{K */
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");
6441 s = line + y + 1; /* Point to result. */
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.
6451 p = (*p == 'k' || *p == 'K') ? p + 1 : NULL;
6455 #endif /* NOKVERBS */
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;
6462 switch (strlen(s)) { /* Action depends on length */
6463 case 0: /* Reset to default binding */
6464 mousemapinit( button, event );
6466 case 1: /* Single character */
6467 mousemap[button][event].type = key;
6468 mousemap[button][event].key.scancode = *s;
6470 default: /* Character string */
6473 y = xlookup(kverbs,p,nkverbs,&x); /* Look it up */
6474 debug(F101,"set mouse kverb lookup",0,y); /* need exact match */
6476 /* Assign the kverb to the event */
6477 mousemap[button][event].type = kverb;
6478 mousemap[button][event].kverb.id = F_KVERB | y;
6482 #endif /* NOKVERBS */
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 */
6491 initvik = 1; /* Update VIK Table */
6492 if ( (button == XYM_B3) && (mousebuttoncount() < 3) && !quiet )
6494 printf("?Warning: this machine does not have a three button mouse.\n");
6499 #endif /* OS2MOUSE */
6500 #endif /* NOLOCAL */
6503 int /* SET SEND/RECEIVE */
6504 setsr(xx, rmsflg) int xx; int rmsflg; {
6506 ckstrncpy(line,"Parameter for inbound packets",LINBUFSIZ);
6508 ckstrncpy(line,"Parameter for outbound packets",LINBUFSIZ);
6511 if ((y = cmkey(rsrtab,nrsrtab,line,"",xxstring)) < 0) {
6513 printf("?Remote receive parameter required\n");
6518 if ((y = cmkey(srtab,nsrtab,line,"",xxstring)) < 0) return(y);
6521 case XYQCTL: /* CONTROL-PREFIX */
6522 if ((x = cmnum("ASCII value of control prefix","",10,&y,xxstring)) < 0)
6524 if ((x = cmcfm()) < 0) return(x);
6525 if ((y > 32 && y < 63) || (y > 95 && y < 127)) {
6527 ctlq = (CHAR) y; /* RECEIVE prefix, use with caution! */
6529 myctlq = (CHAR) y; /* SEND prefix, OK to change */
6530 return(success = 1);
6532 printf("?Illegal value for prefix character\n");
6537 if ((y = setcc("13",&z)) < 0)
6540 printf("Sorry, the legal values are 0-31\n");
6547 return(success = y);
6550 y = cmnum("Maximum number of characters in a packet","90",10,&x,
6552 if (xx == XYRECV) { /* Receive... */
6553 if ((y = setnum(&z,x,y,maxrps)) < 0)
6555 if (protocol != PROTO_K) {
6556 printf("?Sorry, this command does not apply to %s protocol.\n",
6557 ptab[protocol].p_name
6559 printf("Use SET SEND PACKET-LENGTH for XYZMODEM\n");
6563 printf("Sorry, 10 is the minimum\n");
6567 sstate = setgen('S', "401", ckitoa(z), "");
6568 return((int) sstate);
6570 if (protocol == PROTO_K) {
6571 if (z > MAXRP) z = MAXRP;
6572 y = adjpkl(z,wslotr,bigrbsiz);
6577 " Adjusting receive packet-length to %d for %d window slots\n",
6581 ptab[protocol].rpktlen = urpsiz;
6582 rpsiz = (y > 94) ? 94 : y;
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");
6595 } else { /* Send... */
6596 if ((y = setnum(&z,x,y,maxsps)) < 0)
6599 printf("Sorry, 10 is the minimum\n");
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)
6608 printf("Adjusting packet size to %d for %d window slots\n",
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");
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;
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");
6631 if (speed <= 0L) speed = ttgspd();
6634 Kermit does this now itself.
6636 if (speed <= 0L && z > 200 && msgflg) {
6638 Make sure your timeout interval is long enough for %d-byte packets.\n",z);
6640 #endif /* COMMENT */
6642 return(success = y);
6647 Printable start-of-packet works for UNIX and VMS only!
6650 y = cmnum("Code for packet-start character","1",10,&x,xxstring);
6652 if ((y = setnum(&z,x,y,126)) < 0) return(y);
6654 if ((y = setcc("1",&z)) < 0)
6656 #endif /* DOOMSDAY */
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 */
6667 return(success = y);
6669 case XYNPAD: /* PADDING */
6670 y = cmnum("How many padding characters for inbound packets","0",10,&x,
6672 if ((y = setnum(&z,x,y,94)) < 0) return(y);
6677 return(success = y);
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);
6684 case XYTIMO: /* TIMEOUT */
6686 y = cmnum("Packet timeout interval",ckitoa(URTIME),10,&x,xxstring);
6687 if ((y = setnum(&z,x,y,94)) < 0) return(y);
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 */
6696 } else { /* SET SEND TIMEOUT */
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 */
6708 if (y < 0) return(y);
6710 printf("?Out of range - %d\n",x);
6713 if ((z = cmkey(timotab,2,"","dynamic",xxstring)) < 0) return(z);
6715 if ((y = cmnum("Minimum timeout to allow",
6716 "1",10,&tmin,xxstring)) < 0)
6719 printf("?Out of range - %d\n",tmin);
6722 if ((y = cmnum("Maximum timeout to allow",
6723 "0",10,&tmax,xxstring)) < 0)
6725 /* 0 means let Kermit choose, < 0 means no maximum */
6727 if ((y = cmcfm()) < 0)
6729 rttflg = z; /* Round-trip timer flag */
6732 if ((y = setnum(&z,x,y,94)) < 0)
6734 #endif /* CK_TIMERS */
6735 timef = 1; /* Turn on the override flag */
6736 timint = rtimo = z; /* Override value for me to use */
6738 if (rttflg) { /* Lower and upper bounds */
6742 #endif /* CK_TIMERS */
6744 return(success = 1);
6746 case XYFPATH: /* PATHNAMES */
6748 y = cmkey(rpathtab,nrpathtab,"","auto",xxstring);
6750 y = cmkey(pathtab,npathtab,"","off",xxstring);
6752 if (y < 0) return(y);
6754 if ((x = cmcfm()) < 0) return(x);
6755 if (xx == XYRECV) { /* SET RECEIVE PATHNAMES */
6757 ptab[protocol].fnrp = fnrpath;
6758 } else { /* SET SEND PATHNAMES */
6760 ptab[protocol].fnsp = fnspath;
6762 return(success = 1); /* Note: 0 = ON, 1 = OFF */
6763 /* In other words, ON = leave pathnames ON, OFF = take them off. */
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)
6770 return(success = 1);
6772 #ifdef CKXXCHAR /* SET SEND/RECEIVE IGNORE/DOUBLE */
6777 extern short dblt[];
6778 extern int dblflag, ignflag;
6780 /* Make space for a temporary copy of the ignore/double table */
6784 if (zz == XYIGN && xx == XYSEND) {
6787 if (zz == XYDBL && xx == XYRECV) {
6790 #endif /* COMMENT */
6791 p = (short *)malloc(256 * sizeof(short));
6793 printf("?Internal error - malloc failure\n");
6796 for (i = 0; i < 256; i++) p[i] = dblt[i]; /* Copy current table */
6798 while (1) { /* Collect a list of numbers */
6800 x_ifnum = 1; /* Turn off complaints from eval() */
6802 if ((x = cmnum(zz == XYDBL ?
6803 "Character to double" :
6804 "Character to ignore",
6810 if (x == -3) /* Done */
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 */
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);
6828 "?Please specify a number or the word NONE\n");
6840 if (y < 0 || y > 255) {
6841 printf("?Please enter a character code in range 0-255\n");
6846 p[y] |= (zz == XYDBL) ? 2 : 1;
6847 if (zz == XYDBL) dblflag = 1;
6848 if (zz == XYIGN) ignflag = 1;
6849 } /* End of while loop */
6851 if ((x = cmcfm()) < 0) return(x);
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.
6857 for (i = 0; i < 256; i++) dblt[i] = p[i];
6861 return(success = 1);
6863 #endif /* CKXXCHAR */
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",
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);
6882 return(success = 1);
6883 } /* Adding a filter... */
6884 s = brstrip(s); /* Strip any braces */
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;
6893 "?Filter must contain a replacement variable for filename.\n"
6899 makestr(&sndfilter,s);
6900 makestr(&g_sfilter,s);
6902 makestr(&rcvfilter,s);
6903 makestr(&g_rfilter,s);
6905 return(success = 1);
6907 #endif /* PIPESEND */
6910 y = cmnum("Max length for protocol init string","-1",10,&x,xxstring);
6911 if ((y = setnum(&z,x,y,-1)) < 0)
6917 return(success = 1);
6920 extern int sendipkts;
6922 if ((x = seton(&sendipkts)) < 0)
6931 if ((x = seton(&atlpro)) < 0) return(x);
6935 if ((x = seton(&atlpri)) < 0) return(x);
6941 #endif /* CK_PERMS */
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)
6949 if ((x = cmcfm()) < 0)
6955 return(success = 1);
6957 #endif /* NOCSETS */
6960 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0)
6962 if ((x = cmcfm()) < 0) return(x);
6965 skipbup = (y == 0) ? 1 : 0;
6966 return(success = 1);
6969 "?Please use SET FILE COLLISION to choose the desired action\n");
6975 y = cmdir("Directory to move file(s) to after successful transfer",
6978 y = cmtxt("Directory to move file(s) to after successful transfer",
6980 #endif /* COMMENT */
6982 if (y < 0 && y != -3)
6984 ckstrncpy(line,s,LINBUFSIZ);
6988 /* Only needed for cmdir() */
6989 if ((x = cmcfm()) < 0)
6991 #endif /* COMMENT */
6993 /* Check directory existence if absolute */
6994 /* THIS MEANS IT CAN'T INCLUDE ANY DEFERRED VARIABLES! */
6996 if (isabsolute(s) && !isdir(s)) {
6997 printf("?Directory does not exist - %s\n",s);
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);
7010 makestr(&snd_move,NULL);
7011 makestr(&g_snd_move,NULL);
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);
7022 makestr(&rcv_move,NULL);
7023 makestr(&g_rcv_move,NULL);
7026 return(success = 1);
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 */
7033 ckstrncpy(line,s,LINBUFSIZ);
7035 if ((x = cmcfm()) < 0)
7039 makestr(&snd_rename,s);
7040 makestr(&g_snd_rename,s);
7042 makestr(&snd_rename,NULL);
7043 makestr(&g_snd_rename,NULL);
7047 makestr(&rcv_rename,s);
7048 makestr(&g_rcv_rename,s);
7050 makestr(&rcv_rename,NULL);
7051 makestr(&g_rcv_rename,NULL);
7054 return(success = 1);
7057 case 887: /* VERSION-NUMBERS */
7059 extern int vmssversions;
7060 return(seton(&vmssversions));
7062 extern int vmsrversions;
7063 return(seton(&vmsrversions));
7069 } /* End of SET SEND/RECEIVE... */
7076 if ((y = cmkey(xmitab,nxmit,"","",xxstring)) < 0) return(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);
7086 ckstrncpy(xmitbuf,s,XMBUFL);
7087 return(success = 1);
7089 case XMITF: /* Fill */
7090 y = cmnum("Numeric code for blank-line fill character","0",10,&x,
7092 if ((y = setnum(&z,x,y,127)) < 0) return(y);
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);
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);
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);
7118 return(success = 1);
7126 /* D O R M T -- Do a remote command */
7130 if (pflag && !quiet && fdispla != XYFD_N)
7133 " Type your escape character, %s, followed by X or E to cancel.\n",
7136 " Press the X or E key to cancel.\n"
7137 #endif /* CK_NEED_SIG */
7141 static int xzcmd = 0; /* Global copy of REMOTE cmd index */
7143 /* R E M C F M -- Confirm a REMOTE command */
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,
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.
7166 "> filename, | command,\n\
7167 or type carriage return to confirm the command",
7168 "",&s,xxstring)) < 0)
7174 debug(F101,"remcfm local","",local);
7175 debug(F110,"remcfm s",s,0);
7176 debug(F101,"remcfm cmd","",xzcmd);
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?
7193 if (!*s) { /* No redirection indicator */
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);
7205 #endif /* COMMENT */
7206 c = *s; /* We have something */
7207 if (c != '>' && c != '|') { /* Is it > or | ? */
7208 printf("?Not confirmed\n"); /* No */
7211 s++; /* See what follows */
7212 if (c == '>' && *s == '>') { /* Allow for ">>" too */
7214 remappd = 1; /* Append to output file */
7216 while (*s == SP || *s == HT) s++; /* Strip intervening whitespace */
7218 printf("?%s missing\n", c == '>' ? "Filename" : "Command");
7221 if (c == '>' && zchko(s) < 0) { /* Check accessibility */
7222 printf("?Access denied - %s\n", s);
7225 remfile = 1; /* Set global results */
7226 rempipe = (c == '|');
7232 printf("?Sorry, access to external commands is disabled.\n");
7235 makestr(&remdest,s);
7238 debug(F101,"remcfm remfile","",remfile);
7239 debug(F101,"remcfm remappd","",remappd);
7240 debug(F101,"remcfm rempipe","",rempipe);
7241 debug(F110,"remcfm remdest",remdest, 0);
7243 #endif /* NODEBUG */
7247 /* R E M T X T -- Like remcfm()... */
7249 ... but for REMOTE commands that end with cmtxt().
7250 Here we must decipher braces to discover whether the trailing
7251 redirection indicator is intended for local use, or to be sent out
7252 to the server, as in:
7254 remote host blah blah > file This end
7255 remote host { blah blah } > file This end
7256 remote host { blah blah > file } That end
7257 remote host { blah blah > file } > file Both ends
7261 remote host blah blah | cmd This end
7262 remote host { blah blah } | cmd This end
7263 remote host { blah blah | cmd } That end
7264 remote host { blah blah | cmd } | cmd Both ends
7268 remote host blah blah | cmd > file This end, etc etc...
7270 Note: this really only makes sense for REMOTE HOST, but why be picky?
7271 Call after calling cmtxt(), with pointer to string that cmtxt() parsed,
7272 as in "remtxt(&s);".
7275 1 on success with braces & redirection things removed & pointer updated,
7276 -9 on failure (bad indirection), after printing error message.
7279 remtxt(p) char ** p; {
7280 int i, x, bpos, ppos;
7283 remfile = 0; /* Initialize global results */
7291 if (!s) /* No redirection indicator */
7294 if (!*s) { /* Ditto */
7296 (xzcmd == XZDIR || xzcmd == XZTYP ||
7297 xzcmd == XZXIT || xzcmd == XZSPA ||
7298 xzcmd == XZHLP || xzcmd == XZPWD ||
7299 xzcmd == XZLGI || xzcmd == XZLGO ||
7300 xzcmd == XZWHO || xzcmd == XZHOS)) {
7301 printf("?\"%s\" has no effect in remote mode\n",cmdbuf);
7303 printf("Hint: Try again with an output redirector.\n");
7309 #endif /* COMMENT */
7310 bpos = -1; /* Position of > (bracket) */
7311 ppos = -1; /* Position of | (pipe) */
7312 x = strlen(s); /* Length of cmtxt() string */
7314 for (i = x-1; i >= 0; i--) { /* Search right to left. */
7316 if (c == '}') /* Break on first right brace */
7317 break; /* Don't look at contents of braces */
7318 else if (c == '>') /* Record position of > */
7320 else if (c == '|') /* and of | */
7323 if (bpos < 0 && ppos < 0) { /* No redirectors. */
7326 (xzcmd == XZDIR || xzcmd == XZTYP ||
7327 xzcmd == XZXIT || xzcmd == XZSPA ||
7328 xzcmd == XZHLP || xzcmd == XZPWD ||
7329 xzcmd == XZLGI || xzcmd == XZLGO ||
7330 xzcmd == XZWHO || xzcmd == XZHOS)) {
7331 printf("?\"%s\" has no effect in remote mode\n",cmdbuf);
7333 printf("Hint: Try again with an output redirector.\n");
7337 #endif /* COMMENT */
7338 s = brstrip(s); /* Remove outer braces if any. */
7339 *p = s; /* Point to result */
7340 return(1); /* and return. */
7342 remfile = 1; /* It's | or > */
7343 i = -1; /* Get leftmost symbol */
7344 if (bpos > -1) /* Bracket */
7346 if (ppos > -1 && (ppos < bpos || bpos < 0)) { /* or pipe */
7355 printf("?Sorry, access to external commands is disabled.\n");
7358 c = s[i]; /* Copy of symbol */
7360 if (c == '>' && s[i+1] == '>') /* ">>" for append? */
7361 remappd = 1; /* It's not just a flag it's a number */
7363 q = s + i + 1 + remappd; /* Point past symbol in string */
7364 while (*q == SP || *q == HT) q++; /* and any intervening whitespace */
7366 printf("?%s missing\n", c == '>' ? "Filename" : "Command");
7369 if (c == '>' && zchko(q) < 0) { /* (Doesn't work for | cmd > file) */
7370 printf("?Access denied - %s\n", q);
7373 makestr(&remdest,q); /* Create the destination string */
7374 q = s + i - 1; /* Point before symbol */
7375 while (q > s && (*q == SP || *q == HT)) /* Strip trailing whitespace */
7377 *(q+1) = NUL; /* Terminate the string. */
7378 s = brstrip(s); /* Remove any braces */
7379 *p = s; /* Set return value */
7383 debug(F101,"remtxt remfile","",remfile);
7384 debug(F101,"remtxt remappd","",remappd);
7385 debug(F101,"remtxt rempipe","",rempipe);
7386 debug(F110,"remtxt remdest",remdest, 0);
7387 debug(F110,"remtxt command",s,0);
7389 #endif /* NODEBUG */
7395 plogin(xx) int xx; {
7396 char *p1 = NULL, *p2 = NULL, *p3 = NULL;
7397 int psaved = 0, rc = 0;
7399 extern int on_recall; /* around Password prompting */
7400 #endif /* CK_RECALL */
7401 debug(F101,"plogin local","",local);
7403 if (!local || (network && ttchk() < 0)) {
7404 printf("?No connection\n");
7407 if ((x = cmfld("User ID","",&s,xxstring)) < 0) { /* Get User ID */
7408 if (x != -3) return(x);
7412 if ((p1 = malloc(y + 1)) == NULL) {
7413 printf("?Internal error: malloc\n");
7417 strcpy(p1,s); /* safe */
7418 if ((rc = cmfld("Password","",&s,xxstring)) < 0)
7419 if (rc != -3) goto XZXLGI;
7422 if ((p2 = malloc(y + 1)) == NULL) {
7423 printf("?Internal error: malloc\n");
7427 strcpy(p2,s); /* safe */
7428 if ((rc = cmfld("Account","",&s,xxstring)) < 0)
7429 if (rc != -3) goto XZXLGI;
7432 if ((p3 = malloc(y + 1)) == NULL) {
7433 printf("?Internal error: malloc\n");
7437 strcpy(p3,s); /* safe */
7441 if ((rc = remtxt(&s)) < 0) /* Confirm & handle redirectors */
7444 if (!p1) { /* No Userid specified... */
7445 debok = 0; /* Don't log this */
7446 /* Prompt for username, password, and account */
7449 #endif /* CK_RECALL */
7450 cmsavp(psave,PROMPTL); /* Save old prompt */
7452 debug(F110,"REMOTE LOGIN saved",psave,0);
7454 cmsetp("Username: "); /* Make new prompt */
7455 concb((char)escape); /* Put console in cbreak mode */
7459 for (x = -1; x < 0; ) { /* Prompt till they answer */
7460 cmres(); /* Reset the parser */
7461 x = cmtxt("","",&s,NULL); /* Get a literal line of text */
7465 printf("?Canceled\n");
7468 if ((p1 = malloc(y + 1)) == NULL) {
7469 printf("?Internal error: malloc\n");
7472 strcpy(p1,s); /* safe */
7474 cmsetp("Password: "); /* Make new prompt */
7475 concb((char)escape); /* Put console in cbreak mode */
7476 cmini(0); /* No echo */
7479 for (x = -1; x < 0 && x != -3; ) { /* Get answer */
7480 cmres(); /* Reset the parser */
7481 x = cmtxt("","",&s,NULL); /* Get literal line of text */
7483 if ((p2 = malloc((int)strlen(s) + 1)) == NULL) {
7484 printf("?Internal error: malloc\n");
7487 strcpy(p2,s); /* safe */
7489 if ((rc = cmcfm()) < 0)
7492 sstate = setgen('I',p1,p2,p3); /* Get here with at least user ID */
7495 XZXLGI: /* Common exit point */
7497 cmsetp(psave); /* Restore original prompt */
7498 if (p3) { free(p3); p3 = NULL; } /* Free malloc'd storage */
7499 if (p2) { free(p2); p2 = NULL; }
7500 if (p1) { free(p1); p1 = NULL; }
7502 if (local && rc > -1) /* If local, flush tty input buffer */
7514 int term_io_sav = term_io;
7516 extern int ftpget, ftpisopen();
7517 if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
7518 return(doftprmt(xx,0));
7522 term_io = term_io_sav;
7532 #endif /* NOLOCAL */
7537 { /* REMOTE commands */
7539 char *s, sbuf[50], *s2;
7542 extern int ftpget, ftpisopen();
7543 if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
7544 return(doftprmt(xx,0));
7547 remfile = 0; /* Clear these */
7551 if (xx < 0) return(xx); /* REMOTE what? */
7553 xzcmd = xx; /* Make global copy of arg */
7555 if (xx == XZSET) { /* REMOTE SET */
7556 if ((y = cmkey(rmstab,nrms,"","",xxstring)) < 0) {
7558 printf("?Parameter name required\n");
7565 switch (xx) { /* Others... */
7568 if ((x = cmcfm()) < 0) return(x);
7569 printf("?Sorry, REMOTE CDUP not supported yet\n");
7572 case XZCWD: /* CWD (CD) */
7573 if ((x = cmtxt("Remote directory name","",&s,xxstring)) < 0)
7575 if ((x = remtxt(&s)) < 0)
7577 debug(F111,"XZCWD: ",s,x);
7581 The following is commented out because since the disappearance of the
7582 DECSYSTEM-20 from the planet, no known computer requires a password for
7586 if (*s != NUL) { /* If directory name given, */
7587 /* get password on separate line. */
7588 if (tlevel > -1) { /* From take file... */
7590 if (fgets(sbuf,50,tfile[tlevel]) == NULL)
7591 fatal("take file ends prematurely in 'remote cwd'");
7592 debug(F110," pswd from take file",s2,0);
7593 for (x = (int)strlen(sbuf);
7594 x > 0 && (sbuf[x-1] == NL || sbuf[x-1] == CR);
7598 } else { /* From terminal... */
7600 printf(" Password: "); /* get a password */
7602 if (!local && inserver) {
7607 x = is_a_tty(0) ? coninc(0) : /* with no echo ... */
7612 while ((x != NL) && (x != CR)) {
7613 if ((x &= 0177) == '?') {
7614 printf("? Password of remote directory\n Password: ");
7617 } else if (x == ESC) /* Mini command line editor... */
7619 else if (x == BS || x == 0177)
7621 else if (x == 025) { /* Ctrl-U */
7627 /* Get the next character */
7629 if (!local && inserver) {
7634 x = is_a_tty(0) ? coninc(0) : /* with no echo ... */
7645 #endif /* DIRPWDPR */
7647 debug(F110," password",s2,0);
7649 sstate = setgen('C',s,s2,"");
7653 case XZDEL: /* Delete */
7654 if ((x = cmtxt("Name of remote file(s) to delete",
7655 "",&s,xxstring)) < 0) {
7657 printf("?Name of remote file(s) required\n");
7661 if ((x = remtxt(&s)) < 0)
7663 if (local) ttflui(); /* If local, flush tty input buffer */
7664 retcode = sstate = rfilop(s,'E');
7667 case XZDIR: /* Directory */
7668 if ((x = cmtxt("Remote directory or file specification","",&s,
7671 if ((x = remtxt(&s)) < 0)
7673 if (local) ttflui(); /* If local, flush tty input buffer */
7675 retcode = sstate = setgen('D',s,"","");
7678 case XZHLP: /* Help */
7679 if ((x = remcfm()) < 0) return(x);
7680 sstate = setgen('H',"","","");
7684 case XZHOS: /* Host */
7685 if ((x = cmtxt("Command for remote system","",&s,xxstring)) < 0)
7687 if ((x = remtxt(&s)) < 0)
7689 if ((y = (int)strlen(s)) < 1)
7691 ckstrncpy(line,s,LINBUFSIZ);
7694 retcode = sstate = 'c';
7699 if ((x = cmtxt("Command for remote Kermit","",&s,xxstring)) < 0)
7701 if ((x = remtxt(&s)) < 0)
7703 if ((int)strlen(s) < 1) {
7705 printf("?Remote Kermit command required\n");
7709 ckstrncpy(line,s,LINBUFSIZ);
7711 retcode = sstate = 'k';
7715 case XZLGI: /* Login */
7716 rcdactive = 1; /* Suppress "Logged in" msg if quiet */
7717 return(plogin(XXREM));
7719 case XZLGO: { /* Logout */
7720 extern int bye_active;
7721 if ((x = remcfm()) < 0) return(x);
7722 sstate = setgen('I',"","","");
7724 bye_active = 1; /* Close connection when done */
7728 case XZPRI: /* Print */
7729 if (!atdiso || !atcapr) { /* Disposition attribute off? */
7730 printf("?Disposition Attribute is Off\n");
7735 if ((x = cmifi("Local file(s) to print on remote printer","",&s,&y,
7738 printf("?Name of local file(s) required\n");
7743 ckstrncpy(line,s,LINBUFSIZ); /* Make a safe copy of filename */
7744 *optbuf = NUL; /* Wipe out any old options */
7745 if ((x = cmtxt("Options for remote print command","",&s,xxstring)) < 0)
7747 if ((x = remtxt(&s)) < 0)
7749 if ((int)strlen(optbuf) > 94) { /* Make sure this is legal */
7750 printf("?Option string too long\n");
7753 ckstrncpy(optbuf,s,OPTBUFLEN); /* Make a safe copy of options */
7754 nfils = -1; /* Expand file list internally */
7755 cmarg = line; /* Point to file list. */
7756 rprintf = 1; /* REMOTE PRINT modifier for SEND */
7757 sstate = 's'; /* Set start state to SEND */
7758 if (local) displa = 1;
7761 #endif /* NOFRILLS */
7763 case XZSPA: /* Space */
7764 if ((x = cmtxt("Confirm, or remote directory name",
7765 "",&s,xxstring)) < 0)
7767 if ((x = remtxt(&s)) < 0)
7769 retcode = sstate = setgen('U',s,"","");
7772 case XZMSG: /* Message */
7773 if ((x = cmtxt("Short text message for server","",&s,xxstring)) < 0)
7775 if ((x = remtxt(&s)) < 0)
7777 retcode = sstate = setgen('M',s,"","");
7781 case XZTYP: /* Type */
7782 if ((x = cmtxt("Remote file specification","",&s,xxstring)) < 0)
7784 if ((int)strlen(s) < 1) {
7785 printf("?Remote filename required\n");
7788 if ((x = remtxt(&s)) < 0)
7791 retcode = sstate = rfilop(s,'T');
7793 #endif /* NOFRILLS */
7797 if ((x = cmtxt("Remote user name, or carriage return",
7798 "",&s,xxstring)) < 0)
7800 if ((x = remtxt(&s)) < 0)
7802 retcode = sstate = setgen('W',s,"","");
7804 #endif /* NOFRILLS */
7806 case XZPWD: /* PWD */
7807 if ((x = remcfm()) < 0) return(x);
7808 sstate = setgen('A',"","","");
7813 case XZQUE: { /* Query */
7815 extern char querybuf[], * qbufp;
7817 if ((y = cmkey(vartyp,nvartyp,"","",xxstring)) < 0)
7819 if ((x = cmtxt(y == 'F' ? "Remote function invocation" :
7820 ('K' ? "Remote variable name or function":
7821 "Remote variable name"),
7824 (y == 'K') ? xxstring : NULL
7825 )) < 0) /* Don't evaluate */
7827 if ((x = remtxt(&s)) < 0)
7829 query = 1; /* QUERY is active */
7830 qbufp = querybuf; /* Initialize query response buffer */
7833 buf[0] = (char) (y & 127);
7835 retcode = sstate = setgen('V',"Q",(char *)buf,s);
7839 case XZASG: { /* Assign */
7841 if ((y = cmfld("Remote variable name","",&s,NULL)) < 0) /* No eval */
7843 if ((int)strlen(s) >= VNAML) {
7844 printf("?Too long\n");
7847 ckstrncpy(buf,s,VNAML);
7848 if ((x = cmtxt("Assignment for remote variable",
7849 "",&s,xxstring)) < 0) /* Evaluate this one */
7851 if ((x = remtxt(&s)) < 0)
7855 Server commands can't be long packets. In principle there's no reason
7856 why they shouldn't be, except that we don't know at this point if the
7857 server is capable of accepting long packets because we haven't started
7858 the protocol yet. In practice, allowing a long packet here breaks a lot
7859 of assumptions, causes buffer overruns and crashes, etc. To be fixed
7860 later. (But since this is commented out, evidently I fixed it later...)
7862 if ((int)strlen(s) > 85) { /* Allow for encoding expansion */
7863 printf("?Sorry, value is too long - 85 characters max\n");
7866 #endif /* COMMENT */
7867 retcode = sstate = setgen('V',"S",(char *)buf,s);
7872 case XZCPY: { /* COPY */
7873 char buf[TMPBUFSIZ];
7874 buf[TMPBUFSIZ-1] = '\0';
7875 if ((x = cmfld("Name of remote file to copy","",&s,xxstring)) < 0) {
7877 printf("?Name of remote file required\n");
7883 ckstrncpy(buf,s,TMPBUFSIZ);
7884 if ((x = cmfld("Name of remote destination file or directory",
7885 "",&s, xxstring)) < 0) {
7887 printf("?Name of remote file or directory required\n");
7891 ckstrncpy(tmpbuf,s,TMPBUFSIZ);
7892 if ((x = remcfm()) < 0)
7894 if (local) ttflui(); /* If local, flush tty input buffer */
7895 retcode = sstate = setgen('K',buf,tmpbuf,"");
7898 case XZREN: { /* Rename */
7899 char buf[TMPBUFSIZ];
7900 buf[TMPBUFSIZ-1] = '\0';
7901 if ((x = cmfld("Name of remote file to rename",
7902 "",&s,xxstring)) < 0) {
7904 printf("?Name of remote file required\n");
7908 ckstrncpy(buf,s,TMPBUFSIZ);
7909 if ((x = cmfld("New name of remote file","",&s, xxstring)) < 0) {
7911 printf("?Name of remote file required\n");
7915 ckstrncpy(tmpbuf,s,TMPBUFSIZ);
7916 if ((x = remcfm()) < 0)
7918 if (local) ttflui(); /* If local, flush device buffer */
7919 retcode = sstate = setgen('R',buf,tmpbuf,"");
7922 case XZMKD: /* mkdir */
7923 case XZRMD: /* rmdir */
7924 if ((x = cmtxt((xx == XZMKD) ?
7925 "Name of remote directory to create" :
7926 "Name of remote directory to delete",
7932 printf("?Name required\n");
7936 if ((x = remtxt(&s)) < 0)
7938 if (local) ttflui(); /* If local, flush tty input buffer */
7939 retcode = sstate = rfilop(s, (char)(xx == XZMKD ? 'm' : 'd'));
7942 case XZXIT: /* Exit */
7943 if ((x = remcfm()) < 0) return(x);
7944 sstate = setgen('X',"","","");
7949 if ((x = remcfm()) < 0) return(x);
7950 printf("?Not implemented - %s\n",cmdbuf);
7953 if (local && retcode > -1) /* If local, flush tty input buffer */
7959 /* R F I L O P -- Remote File Operation */
7963 rfilop(char * s, char t)
7965 rfilop(s,t) char *s, t;
7966 #endif /* CK_ANSIC */
7969 printf("?File specification required\n");
7972 debug(F111,"rfilop",s,t);
7973 return(setgen(t,s,"",""));
7980 if ((y = cmkey(x25tab,nx25,"X.25 call options","",xxstring)) < 0)
7984 if ((z = cmkey(onoff,2,"X.25 call user data","",xxstring))
7987 if ((z = cmcfm()) < 0) return(z);
7988 cudata = 0; /* disable call user data */
7989 return (success = 1);
7991 if ((x = cmtxt("X.25 call user data string","",&s,xxstring)) < 0)
7993 if ((int)strlen(s) == 0) {
7995 } else if ((int)strlen(s) > MAXCUDATA) {
7996 printf("?The length must be > 0 and <= %d\n",MAXCUDATA);
7999 if ((y = cmcfm()) < 0) return(y);
8000 ckstrncpy(udata,s,MAXCUDATA);
8001 cudata = 1; /* X.25 call user data specified */
8002 return (success = 1);
8004 if ((z = cmkey(onoff,2,"X.25 closed user group call","",xxstring))
8007 if ((z = cmcfm()) < 0) return(z);
8008 closgr = -1; /* disable closed user group */
8009 return (success = 1);
8011 if ((y = cmnum("0 <= cug index >= 99","",10,&x,xxstring)) < 0)
8013 if (x < 0 || x > 99) {
8014 printf("?The choices are 0 <= cug index >= 99\n");
8017 if ((y = cmcfm()) < 0) return(y);
8018 closgr = x; /* closed user group selected */
8019 return (success = 1);
8022 if((z = cmkey(onoff,2,"X.25 reverse charge call","",xxstring)) < 0)
8024 if ((x = cmcfm()) < 0) return(x);
8026 return (success = 1);
8033 if ((y = cmkey(padx3tab,npadx3,"PAD X.3 parameter name","",xxstring)) < 0)
8037 case PAD_BREAK_CHARACTER:
8038 if ((y = cmnum("PAD break character value","",10,&z,xxstring)) < 0)
8040 if ((y = cmcfm()) < 0) return(y);
8043 if ((y = cmnum("PAD escape","",10,&z,xxstring)) < 0) return(y);
8044 if (z != 0 && z != 1) {
8045 printf("?The choices are 0 or 1\n");
8048 if ((y = cmcfm()) < 0) return(y);
8051 if ((y = cmnum("PAD echo","",10,&z,xxstring)) < 0) return(y);
8052 if (z != 0 && z != 1) {
8053 printf("?The choices are 0 or 1\n");
8056 if ((y = cmcfm()) < 0) return(y);
8058 case PAD_DATA_FORWARD_CHAR:
8059 if ((y = cmnum("PAD data forward char","",10,&z,xxstring)) < 0)
8061 if (z != 0 && z != 2) {
8062 printf("?The choices are 0 or 2\n");
8065 if ((y = cmcfm()) < 0) return(y);
8067 case PAD_DATA_FORWARD_TIMEOUT:
8068 if ((y = cmnum("PAD data forward timeout","",10,&z,xxstring)) < 0)
8070 if (z < 0 || z > 255) {
8071 printf("?The choices are 0 or 1 <= timeout <= 255\n");
8074 if ((y = cmcfm()) < 0) return(y);
8076 case PAD_FLOW_CONTROL_BY_PAD:
8077 if ((y = cmnum("PAD pad flow control","",10,&z,xxstring)) < 0)
8079 if (z != 0 && z != 1) {
8080 printf("?The choices are 0 or 1\n");
8083 if ((y = cmcfm()) < 0) return(y);
8085 case PAD_SUPPRESSION_OF_SIGNALS:
8086 if ((y = cmnum("PAD service","",10,&z,xxstring)) < 0) return(y);
8087 if (z != 0 && z != 1) {
8088 printf("?The choices are 0 or 1\n");
8091 if ((y = cmcfm()) < 0) return(y);
8094 case PAD_BREAK_ACTION:
8095 if ((y = cmnum("PAD break action","",10,&z,xxstring)) < 0) return(y);
8096 if (z != 0 && z != 1 && z != 2 && z != 5 && z != 8 && z != 21) {
8097 printf("?The choices are 0, 1, 2, 5, 8 or 21\n");
8100 if ((y = cmcfm()) < 0) return(y);
8103 case PAD_SUPPRESSION_OF_DATA:
8104 if ((y = cmnum("PAD data delivery","",10,&z,xxstring)) < 0) return(y);
8105 if (z != 0 && z != 1) {
8106 printf("?The choices are 0 or 1\n");
8109 if ((y = cmcfm()) < 0) return(y);
8112 case PAD_PADDING_AFTER_CR:
8113 if ((y = cmnum("PAD crpad","",10,&z,xxstring)) < 0) return(y);
8114 if (z < 0 || z > 7) {
8115 printf("?The choices are 0 or 1 <= crpad <= 7\n");
8118 if ((y = cmcfm()) < 0) return(y);
8121 case PAD_LINE_FOLDING:
8122 if ((y = cmnum("PAD linefold","",10,&z,xxstring)) < 0) return(y);
8123 if (z < 0 || z > 255) {
8124 printf("?The choices are 0 or 1 <= linefold <= 255\n");
8127 if ((y = cmcfm()) < 0) return(y);
8130 case PAD_LINE_SPEED:
8131 if ((y = cmnum("PAD baudrate","",10,&z,xxstring)) < 0) return(y);
8132 if (z < 0 || z > 18) {
8133 printf("?The choices are 0 <= baudrate <= 18\n");
8136 if ((y = cmcfm()) < 0) return(y);
8139 case PAD_FLOW_CONTROL_BY_USER:
8140 if ((y = cmnum("PAD terminal flow control","",10,&z,xxstring)) < 0)
8142 if (z != 0 && z != 1) {
8143 printf("?The choices are 0 or 1\n");
8146 if ((y = cmcfm()) < 0) return(y);
8149 case PAD_LF_AFTER_CR:
8150 if ((y = cmnum("PAD crpad","",10,&z,xxstring)) < 0) return(y);
8151 if (z < 0 || z == 3 || z > 7) {
8152 printf("?The choices are 0, 1, 2, 4, 5, 6 or 7\n");
8155 if ((y = cmcfm()) < 0) return(y);
8158 case PAD_PADDING_AFTER_LF:
8159 if ((y = cmnum("PAD lfpad","",10,&z,xxstring)) < 0) return(y);
8160 if (z < 0 || z > 7) {
8161 printf("?The choices are 0 or 1 <= lfpad <= 7\n");
8164 if ((y = cmcfm()) < 0) return(y);
8168 if ((y = cmnum("PAD edit control","",10,&z,xxstring)) < 0) return(y);
8169 if (z != 0 && z != 1) {
8170 printf("?The choices are 0 or 1\n");
8173 if ((y = cmcfm()) < 0) return(y);
8176 case PAD_CHAR_DELETE_CHAR:
8177 if ((y = cmnum("PAD char delete char","",10,&z,xxstring)) < 0)
8179 if (z < 0 || z > 127) {
8180 printf("?The choices are 0 or 1 <= chardelete <= 127\n");
8183 if ((y = cmcfm()) < 0) return(y);
8186 case PAD_BUFFER_DELETE_CHAR:
8187 if ((y = cmnum("PAD buffer delete char","",10,&z,xxstring)) < 0)
8189 if (z < 0 || z > 127) {
8190 printf("?The choices are 0 or 1 <= bufferdelete <= 127\n");
8193 if ((y = cmcfm()) < 0) return(y);
8196 case PAD_BUFFER_DISPLAY_CHAR:
8197 if ((y = cmnum("PAD display line char","",10,&z,xxstring)) < 0)
8199 if (z < 0 || z > 127) {
8200 printf("?The choices are 0 or 1 <= displayline <= 127\n");
8203 if ((y = cmcfm()) < 0) return(y);
8207 return(success = 1);
8214 setat(rmsflg) int rmsflg; {
8216 if ((y = cmkey(attrtab,natr,"File Attribute packets","",xxstring)) < 0)
8218 if (y == AT_XALL) { /* ATTRIBUTES ALL ON or ALL OFF */
8219 if ((z = seton(&xx)) < 0) return(z);
8221 printf("Sorry, command not available\n");
8224 atenci = xx; /* Encoding in */
8225 atenco = xx; /* Encoding out */
8226 atdati = xx; /* Date in */
8227 atdato = xx; /* Date out */
8228 atdisi = xx; /* Disposition in/out */
8230 atleni = xx; /* Length in/out (both kinds) */
8232 atblki = xx; /* Blocksize in/out */
8234 attypi = xx; /* File type in/out */
8236 atsidi = xx; /* System ID in/out */
8238 atsysi = xx; /* System-dependent params in/out */
8240 #ifdef CK_PERMS /* Protection */
8241 atlpri = xx; /* Local in */
8242 atlpro = xx; /* Local out */
8243 atgpri = xx; /* Generic in */
8244 atgpro = xx; /* Generic out */
8245 #endif /* CK_PERMS */
8247 atfrmi = xx; /* Format in/out */
8249 atcrei = xx; /* Creator id in/out */
8251 atacti = xx; /* Account in/out */
8253 #endif /* STRATUS */
8256 } else if (y == AT_ALLY || y == AT_ALLN) { /* ATTRIBUTES ON or OFF */
8257 if ((x = cmcfm()) < 0) return(x);
8258 atcapr = (y == AT_ALLY) ? 1 : 0;
8260 sstate = setgen('S', "132", atcapr ? "1" : "0", "");
8261 return((int) sstate);
8262 } else return(success = 1);
8264 /* Otherwise, it's an individual attribute that wants turning off/on */
8266 if ((z = cmkey(onoff,2,"","",xxstring)) < 0) return(z);
8267 if ((x = cmcfm()) < 0) return(x);
8269 /* There are better ways to do this... */
8270 /* The real problem is that we're not separating the in and out cases */
8271 /* and so we have to arbitrarily pick the "in" case, i.e tell the remote */
8272 /* server to ignore incoming attributes of the specified type, rather */
8273 /* than telling it not to send them. The protocol does not (yet) define */
8274 /* codes for "in-and-out-at-the-same-time". */
8278 /* We're lumping local and generic protection together for now... */
8282 sstate = setgen('S', "143", z ? "1" : "0", "");
8283 return((int) sstate);
8285 atlpri = atlpro = atgpri = atgpro = z; break;
8286 #endif /* CK_PERMS */
8289 sstate = setgen('S', "142", z ? "1" : "0", "");
8290 return((int) sstate);
8292 atdisi = atdiso = z; break;
8295 sstate = setgen('S', "141", z ? "1" : "0", "");
8296 return((int) sstate);
8298 atenci = atenco = z; break;
8301 sstate = setgen('S', "135", z ? "1" : "0", "");
8302 return((int) sstate);
8304 atdati = atdato = z; break;
8308 sstate = setgen('S', "133", z ? "1" : "0", "");
8309 return((int) sstate);
8311 atleni = atleno = z; break;
8314 sstate = setgen('S', "139", z ? "1" : "0", "");
8315 return((int) sstate);
8317 atblki = atblko = z; break;
8320 sstate = setgen('S', "134", z ? "1" : "0", "");
8321 return((int) sstate);
8323 attypi = attypo = z; break;
8327 sstate = setgen('S', "136", z ? "1" : "0", "");
8328 return((int) sstate);
8330 atcrei = atcreo = z; break;
8333 sstate = setgen('S', "137", z ? "1" : "0", "");
8334 return((int) sstate);
8336 atacti = atacto = z; break;
8337 #endif /* STRATUS */
8340 sstate = setgen('S', "145", z ? "1" : "0", "");
8341 return((int) sstate);
8343 atsidi = atsido = z; break;
8346 sstate = setgen('S', "146", z ? "1" : "0", "");
8347 return((int) sstate);
8349 atfrmi = atfrmo = z; break;
8352 sstate = setgen('S', "147", z ? "1" : "0", "");
8353 return((int) sstate);
8355 atsysi = atsyso = z; break;
8357 printf("?Not available\n");
8367 if ((y = cmkey(inptab,ninp,"","",xxstring)) < 0) return(y);
8370 case IN_PAC: /* SET INPUT PACING */
8371 z = cmnum("milliseconds","0",10,&x,xxstring);
8372 return(setnum(&tt_inpacing,x,z,1000));
8373 case IN_TRM: /* SET INPUT TERMINAL */
8374 return(seton(&interm));
8376 case IN_DEF: /* SET INPUT DEFAULT-TIMEOUT */
8377 z = cmnum("Positive number","",10,&x,xxstring);
8378 return(setnum(&indef,x,z,94));
8380 case IN_SCA: /* SET INPUT SCALE-FACTOR */
8381 if ((x = cmfld("Number such as 2 or 0.5","1.0",&s, xxstring)) < 0)
8383 if (isfloat(s,0)) { /* A floating-point number? */
8384 extern char * inpscale;
8385 inscale = floatval; /* Yes, get its value */
8386 makestr(&inpscale,s); /* Save it as \v(inscale) */
8387 return(success = 1);
8391 #endif /* CKFLOAT */
8392 case IN_TIM: /* SET INPUT TIMEOUT-ACTION */
8393 if ((z = cmkey(intimt,2,"","",xxstring)) < 0) return(z);
8394 if ((x = cmcfm()) < 0) return(x);
8396 return(success = 1);
8397 case IN_CAS: /* SET INPUT CASE */
8398 if ((z = cmkey(incast,2,"","",xxstring)) < 0) return(z);
8399 if ((x = cmcfm()) < 0) return(x);
8401 return(success = 1);
8402 case IN_ECH: /* SET INPUT ECHO */
8403 return(seton(&inecho));
8404 case IN_SIL: /* SET INPUT SILENCE */
8405 z = cmnum("Seconds of inactivity before INPUT fails","",10,&x,
8407 return(setnum(&insilence,x,z,-1));
8409 case IN_BUF: /* SET INPUT BUFFER-SIZE */
8410 if ((z = cmnum("Number of bytes in INPUT buffer",
8411 ckitoa(INPBUFSIZ),10,&x, xxstring)) < 0)
8413 if ((y = cmcfm()) < 0) return(y);
8420 if (!(s = (char *)malloc(x + 1)))
8425 for (x = 0; x <= inbufsize; x++)
8427 return(success = 1);
8430 case IN_ADL: /* AUTODOWNLOAD */
8431 return(seton(&inautodl));
8432 #endif /* CK_AUTODL */
8434 case IN_CAN: /* SET INPUT INTERRUPTS */
8435 return(seton(&inintr));
8444 #ifndef NODIAL /* This depends on DIAL... */
8446 if (!ndinited) /* Don't free garbage... */
8448 for (i = 0; i < nhcount; i++) { /* Clean out previous list */
8455 for (j = 0; j < 4; j++) {
8465 ndinit() { /* Net directory pointers */
8466 #ifndef NODIAL /* This depends on DIAL... */
8468 if (ndinited++) /* Don't do this more than once. */
8470 for (i = 0; i < MAXDDIR; i++) { /* Init all pointers to NULL */
8473 for (i = 0; i < MAXDNUMS; i++) {
8476 for (j = 0; j < 4; j++)
8484 VOID /* Get net defaults from environment */
8488 makestr(&p,getenv("K_NET_DIRECTORY")); /* Dialing directories */
8491 xwords(p,MAXDDIR,netdir,0);
8492 for (i = 0; i < MAXDDIR; i++) { /* Fill in any gaps... */
8496 netdir[i] = netdir[i+1];
8497 debug(F111,"netdir[i]",netdir[i],i);
8502 #endif /* NETCONN */
8507 lunet(char *s) /* s = name to look up */
8510 #endif /* CK_ANSIC */
8512 #ifndef NODIAL /* This depends on DIAL... */
8513 int n, n1, t, dd = 0;
8518 int netdpy = dialdpy;
8521 nhcount = 0; /* Set this before returning */
8523 if (!s || nnetdir < 1) /* Validate arguments */
8526 if (isdigit(*s) || *s == '*' || *s == '.')
8529 if ((n1 = (int) strlen(s)) < 1) /* Length of string to look up */
8532 if (!(line = malloc(1024))) /* Allocate input buffer */
8536 f = NULL; /* Network directory file descriptor */
8537 t = nhcount = 0; /* Match count */
8538 dd = 0; /* Directory counter */
8541 while (1) { /* We make one pass */
8542 if (!f) { /* Directory not open */
8543 if (dd >= nnetdir) /* No directories left? */
8545 if ((f = fopen(netdir[dd],"r")) == NULL) { /* Open it */
8546 perror(netdir[dd]); /* Can't, print message saying why */
8548 continue; /* But go on to next one. */
8551 printf("Opening %s...\n",netdir[dd]);
8555 if (getnct(line,1023,f,1) < 0) { /* Read a line */
8556 if (f) { /* f can be clobbered! */
8557 fclose(f); /* Close the file */
8558 f = NULL; /* Indicate next one needs opening */
8562 if (!line[0]) /* Empty line */
8565 xwords(line,7,info,0); /* Parse it */
8567 if (!info[1] || !info[2] || !info[3]) /* Required fields */
8569 if (*info[1] == ';') /* Full-line comment */
8571 if ((n = (int) strlen(info[1])) < 1) /* Length of name-tag */
8573 if (n < n1) /* Search name is longer */
8574 continue; /* Can't possibly match */
8575 if (ambiguous && n != n1)
8577 if (ckstrcmp(s,info[1],n1,0)) /* Compare using length of */
8578 continue; /* search string s. */
8582 makestr(&(nh_p[nhcount]), info[3]); /* address */
8583 makestr(&(nh_p2[nhcount]),info[2]); /* net type */
8584 makestr(&(nh_px[0][nhcount]),info[4]); /* net-specific stuff... */
8585 makestr(&(nh_px[1][nhcount]),info[5]);
8586 makestr(&(nh_px[2][nhcount]),info[6]);
8587 makestr(&(nh_px[3][nhcount]),info[7]);
8589 nhcount++; /* Count this match */
8590 if (nhcount > MAXDNUMS) { /* Watch out for too many */
8591 printf("Warning: %d matches found, %d max\n",
8598 if (nhcount == 1) { /* First one - save entry name */
8599 if (n_name) { /* Free the one from before if any */
8603 if (!(n_name = (char *)malloc(n + 1))) { /* Allocate new storage */
8604 printf("?memory allocation error - lunet:3\n");
8612 t = n; /* Remember its length */
8613 strcpy(n_name,info[1]); /* safe */
8614 } else { /* Second or subsequent one */
8615 if ((int) strlen(info[1]) == t) /* Lengths compare */
8616 if (!ckstrcmp(n_name,info[1],t,0)) /* Caseless compare OK */
8619 /* Name given by user matches entries with different names */
8621 if (ambiguous) /* Been here before */
8624 ambiguous = 1; /* Now an exact match is required */
8625 ndreset(); /* Clear out previous list */
8626 goto lu_again; /* Do it all over again. */
8633 if (nhcount == 0 && ambiguous)
8634 printf("?\"%s\" - ambiguous in network directory\n",s);
8640 #endif /* NETCONN */
8643 /* C L S C O N N X -- Close connection */
8646 clsconnx(ask) int ask; {
8649 extern int ftpget, ftpisopen();
8650 if ((ftpget == 1) || ((ftpget == 2) && !local && ftpisopen()))
8651 return(success = ftpbye());
8653 debug(F101,"clsconnx local","",local);
8655 x = ask ? hupok(1) : 1; /* Make sure it's OK to close */
8658 debug(F101,"clsconnx hupok says no","",rc);
8661 ttflui(); /* Clear away buffered up junk */
8664 /* Don't hangup a line that is shared with the SLIP or PPP driver */
8665 if (!ttslip && !ttppp)
8666 #endif /* OS2ONLY */
8669 if (network && msgflg)
8670 printf(" Closing connection\n");
8671 ttclos(0); /* Close old connection, if any */
8674 extern int wasclosed, whyclosed;
8676 whyclosed = WC_CLOS;
8678 if (nmac) { /* Any macros defined? */
8680 /* printf("ON_CLOSE CLSCONNX\n"); */
8682 k = mlook(mactab,"on_close",nmac); /* Look this up */
8683 if (k >= 0) { /* If found, */
8684 if (dodo(k,ckitoa(whyclosed),0) > -1) /* set it up, */
8685 parser(1); /* and execute it */
8689 whyclosed = WC_REMO;
8694 #ifdef VMS /* Or maybe #ifndef UNIX? */
8695 else { /* Need to do this in VMS to */
8696 ttclos(0); /* free the tty channel number */
8697 rc = 1; /* obtained in ttopen() or else */
8698 } /* subsequent ttopen's won't work */
8702 if (mdmtyp < 0) { /* Switching from net to async? */
8703 if (mdmsav > -1) /* Restore modem type from last */
8704 mdmtyp = mdmsav; /* SET MODEM command, if any. */
8712 if (oldplex > -1) { /* Restore previous duplex setting. */
8716 #endif /* NETCONN */
8718 ckstrncpy(ttname,dftty,TTNAMLEN); /* Restore default communication */
8720 local = dfloc; /* device and local/remote status */
8722 cxtype = CXT_DIRECT; /* Something reasonable */
8723 speed = ttgspd(); /* Get the current speed */
8725 cxtype = CXT_REMOTE;
8729 if (xreliable > -1 && !setreliable) {
8730 reliable = xreliable;
8731 debug(F101,"clsconnx reliable A","",reliable);
8732 } else if (!setreliable) {
8733 reliable = SET_AUTO;
8734 debug(F101,"clsconnx reliable B","",reliable);
8737 setflow(); /* Revert flow control */
8742 clskconnx(x) int x; { /* Close Kermit connection only */
8743 int t, rc; /* (not FTP) */
8756 /* May 2002: setlin() decomposition starts here ... */
8759 #define SRVBUFSIZ PIPENAML
8761 #define SRVBUFSIZ 63
8763 #define HOSTNAMLEN 15*65
8766 static char * tmpstring = NULL;
8767 static char * tmpusrid = NULL;
8770 char * sshcmd = NULL;
8771 char * defsshcmd = "ssh -e none";
8774 char * sshrcmd = NULL;
8775 char * sshtmpcmd = NULL;
8776 #endif /* SSHBUILTIN */
8779 /* c x _ f a i l -- Common error exit routine for cx_net, cx_line */
8782 cx_fail(msg, text) int msg; char * text; {
8783 makestr(&slmsg,text); /* For the record (or GUI) */
8784 if (msg) /* Not GUI, not quiet, etc */
8785 printf("?%s\n",text); /* Print error message */
8786 slrestor(); /* Restore LINE/HOST to known state */
8787 return(msg ? -9 : (success = 0)); /* Return appropriate code */
8791 /* c x _ n e t -- Make a network connection */
8796 protocol = protocol type
8797 host = string pointer to host name.
8798 svc = string pointer to service or port on host.
8799 username = username for connection
8800 password = password for connection
8801 command = command to execute
8802 param1 = Telnet: Authentication type
8804 param2 = Telnet: Encryption type
8805 SSH: Command as Subsystem
8806 param3 = Telnet: 1 to wait for negotiations, 0 otherwise
8808 cx = 1 to automatically enter Connect mode, 0 otherwise.
8809 sx = 1 to automatically enter Server mode, 0 otherwise.
8810 flag = if no host name given, 1 = close current connection, 0 = resume
8811 gui = 1 if called from GUI dialog, 0 otherwise.
8814 0 on failure and no message printed, slmsg set to failure message.
8815 -9 on failure and message printed, ditto.
8819 cx_net( int net, int protocol, char * xhost, char * svc,
8820 char * username, char * password, char * command,
8821 int param1, int param2, int param3, int cx, int sx, int flag, int gui)
8822 #else /* CK_ANSIC */
8823 cx_net(net, protocol, xhost, svc,
8824 username, password, command,
8825 param1, param2, param3, cx, sx, flag, gui)
8826 char * xhost, * svc, * username, *password, *command;
8827 int net, protocol, cx, sx, flag, param1, param2, param3, gui;
8828 #endif /* CK_ANSIC */
8834 extern char pwbuf[], * g_pswd;
8835 extern int pwflg, pwcrypt, g_pflg, g_pcpt, nolocal;
8837 char srvbuf[SRVBUFSIZ+1]; /* Service */
8838 char hostbuf[HOSTNAMLEN]; /* Host buffer to manipulate */
8839 char hostname[HOSTNAMLEN]; /* Copy of host parameter */
8840 char * host = hostbuf; /* Pointer to copy of host param */
8842 if (!xhost) xhost = ""; /* Watch out for null pointers */
8844 ckstrncpy(host,xhost,HOSTNAMLEN); /* Avoid buffer confusion */
8846 debug(F110,"cx_net host",host,0);
8847 debug(F111,"cx_net service",svc,SRVBUFSIZ);
8848 debug(F101,"cx_net network type","",net);
8850 msg = (gui == 0) && msgflg; /* Whether to print messages */
8853 debug(F101,"cx_net nnetdir","",nnetdir);
8854 x = 0; /* Look up in network directory */
8855 if (*host == '=') { /* If number starts with = sign */
8856 host++; /* strip it */
8857 while (*host == SP) host++; /* and any leading spaces */
8858 debug(F110,"cx_net host 2",host,0);
8860 } else if (*host) { /* We want to look it up. */
8861 if (nnetdir > 0) /* If there is a directory... */
8862 x = lunet(host); /* (sets nhcount) */
8863 else /* otherwise */
8864 nhcount = 0; /* we didn't find any there */
8865 if (x < 0) /* Internal error? */
8866 return(cx_fail(msg,"Network directory lookup error"));
8867 debug(F111,"cx_net lunet nhcount",host,nhcount);
8871 /* New connection wanted. Make a copy of the host name/address... */
8873 if (clskconnx(1) < 0) /* Close current Kermit connection */
8874 return(cx_fail(msg,"Error closing previous connection"));
8876 if (*host) { /* They gave a hostname */
8877 _local = 1; /* Network connection always local */
8879 mdmsav = mdmtyp; /* Remember old modem type */
8880 mdmtyp = -net; /* Special code for network */
8881 } else { /* They just said "set host" */
8882 host = dftty; /* So go back to normal */
8883 _local = dfloc; /* default tty, location, */
8884 if (flag) { /* Close current connection */
8885 setflow(); /* Maybe change flow control */
8886 haveline = 1; /* (* is this right? *) */
8896 /* XXX - Is this right? */
8897 /* Should we be returning without doing anything ? */
8898 /* Yes it's right -- we closed the old connection just above. */
8899 return(success = 1);
8903 if (host != line) /* line[] is a global */
8904 ckstrncpy(line,host,LINBUFSIZ);
8905 ckstrncpy(hostname,host,HOSTNAMLEN);
8906 ckstrncpy(srvbuf,svc,SRVBUFSIZ+1);
8909 if ((nhcount > 1) && msg) {
8911 printf("%d entr%s found for \"%s\"%s\n",
8913 (nhcount == 1) ? "y" : "ies",
8915 (nhcount > 0) ? ":" : "."
8917 for (i = 0; i < nhcount; i++) {
8918 printf("%3d. %-12s => %-9s %s",
8919 i+1,n_name,nh_p2[i],nh_p[i]);
8920 for (k = 0; k < 4; k++) { /* Also list net-specific items */
8921 if (nh_px[k][i]) /* free format... */
8922 printf(" %s",nh_px[k][i]);
8938 for (i = 0; i < n; i++) { /* Loop for each entry found */
8939 debug(F101,"cx_net loop i","",i);
8941 if (nhcount > 0) { /* If we found at least one entry... */
8942 ckstrncpy(line,nh_p[i],LINBUFSIZ); /* Copy current entry */
8943 if (lookup(netcmd,nh_p2[i],nnets,&x) > -1) { /* Net type */
8945 xx = netcmd[x].kwval;
8946 /* User specified SSH so don't let net directory override */
8947 if (net != NET_SSH || xx != NET_TCPB) {
8952 makestr(&slmsg,"Network type not supported");
8954 printf("Error - network type \"%s\" not supported\n",
8959 switch (net) { /* Net-specific directory things */
8961 case NET_SSH: /* SSH */
8962 /* Any SSH specific network directory stuff? */
8963 break; /* NET_SSH */
8964 #endif /* SSHBUILTIN */
8966 case NET_TCPB: { /* TCP/IP TELNET,RLOGIN,... */
8971 /* Extract ":service", if any, from host string */
8972 debug(F110,"cx_net service 1",line,0);
8973 for (q = line; (*q != '\0') && (*q != ':'); q++)
8975 if (*q == ':') { *q++ = NUL; flag = 1; }
8976 debug(F111,"cx_net service 2",line,flag);
8978 /* Get service, if any, from directory entry */
8982 ckstrncpy(srvbuf,nh_px[0][i],SRVBUFSIZ);
8983 debug(F110,"cx_net service 3",srvbuf,0);
8986 ckstrncpy(srvbuf,q,SRVBUFSIZ);
8987 debug(F110,"cx_net service 4",srvbuf,0);
8990 ckstrncpy(hostname,line,HOSTNAMLEN);
8992 /* If we have a service, append to host name/address */
8994 ckstrncat(line, ":", LINBUFSIZ);
8995 ckstrncat(line, srvbuf, LINBUFSIZ);
8996 debug(F110,"cx_net service 5",line,0);
8999 /* If no service given but command was RLOGIN */
9000 else if (ttnproto == NP_RLOGIN) { /* add this... */
9001 ckstrncat(line, ":login",LINBUFSIZ);
9002 debug(F110,"cx_net service 6",line,0);
9004 #ifdef CK_AUTHENTICATION
9006 else if (ttnproto == NP_K4LOGIN ||
9007 ttnproto == NP_K5LOGIN) { /* add this... */
9008 ckstrncat(line, ":klogin",LINBUFSIZ);
9009 debug(F110,"cx_net service 7",line,0);
9011 else if (ttnproto == NP_EK4LOGIN ||
9012 ttnproto == NP_EK5LOGIN) { /* add this... */
9013 ckstrncat(line, ":eklogin",LINBUFSIZ);
9014 debug(F110,"cx_net service 8",line,0);
9016 #endif /* CK_KERBEROS */
9017 #endif /* CK_AUTHENTICATION */
9018 #endif /* RLOGCODE */
9019 else { /* Otherwise, add ":telnet". */
9020 ckstrncat(line, ":telnet", LINBUFSIZ);
9021 debug(F110,"cx_net service 9",line,0);
9023 if (username) { /* This is a parameter... */
9024 ckstrncpy(uidbuf,username,UIDBUFLEN);
9027 /* Fifth field, if any, is user ID (for rlogin) */
9029 if (nh_px[1][i] && !uidflag)
9030 ckstrncpy(uidbuf,username,UIDBUFLEN);
9032 if (IS_RLOGIN() && !uidbuf[0])
9033 return(cx_fail(msg,"Username required"));
9034 #endif /* RLOGCODE */
9035 #endif /* TCPSOCKET */
9038 case NET_PIPE: /* Pipe */
9040 if (!pipename[0]) { /* User didn't give a pipename */
9041 if (nh_px[0][i]) { /* But directory entry has one */
9042 if (strcmp(pipename,"\\pipe\\")) {
9043 ckstrncpy(pipename,"\\pipe\\",LINBUFSIZ);
9044 ckstrncat(srvbuf,nh_px[0][i],PIPENAML-6);
9046 ckstrncpy(pipename,nh_px[0][i],PIPENAML);
9048 debug(F110,"cx_net pipeneme",pipename,0);
9054 case NET_SLAT: /* LAT / CTERM */
9056 if (!slat_pwd[0]) { /* User didn't give a password */
9057 if (nh_px[0][i]) { /* But directory entry has one */
9058 ckstrncpy(slat_pwd,nh_px[0][i],18);
9059 debug(F110,"cx_net SuperLAT password",slat_pwd,0);
9062 #endif /* SUPERLAT */
9065 case NET_SX25: /* X.25 keyword parameters */
9069 int k; /* Cycle through the four fields */
9070 for (k = 0; k < 4; k++) {
9071 if (!nh_px[k][i]) /* Bail out if none left */
9073 if (!ckstrcmp(nh_px[k][i],"cug=",4,0)) {
9074 closgr = atoi(nh_px[k][i]+4);
9075 debug(F101,"X25 CUG","",closgr);
9076 } else if (!ckstrcmp(nh_px[k][i],"cud=",4,0)) {
9078 ckstrncpy(udata,nh_px[k][i]+4,MAXCUDATA);
9079 debug(F110,"X25 CUD",cudata,0);
9080 } else if (!ckstrcmp(nh_px[k][i],"rev=",4,0)) {
9081 revcall = !ckstrcmp(nh_px[k][i]+4,"=on",3,0);
9082 debug(F101,"X25 REV","",revcall);
9084 } else if (!ckstrcmp(nh_px[k][i],"pad=",4,0)) {
9087 s1 = s2 = nh_px[k][i]+4; /* PAD parameters */
9088 while (*s2) { /* Pick them apart */
9094 } else if (*s2 == ',') {
9098 debug(F111,"X25 PAD",x3par,x3val);
9100 x3par <= MAXPADPARMS)
9101 padparms[x3par] = x3val;
9112 default: /* Nothing special for other nets */
9117 { /* No directory entries found. */
9118 ckstrncpy(line,hostname,LINBUFSIZ); /* Put this back... */
9119 /* If the user gave a TCP service */
9120 if (net == NET_TCPB || net == NET_SSH)
9121 if (*srvbuf) { /* Append it to host name/address */
9122 ckstrncat(line, ":", LINBUFSIZ);
9123 ckstrncat(line, srvbuf,LINBUFSIZ);
9127 Get here with host name/address and all net-specific
9128 parameters set, ready to open the connection.
9130 mdmtyp = -net; /* This should have been done */
9131 /* already but just in case ... */
9133 debug(F110,"cx_net net line[] before ttopen",line,0);
9134 debug(F101,"cx_net net mdmtyp before ttopen","",mdmtyp);
9135 debug(F101,"cx_net net ttnproto","",ttnproto);
9138 if (net == NET_SSH) {
9139 makestr(&ssh_hst,hostname); /* Stash everything */
9141 if (!sl_uid_saved) {
9142 ckstrncpy(sl_uidbuf,uidbuf,UIDBUFLEN);
9145 ckstrncpy(uidbuf,username,UIDBUFLEN);
9148 makestr(&ssh_prt,srvbuf);
9150 makestr(&ssh_prt,NULL);
9153 makestr(&ssh_cmd,brstrip(command));
9156 makestr(&ssh_cmd,NULL);
9160 if (!sl_ssh_ver_saved) {
9161 sl_ssh_ver = ssh_ver;
9162 sl_ssh_ver_saved = 1;
9164 #endif /* SSHTEST */
9169 if (!sl_ssh_xfw_saved) {
9170 sl_ssh_xfw = ssh_xfw;
9171 sl_ssh_xfw_saved = 1;
9173 #endif /* SSHTEST */
9176 } else /* NET_SSH */
9177 #endif /* SSHBUILTIN */
9179 if (net == NET_TCPB) {
9184 Jeff's version from 30 Dec 2006 - doesn't work - SSL/TLS_RAW still
9185 start Telnet negotions if a 0xff byte comes in.
9188 ttnproto = NP_SSL_RAW;
9189 debug(F101,"NP_SSL_RAW ttnproto","",ttnproto);
9195 ttnproto = NP_TLS_RAW;
9196 debug(F101,"NP_TLS_RAW ttnproto","",ttnproto);
9203 debug(F101,"NP_SSL ttnproto","",ttnproto);
9210 debug(F101,"NP_TLS ttnproto","",ttnproto);
9216 ttnproto = NP_TELNET;
9217 debug(F101,"NP_SSL_TELNET ttnproto","",ttnproto);
9223 ttnproto = NP_TELNET;
9224 debug(F101,"NP_TLS_TELNET ttnproto","",ttnproto);
9229 /* fdc version of 4 Dec 2006 works OK */
9232 ssl_raw_flag = (protocol == NP_SSL_RAW) ? 1 : 0;
9233 ttnproto = protocol;
9234 debug(F101,protocol==NP_SSL ?
9236 "NP_SSL_RAW ttnproto",
9244 tls_raw_flag = (protocol == NP_SSL_RAW) ? 1 : 0;
9245 ttnproto = protocol;
9246 debug(F101,protocol==NP_TLS ?
9248 "NP_TLS_RAW ttnproto",
9256 ttnproto = NP_TELNET;
9257 debug(F101,"NP_SSL_TELNET ttnproto","",ttnproto);
9264 ttnproto = NP_TELNET;
9265 debug(F101,"NP_TLS_TELNET ttnproto","",ttnproto);
9269 #endif /* COMMENT */
9282 ttnproto = protocol;
9285 /* Jeff version from 30 Dec 2006 */
9289 /* fdc version from 4 Dec 2006 */
9294 #endif /* COMMENT */
9298 #ifdef CK_AUTHENTICATION
9299 if ((ttnproto == NP_TELNET || ttnproto == NP_KERMIT) &&
9301 if (!sl_auth_saved) {
9303 for (x = 0; x < AUTHTYPLSTSZ; x++)
9304 sl_auth_type_user[x] = auth_type_user[x];
9307 if (!sl_topt_a_s_saved) {
9308 sl_topt_a_su = TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION);
9309 sl_topt_a_s_saved = 1;
9311 if (!sl_topt_a_c_saved) {
9312 sl_topt_a_cm = TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION);
9313 sl_topt_a_c_saved = 1;
9317 auth_type_user[0] = AUTHTYPE_AUTO;
9318 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_RQ;
9319 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_RQ;
9322 auth_type_user[0] = AUTHTYPE_NULL;
9323 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_RF;
9324 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_RF;
9328 auth_type_user[0] = AUTHTYPE_SRP;
9329 auth_type_user[1] = AUTHTYPE_NULL;
9330 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9331 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9336 auth_type_user[0] = AUTHTYPE_SSL;
9337 auth_type_user[1] = AUTHTYPE_NULL;
9338 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9339 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9344 auth_type_user[0] = AUTHTYPE_NTLM;
9345 auth_type_user[1] = AUTHTYPE_NULL;
9346 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9347 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9351 case AUTHTYPE_KERBEROS_V4:
9352 auth_type_user[0] = AUTHTYPE_KERBEROS_V4;
9353 auth_type_user[1] = AUTHTYPE_NULL;
9354 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9355 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9358 case AUTHTYPE_KERBEROS_V5:
9359 auth_type_user[0] = AUTHTYPE_KERBEROS_V5;
9360 auth_type_user[1] = AUTHTYPE_NULL;
9361 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9362 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9364 #endif /* CK_KERBEROS */
9368 If the user requires a particular type of Kerberos connection,
9369 make sure we have a valid TGT.
9371 makestr(&slmsg,"Authentication failure");
9372 if ((ttnproto == NP_TELNET || ttnproto == NP_KERMIT) &&
9374 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) == TN_NG_MU ||
9376 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) == TN_NG_MU)
9379 if ( auth_type_user[0] == AUTHTYPE_KERBEROS_V4 ) {
9380 extern int krb4_autoget;
9381 if (!ck_krb4_is_installed())
9383 "Required authentication method (Kerberos 4) is not installed"));
9385 /* This code results in false failures when using */
9386 /* kerberos to machines in realms other than the */
9387 /* default since we don't know the realm of the */
9388 /* other machine until perform the reverse DNS */
9390 else if (line[0] != '*' && !ck_krb4_is_tgt_valid() &&
9392 krb4_autoget && !ck_krb4_autoget_TGT(NULL))) {
9394 "Kerberos 4: Ticket Getting Ticket not valid"));
9396 #endif /* COMMENT */
9397 } else if (auth_type_user[0] == AUTHTYPE_KERBEROS_V5) {
9398 extern int krb5_autoget;
9399 if (!ck_krb5_is_installed()) {
9401 "Required authentication method (Kerberos 5) is not installed"));
9404 /* This code results in false failures when using */
9405 /* kerberos to machines in realms other than the */
9406 /* default since we don't know the realm of the */
9407 /* other machine until perform the reverse DNS */
9409 else if (line[0] != '*' && !ck_krb5_is_tgt_valid() &&
9411 krb5_autoget && !ck_krb5_autoget_TGT(NULL))) {
9413 "Kerberos 5: Ticket Getting Ticket not valid."));
9415 #endif /* COMMENT */
9417 #endif /* CK_KERBEROS */
9419 if (auth_type_user[0] == AUTHTYPE_NTLM) {
9420 if (!ck_ntlm_is_installed()) {
9422 "Required authentication method (NTLM) is not installed"));
9423 } else if (line[0] != '*' && !ck_ntlm_is_valid(0)) {
9424 return(cx_fail(msg,"NTLM: Credentials are unavailable."));
9429 if (auth_type_user[0] == AUTHTYPE_SSL) {
9430 if (!ck_ssleay_is_installed()) {
9432 "Required authentication method (SSL) is not installed"));
9437 if (auth_type_user[0] == AUTHTYPE_SRP) {
9438 if (!ck_srp_is_installed()) {
9440 "Required authentication method (SRP) is not installed"));
9445 #endif /* CK_AUTHENTICATION */
9446 #ifdef CK_ENCRYPTION
9447 if ((ttnproto == NP_TELNET || ttnproto == NP_KERMIT) &&
9450 sl_cx_type = cx_type;
9453 if (!sl_topt_e_s_saved) {
9454 sl_topt_e_su = TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION);
9455 sl_topt_e_sm = TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION);
9456 sl_topt_e_s_saved = 1;
9458 if (!sl_topt_e_c_saved) {
9459 sl_topt_e_cu = TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION);
9460 sl_topt_e_cm = TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION);
9461 sl_topt_e_c_saved = 1;
9464 if (cx_type == CX_AUTO) {
9465 TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
9466 TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
9467 TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
9468 TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
9469 } else if (cx_type == CX_NONE) {
9470 TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
9471 TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
9472 TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
9473 TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
9475 TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
9476 TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
9477 TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
9478 TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
9481 if (ttnproto == NP_EK4LOGIN || ttnproto == NP_EK5LOGIN ||
9482 (ttnproto == NP_TELNET || ttnproto == NP_KERMIT) &&
9484 TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) == TN_NG_MU &&
9485 TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_MU) ||
9487 TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) == TN_NG_MU &&
9488 TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_MU))
9490 if (!ck_crypt_is_installed()) {
9492 "Required Encryption methods are not installed"));
9495 #endif /* CK_ENCRYPTION */
9499 if (ttnproto == NP_K4LOGIN || ttnproto == NP_EK4LOGIN) {
9500 extern int krb4_autoget;
9504 /* We don't have the full hostname at yet so */
9505 /* we do a DNS lookup before calling ttopen() */
9507 realm = ck_krb4_realmofhost(ckgetfqhostname(hostname));
9508 ckmakmsg(tgt,256,"krbtgt.",realm,"@",realm);
9509 if (!ck_krb4_is_installed()) {
9511 "Required authentication method (Kerberos 4) is not installed"
9514 if ((ck_krb4_tkt_isvalid(tgt) <= 0) &&
9516 krb4_autoget && !ck_krb4_autoget_TGT(realm))) {
9518 "Kerberos 4: Ticket Getting Ticket not valid"));
9524 if (ttnproto == NP_K5LOGIN || ttnproto == NP_EK5LOGIN ||
9525 ttnproto == NP_K5U2U)
9527 extern int krb5_autoget;
9531 /* Must get full hostname before calling ttopen() */
9533 realm = ck_krb5_realmofhost(ckgetfqhostname(hostname));
9534 ckmakmsg(tgt,256,"krbtgt/",realm,"@",realm);
9536 if (!ck_krb5_is_installed()) {
9538 "Required authentication method (Kerberos 5) not installed"));
9539 } else if (!((ck_krb5_tkt_isvalid(NULL,tgt) > 0) ||
9540 ck_krb5_is_tgt_valid()) &&
9542 krb5_autoget && !ck_krb5_autoget_TGT(realm))) {
9544 "Kerberos 5: Ticket Getting Ticket not valid."));
9548 #endif /* CK_KERBEROS */
9549 #endif /* RLOGCODE */
9554 if (!sl_uid_saved) {
9555 ckstrncpy(sl_uidbuf,uidbuf,UIDBUFLEN);
9558 ckstrncpy(uidbuf,username,UIDBUFLEN);
9561 #endif /* RLOGCODE */
9564 sl_tn_wait = tn_wait_flg;
9567 tn_wait_flg = param3;
9570 } /* if (net == NET_TCPB) */
9571 #endif /* TCPSOCKET */
9577 ckstrncpy(pwbuf,password,PWBUFL+1);
9583 #endif /* CK_SECURITY */
9586 /* Try to open - network */
9587 ckstrncpy(ttname,line,TTNAMLEN);
9588 y = ttopen(line, &_local, mdmtyp, 0 );
9591 /* If the connection failed and we are using an HTTP Proxy
9592 * and the reason for the failure was an authentication
9593 * error, then we need to give the user to ability to
9594 * enter a username and password, just like a browser.
9596 * I tried to do all of this within the netopen() call
9597 * but it is much too much work.
9599 while (y < 0 && tcp_http_proxy != NULL ) {
9601 if (tcp_http_proxy_errno == 401 ||
9602 tcp_http_proxy_errno == 407 ) {
9603 char uid[UIDBUFLEN];
9605 struct txtbox tb[2];
9609 tb[0].t_len = UIDBUFLEN;
9610 tb[0].t_lbl = "Proxy Userid: ";
9611 tb[0].t_dflt = NULL;
9615 tb[1].t_lbl = "Proxy Passphrase: ";
9616 tb[1].t_dflt = NULL;
9619 ok = uq_mtxt("Proxy Server Authentication Required\n",
9623 char * proxy_user, * proxy_pwd;
9625 proxy_user = tcp_http_proxy_user;
9626 proxy_pwd = tcp_http_proxy_pwd;
9628 tcp_http_proxy_user = uid;
9629 tcp_http_proxy_pwd = pwd;
9631 ckstrncpy(ttname,line,TTNAMLEN);
9632 y = ttopen(line, &_local, mdmtyp, 0);
9633 memset(pwd,0,sizeof(pwd));
9634 tcp_http_proxy_user = proxy_user;
9635 tcp_http_proxy_pwd = proxy_pwd;
9644 makestr(&slmsg,"Network connection failure");
9646 if (msg && hints && !xcmdsrc && IS_RLOGIN()) {
9647 makestr(&slmsg,"RLOGIN failure");
9648 if (socket_errno == EACCES) {
9649 printf("*************************\n");
9651 "Hint: RLOGIN requires privileges to open an outbound port.\n");
9653 "(Use SET HINTS OFF to suppress future hints.)\n");
9654 printf("*************************\n");
9657 #else /* Not VMS... */
9660 debug(F111,"set host line, errno","",errno);
9661 makestr(&slmsg,ck_errstr());
9664 printf("Can't connect to %s\n",line);
9667 if (hints && !xcmdsrc && IS_RLOGIN()) {
9668 makestr(&slmsg,"RLOGIN failure");
9669 printf("*************************\n");
9671 "Hint: RLOGIN requires privileges to open an outbound port.\n");
9673 "(Use SET HINTS OFF to suppress future hints.)\n");
9674 printf("*************************\n");
9678 } else printf("Can't connect to %s\n",line);
9681 if (msg) printf("Can't open connection to %s\n",line);
9693 /* This works but it messes up interactive anonymous login */
9696 /* If we have connected to an Internet Kermit service */
9697 /* and a /USER: switch was given, then log in. */
9699 if (TELOPT_U(TELOPT_KERMIT) || TELOPT_ME(TELOPT_KERMIT)) {
9700 debug(F111,"cx_net IKSD /USER:",uidbuf,haveuser);
9701 if (haveuser /* && cx == 0 */ ) { /* /USER: given */
9702 char * psw = pwbuf; /* Do we have a password? */
9703 if (!*psw) { /* No... */
9704 if (!strcmp(uidbuf,"anonymous") ||
9705 !strcmp(uidbuf,"ftp")) {
9706 extern char myhost[];
9707 char * u = (char *)sl_uidbuf;
9708 char * h = (char *)myhost;
9709 if (!*u) u = "nobody";
9710 if (!*h) h = "nowhere";
9711 ckmakmsg(tmpbuf,TMPBUFSIZ,u,"@",h,NULL);
9713 debug(F110,"cx_net IKSD anon",psw,0);
9715 readpass(" Password: ",pwbuf,PWBUFL);
9718 sstate = setgen('I',uidbuf,psw,"");
9721 #endif /* IKS_OPTION */
9723 #endif /* COMMENT */
9727 duplex = 0; /* Remote echo */
9739 cxtype = CXT_NETBIOS;
9757 debug(F101,"cx_net post ttopen success","",success);
9759 local = dfloc; /* Go back to normal */
9761 ckstrncpy(ttname,dftty,TTNAMLEN); /* Restore default tty name */
9764 network = 0; /* No network connection active */
9766 if (mdmtyp < 0) { /* Switching from net to async? */
9767 if (mdmsav > -1) /* Restore modem type from last */
9768 mdmtyp = mdmsav; /* SET MODEM command, if any. */
9773 return(0); /* Return failure */
9775 if (_local > -1) local = _local; /* Opened ok, set local/remote. */
9776 makestr(&slmsg,NULL);
9777 network = (mdmtyp < 0); /* Remember connection type. */
9778 ckstrncpy(ttname,s,TTNAMLEN); /* Copy name into real place. */
9779 debug(F110,"cx_net ok",ttname,0);
9780 debug(F101,"cx_net network","",network);
9782 if ((reliable != SET_OFF || !setreliable)) /* Assume not reliable. */
9785 if (!network || istncomport())
9786 speed = ttgspd(); /* Get the current speed. */
9787 debug(F101,"cx_net local","",local);
9789 debug(F101,"cx_net net","",net);
9791 /* Force prefixing of 255 on TCP/IP connections... */
9795 #endif /* SSHBUILTIN */
9797 debug(F101,"cx_net reliable A","",reliable);
9799 ctlp[(unsigned)255] = 1;
9800 #endif /* CK_SPEED */
9801 if ((reliable != SET_OFF || !setreliable)) {
9803 if (istncomport()) { /* Telnet communication port */
9804 reliable = SET_OFF; /* Transport is not reliable */
9805 debug(F101,"cx_net reliable istncomport()","",1);
9807 reliable = SET_ON; /* Transport is reliable end to end */
9808 debug(F101,"cx_net reliable istncomport()","",0);
9811 reliable = SET_ON; /* Transport is reliable end to end */
9812 #endif /* ifdef TN_COMPORT */
9814 debug(F101,"cx_net reliable B","",reliable);
9815 } else if (net == NET_SX25 ||
9819 duplex = 1; /* Local echo for X.25 */
9820 if (reliable != SET_OFF || !setreliable)
9821 reliable = SET_ON; /* Transport is reliable end to end */
9826 debug(F101,"cx_net reliable","",reliable);
9829 if (mdmtyp <= 0) /* Network or Direct Connection */
9830 DialerSend(OPT_KERMIT_CONNECT, 0);
9835 setflow(); /* Set appropriate flow control */
9840 #endif /* CKLOGDIAL */
9844 if (nmac) { /* Any macros defined? */
9846 k = mlook(mactab,"on_open",nmac); /* Look this up */
9847 if (k >= 0) { /* If found, */
9848 if (dodo(k,ttname,0) > -1) /* set it up, */
9849 parser(1); /* and execute it */
9855 if (local && (cx || sx)) { /* /CONNECT or /SERVER switch given */
9856 if (cx) { /* /CONNECT */
9858 /* Command was confirmed so we can pre-pop command level. */
9859 /* This is so CONNECT module won't think we're executing a */
9860 /* script if CONNECT was the final command in the script. */
9872 success = doconect(0, cmdlvl == 0 ? 1 : 0);
9875 debug(F101,"cx_net post doconect success","",success);
9878 } else if (sx) { /* /SERVER */
9884 if (local) displa = 1;
9886 reqoff(); /* No DOS requestors while server */
9899 return(success = 1);
9901 #endif /* NETCONN */
9903 /* c x _ s e r i a l -- Make a serial connection */
9907 device = string pointer to device name.
9908 cx = 1 to automatically enter Connect mode, 0 otherwise.
9909 sx = 1 to automatically enter Server mode, 0 otherwise.
9910 shr = 1 if device should be opened in shareable mode, 0 otherwise.
9911 flag = if no dev name given: 1 = close current connection, 0 = resume.
9912 gui = 1 if called from GUI dialog, 0 otherwise.
9915 0 on failure and no message printed, slmsg set to failure message.
9916 -9 on failure and message printed, ditto.
9919 /* these are bit flags */
9926 cx_serial(char *device,
9927 int cx, int sx, int shr, int flag, int gui, int special)
9928 #else /* CK_ANSIC */
9929 cx_serial(device, cx, sx, shr, flag, gui, special)
9930 char * device; int cx, sx, shr, flag, gui, special;
9931 #endif /* CK_ANSIC */
9933 int i, n, x, y, msg;
9937 debug(F110,"cx_serial device",device,0);
9939 msg = (gui == 0) && msgflg; /* Whether to print messages */
9945 debug(F101,"cx_serial mdmtyp","",mdmtyp);
9946 if (clskconnx(1) < 0) /* Close the Kermit connection */
9947 return(success = 0);
9948 if (*s) { /* They gave a device name */
9949 _local = -1; /* Let ttopen decide about it */
9950 } else { /* They just said "set line" */
9951 s = dftty; /* so go back to normal tty */
9952 _local = dfloc; /* and mode. */
9956 extern int ok_to_share;
9961 #ifdef OS2 /* Must wait until after ttclos() */
9962 #ifdef NT /* to change these settings */
9964 tttapi = special & CX_TAPI;
9965 #endif /* CK_TAPI */
9967 ttslip = special & CX_SLIP;
9968 ttppp = special & CX_PPP;
9970 ttshare = shr; /* Shareable device ? */
9971 debug(F110,"OS2 SET PORT final s",s,"");
9974 /* Open the new line */
9976 ckstrncpy(ttname,s,TTNAMLEN);
9977 if ((y = ttopen(s,&_local,mdmtyp,cdtimo)) > -1) {
9978 cxtype = (mdmtyp > 0) ? CXT_MODEM : CXT_DIRECT;
9982 /* if the line is a tapi device, then we need to auto-execute */
9983 /* SET MODEM TYPE TAPI - which we do the equivalent of here. */
9987 initmdm(38); /* From ckudia.c n_TAPI == 38 */
9989 #endif /* CK_TAPI */
9992 } else { /* Failed */
9994 if (!strcmp(s,dftty)) /* Do not generate an error with dftty */
9996 else if (y == -6 && ttslip) {
9997 makestr(&slmsg,"Can't access SLIP driver");
9998 if (msg) printf("?%s\n",slmsg);
9999 } else if (y == -6 && ttppp) {
10000 makestr(&slmsg,"Can't access PPP driver");
10001 if (msg) printf("?%s\n",slmsg);
10003 #endif /* OS2ONLY */
10005 makestr(&slmsg,"Timed out - no carrier");
10007 printf("?%s\n",slmsg);
10009 printf("\n*************************\n");
10011 "HINT (Use SET HINTS OFF to suppress future hints):\n");
10013 "Try SET CARRIER OFF and SET LINE again, or else\n");
10014 printf("SET MODEM, SET LINE, and then DIAL.\n");
10015 printf("*************************\n\n");
10018 } else if (y == -3) {
10019 makestr(&slmsg,"Access to lock denied");
10023 "Sorry, write access to UUCP lockfile directory denied.\n");
10026 printf("\n*************************\n");
10028 "HINT (Use SET HINTS OFF to suppress future hints):\n");
10030 "Please read the installation instructions file, %sckuins.txt,\n",
10031 k_info_dir ? k_info_dir : ""
10034 "or the UNIX appendix of the manual, \"Using C-Kermit\"\n"
10037 "or visit http://www.columbia.edu/kermit/ckuins.html \n"
10039 printf("*************************\n\n");
10041 #endif /* NOHINTS */
10043 printf("Sorry, access to lock denied: %s\n",s);
10046 } else if (y == -4) {
10047 makestr(&slmsg,"Access to device denied");
10049 printf("Sorry, access to device denied: %s\n",s);
10053 printf("\n*************************\n");
10055 "HINT (Use SET HINTS OFF to suppress future hints):\n");
10057 "Please read the installation instructions file, %sckuins.txt,\n",
10058 k_info_dir ? k_info_dir : ""
10061 "or the UNIX appendix of the manual, \"Using C-Kermit\".\n"
10063 printf("*************************\n\n");
10065 #endif /* NOHINTS */
10068 } else if (y == -5) {
10069 makestr(&slmsg,"Device is in use or unavailable");
10073 "Sorry, device is in use or otherwise unavailable: %s\n",s);
10075 printf("Sorry, device is in use: %s\n",s);
10077 } else { /* Other error. */
10078 makestr(&slmsg,"Device open failed");
10086 int x; /* Find a safe, long buffer */
10087 makestr(&slmsg,ck_errstr());
10089 debug(F111,"cx_serial serial errno",slmsg,errno);
10092 printf("Connection to %s failed: %s\n",s,slmsg);
10094 printf("Sorry, can't open connection: %s\n",s);
10097 network = 0; /* No network connection active */
10100 local = dfloc; /* Go back to normal */
10102 ckstrncpy(ttname,dftty,TTNAMLEN); /* Restore default tty name */
10105 if (mdmtyp < 0) { /* Switching from net to async? */
10106 if (mdmsav > -1) /* Restore modem type from last */
10107 mdmtyp = mdmsav; /* SET MODEM command, if any. */
10112 return(msg ? -9 : 0); /* Return failure */
10115 local = _local; /* Opened ok, set local/remote. */
10116 makestr(&slmsg,NULL); /* Erase SET LINE message */
10117 ckstrncpy(ttname,s,TTNAMLEN); /* Copy name into real place. */
10118 debug(F110,"cx_serial ok",ttname,0);
10120 if ((reliable != SET_OFF || !setreliable)) /* Assume not reliable. */
10121 reliable = SET_OFF;
10122 #endif /* NOXFER */
10125 setflow(); /* Set appropriate flow control */
10129 #endif /* CKLOGDIAL */
10133 if (nmac) { /* Any macros defined? */
10135 k = mlook(mactab,"on_open",nmac); /* Look this up */
10136 if (k >= 0) { /* If found, */
10137 if (dodo(k,ttname,0) > -1) /* set it up, */
10138 parser(1); /* and execute it */
10144 if (local && (cx || sx)) { /* /CONNECT or /SERVER switch given */
10145 extern int carrier;
10146 if (carrier != CAR_OFF) { /* Looking for carrier? */
10147 /* Open() turns on DTR -- wait up to a second for CD to come up */
10149 for (i = 0; i < 10; i++) { /* WAIT 1 CD... */
10151 if (x < 0 || x & BM_DCD)
10156 if (cx) { /* /CONNECT */
10157 /* Command was confirmed so we can pre-pop command level. */
10158 /* This is so CONNECT module won't think we're executing a */
10159 /* script if CONNECT was the final command in the script. */
10165 #endif /* NODIAL */
10171 success = doconect(0, cmdlvl == 0 ? 1 : 0);
10176 } else if (sx) { /* /SERVER */
10182 if (local) displa = 1;
10184 reqoff(); /* No DOS requestors while server */
10186 #endif /* NOXFER */
10191 #endif /* NODIAL */
10197 return(success = 1);
10201 /* S E T L I N -- parse name of and then open communication device. */
10204 xx == XYLINE for a serial (tty) line, XYHOST for a network host,
10205 zz == 0 means if user doesn't give a device name, continue current
10206 active connection (if any);
10207 zz != 0 means if user doesn't give a device name, then close the
10208 current connection and restore the default communication device.
10209 fc == 0 to just make the connection, 1 to also CONNECT (e.g. "telnet").
10215 extern char pwbuf[], * g_pswd;
10216 extern int pwflg, pwcrypt, g_pflg, g_pcpt, nolocal;
10218 /* int tn_wait_sv; */
10221 int c, i, haveswitch = 0;
10224 int wild = 0; /* Filespec has wildcards */
10225 int cx = 0; /* Connect after */
10226 int sx = 0; /* Become server after */
10227 int a_type = -1; /* Authentication type */
10228 int e_type = -1; /* Telnet /ENCRYPT type */
10229 #ifdef CK_ENCRYPTION
10230 int encrypt = 0; /* Encrypted? */
10231 #endif /* CK_ENCRYPTION */
10232 int shr = 0; /* Share serial device */
10233 int confirmed = 0; /* Command has been entered */
10234 struct FDB sw, tx, nx;
10242 #endif /* TCPSOCKET */
10244 char srvbuf[SRVBUFSIZ+1];
10250 int xxslip = 0, xxppp = 0;
10256 debug(F101,"setlin fc","",fc);
10257 debug(F101,"setlin zz","",zz);
10258 debug(F101,"setlin xx","",xx);
10261 if (xx == XXSSH) { /* SSH becomes PTY SSH ... */
10264 } else if (!ckstrcmp("ssh ",line,4,0)) { /* 2010/03/01 */
10268 debug(F101,"setlin dossh","",dossh);
10269 #endif /* SSHCMD */
10272 /* tn_wait_sv = tn_wait_flg; */
10273 wait = tn_wait_flg;
10275 /* tn_wait_sv = 0; */
10277 #endif /* TNCODE */
10282 makestr(&slmsg,"Making connections is disabled");
10283 printf("?Sorry, making connections is disabled\n");
10289 if (fc != 0 || zz == 0) /* Preset /CONNECT switch */
10292 debug(F101,"setlin cx","",cx);
10302 makestr(&tmpstring,NULL);
10303 #endif /* CK_SECURITY */
10305 makestr(&tmpusrid,NULL);
10306 #endif /* NETCONN */
10308 autoflow = 1; /* Enable automatic flow setting */
10310 if (xx == XYHOST) { /* SET HOST <hostname> */
10312 makestr(&slmsg,"Network connections not supported");
10313 printf("?%s\n",slmsg);
10315 #else /* NETCONN */
10317 if ((mynet == NET_CMD || mynet == NET_PTY || dossh) && nopush) {
10318 makestr(&slmsg,"Access to external commands is disabled");
10319 printf("?Sorry, access to external commands is disabled\n");
10322 #endif /* NOPUSH */
10325 if (dossh) { /* SSH connection via pty */
10327 extern int ttyfd; /* 2010/03/01 */
10328 k = ckstrncpy(line, sshcmd ? sshcmd : defsshcmd, LINBUFSIZ);
10329 debug(F111,"setlin sshcmd 1",line,k);
10330 if ((x = cmtxt("Optional switches and hostname","",&s,xxstring))<0)
10334 if (!*s && ttyfd < 0 && !ckstrcmp("ssh ",ttname,4,0)) {
10335 x = ckstrncpy(line,ttname,LINBUFSIZ);
10338 printf("?SSH to where?\n");
10341 if (k < LINBUFSIZ) {
10344 debug(F111,"setlin sshcmd 2",line,k);
10345 } if (k < LINBUFSIZ) {
10346 ckstrncpy(&line[k],s,LINBUFSIZ-k);
10347 debug(F111,"setlin sshcmd 3",line,k);
10349 printf("?Too long\n");
10353 x = cx_net( NET_PTY, /* network type */
10354 0, /* protocol (not used) */
10356 NULL, /* service (not used) */
10357 NULL, /* username (not used) */
10358 NULL, /* password (not used) */
10359 NULL, /* command (not used) */
10360 -1,-1,-1, /* params 1-3 (not used) */
10361 1, /* connect immediately */
10363 zz, /* close current? */
10365 debug(F111,"setlin cx_net",line,x);
10368 #endif /* SSHCMD */
10371 Here we parse optional switches and then the hostname or whatever,
10372 which depends on the network type. The tricky part is, the network type
10373 can be set by a switch.
10376 makestr(&g_pswd,pwbuf); /* Save global pwbuf */
10377 g_pflg = pwflg; /* and flag */
10384 if (mynet != NET_FILE) {
10385 #endif /* NETFILE */
10386 ss = (mynet == NET_CMD || mynet == NET_PTY) ?
10387 "Command, or switch" :
10388 (mynet == NET_TCPA || mynet == NET_TCPB
10389 || mynet == NET_SSH) ?
10390 "Hostname, ip-address, or switch" :
10393 if (mynet == NET_TCPB &&
10394 (ttnproto == NP_TELNET || ttnproto == NP_KERMIT)) {
10397 cmfdbi(&sw,_CMKEY,ss,"","",nshteltab,4,xxstring,
10402 else if (mynet == NET_TCPB && ttnproto == NP_RLOGIN) {
10405 cmfdbi(&sw,_CMKEY,ss,"","",nshrlgtab,4,xxstring,
10409 #endif /* RLOGCODE */
10412 cmfdbi(&sw,_CMKEY,ss,"","",nshtab,4,xxstring,shtab,&nx);
10416 #endif /* NETFILE */
10417 if (mynet == NET_TCPB || mynet == NET_SLAT ||
10418 mynet == NET_SSH || mynet == NET_DEC) {
10419 cmfdbi(&nx,_CMFLD,"Host","","",0,0,xxstring,NULL,NULL);
10421 } else if (mynet == NET_FILE) {
10422 cmfdbi(&nx,_CMIFI,"Filename","","",0,0,xxstring,NULL,NULL);
10423 #endif /* NETFILE */
10425 } else if (mynet == NET_CMD || mynet == NET_PTY) {
10426 cmfdbi(&nx,_CMTXT,"Command","","",0,0,xxstring,NULL,NULL);
10427 #endif /* PTYORPIPE */
10429 cmfdbi(&nx,_CMTXT,"Host","","",0,0,xxstring,NULL,NULL);
10432 x = cmfdb(haveswitch ? &sw : &nx);
10433 debug(F101,"setlin cmfdb","",x);
10438 if ((x = cmcfm()) < 0) {
10445 if (cmresult.fcode != _CMKEY) { /* Not a switch */
10446 ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Save the data */
10447 s = line; /* that was parsed... */
10448 if (cmresult.fcode == _CMIFI) {
10449 wild = cmresult.nresult;
10450 } else if (cmresult.fcode == _CMTXT) {
10453 break; /* and break out of this loop */
10455 c = cmgbrk(); /* Have switch - get break character */
10456 getval = (c == ':' || c == '='); /* Must parse an agument? */
10457 if (getval && !(cmresult.kflags & CM_ARG)) {
10458 printf("?This switch does not take arguments\n");
10461 if (!getval && (cmgkwflgs() & CM_ARG)) {
10462 printf("?This switch requires an argument\n");
10465 switch (cmresult.nresult) { /* It's a switch.. */
10466 case SL_CNX: /* /CONNECT */
10470 case SL_SRV: /* /SERVER */
10475 case SL_CMD: /* /COMMAND */
10479 #endif /* NETCMD */
10481 case SL_PTY: /* /PTY */
10485 #endif /* NETPTY */
10486 case SL_NET: /* /NETWORK-TYPE */
10487 if ((x = cmkey(netcmd,nnets,"","",xxstring)) < 0)
10493 case SL_PSW: /* /PASSWORD: */
10497 if ((x = cmfld("Password","",&s,xxstring)) < 0) {
10499 makestr(&tmpstring,"");
10505 if ((x = (int)strlen(s)) > PWBUFL) {
10506 makestr(&slmsg,"Internal error");
10507 printf("?Sorry, too long - max = %d\n",PWBUFL);
10510 makestr(&tmpstring,s);
10513 #endif /* CK_SECURITY */
10515 case SL_UID: /* /USERID: */
10518 if ((x = cmfld("Userid","",&s,xxstring)) < 0) {
10520 makestr(&tmpusrid,"");
10526 if ((x = (int)strlen(s)) > 63) {
10527 makestr(&slmsg,"Internal error");
10528 printf("?Sorry, too long - max = %d\n",63);
10531 makestr(&tmpusrid,s);
10536 #ifdef CK_AUTHENTICATION
10539 a_type = AUTHTYPE_SRP;
10541 #endif /* CK_SRP */
10544 a_type = AUTHTYPE_SSL;
10546 #endif /* CK_SSL */
10549 a_type = AUTHTYPE_NTLM;
10554 a_type = AUTHTYPE_KERBEROS_V4;
10555 if (ttnproto == NP_RLOGIN)
10557 #ifdef CK_ENCRYPTION
10558 encrypt ? NP_EK4LOGIN :
10559 #endif /* CK_ENCRYPTION */
10561 else if (ttnproto == NP_K5LOGIN)
10562 ttnproto = NP_K4LOGIN;
10563 #ifdef CK_ENCRYPTION
10564 else if (ttnproto == NP_EK5LOGIN)
10565 ttnproto = NP_EK4LOGIN;
10566 #endif /* CK_ENCRYPTION */
10569 a_type = AUTHTYPE_KERBEROS_V5;
10570 if (ttnproto == NP_RLOGIN)
10572 #ifdef CK_ENCRYPTION
10573 encrypt ? NP_EK5LOGIN :
10574 #endif /* CK_ENCRYPTION */
10576 else if (ttnproto == NP_K4LOGIN)
10577 ttnproto = NP_K5LOGIN;
10578 #ifdef CK_ENCRYPTION
10579 else if (ttnproto == NP_EK4LOGIN)
10580 ttnproto = NP_EK5LOGIN;
10581 #endif /* CK_ENCRYPTION */
10583 #endif /* CK_KERBEROS */
10585 extern struct keytab autyptab[];
10587 if ((x = cmkey(autyptab,nautyp,"type of authentication",
10588 "automatic",xxstring)) < 0)
10593 #endif /* CK_AUTHENTICATION */
10594 #ifdef CK_ENCRYPTION
10596 switch (ttnproto) {
10598 ttnproto = NP_EK4LOGIN;
10602 ttnproto = NP_EK5LOGIN;
10607 static struct keytab * tnetbl = NULL;
10608 static int ntnetbl = 0;
10609 x = ck_get_crypt_table(&tnetbl,&ntnetbl);
10610 debug(F101,"ck_get_crypt_table x","",x);
10611 debug(F101,"ck_get_crypt_table n","",ntnetbl);
10612 if (x < 1 || !tnetbl || ntnetbl < 1) /* Didn't get it */
10615 makestr(&slmsg,"Internal error");
10616 printf("?Oops, types not loaded\n");
10619 if ((x = cmkey(tnetbl,ntnetbl,"type of encryption",
10620 "automatic",xxstring)) < 0)
10627 #endif /* CK_ENCRYPTION */
10638 if (mynet == NET_FILE) { /* Parsed by cmifi() */
10639 if ((x = cmcfm()) < 0) /* Needs confirmation */
10641 x = cx_net(mynet, /* nettype */
10642 0, /* protocol (not used) */
10645 NULL, /* alternate username */
10646 NULL, /* password */
10647 NULL, /* command to execute */
10651 cx, /* enter CONNECT mode */
10652 sx, /* enter SERVER mode */
10653 zz, /* close connection if open */
10657 #endif /* NETFILE */
10660 if (mynet == NET_CMD || mynet == NET_PTY) {
10663 if ((x = cmtxt("Rest of command","",&s,xxstring)) < 0)
10666 ckstrncat(line," ",LINBUFSIZ);
10667 ckstrncat(line,s,LINBUFSIZ);
10671 /* s == line - so we must protect the line buffer */
10674 ckstrncpy(line,p,LINBUFSIZ);
10677 x = cx_net( mynet, /* nettype */
10678 0, /* protocol (not used) */
10681 NULL, /* alternate username */
10682 NULL, /* password */
10683 NULL, /* command to execute */
10687 cx, /* enter CONNECT mode */
10688 sx, /* enter SERVER mode */
10689 zz, /* close connection if open */
10693 #endif /* NETCMD */
10695 #ifdef NPIPE /* Named pipe */
10696 if (mynet == NET_PIPE) { /* Needs backslash twiddling */
10698 if (strcmp(line,"*")) { /* If remote, begin with */
10701 ckstrncpy(line,"\\\\",LINBUFSIZ); /* server name */
10702 ckstrncat(line,p,LINBUFSIZ);
10707 ckstrncat(line,"\\pipe\\", LINBUFSIZ); /* Make pipe name */
10708 ckstrncat(line,pipename, LINBUFSIZ); /* Add name of pipe */
10710 x = cx_net(mynet, /* nettype */
10711 0, /* protocol (not used) */
10714 NULL, /* alternate username */
10715 NULL, /* password */
10716 NULL, /* command to execute */
10720 cx, /* enter CONNECT mode */
10721 sx, /* enter SERVER mode */
10722 zz, /* close connection if open */
10730 if (mynet == NET_SLAT) { /* Needs password, etc. */
10731 slat_pwd[0] = NUL; /* Erase any previous password */
10733 if (*line) { /* If they gave a host name... */
10735 "password,\n or carriage return if no password required",
10741 ckstrncpy(slat_pwd,s,18); /* Set the password, if any */
10743 if ((x = cmcfm()) < 0) return(x); /* Confirm the command */
10745 x = cx_net(mynet, /* nettype */
10746 0, /* protocol (not used) */
10749 NULL, /* alternate username */
10750 NULL, /* password */
10751 NULL, /* command to execute */
10755 cx, /* enter CONNECT mode */
10756 sx, /* enter SERVER mode */
10757 zz, /* close connection if open */
10761 #endif /* SUPERLAT */
10764 if (mynet == NET_DEC) {
10765 if (!line[0]) { /* If they gave a host name... */
10766 printf("?hostname required\n");
10769 if ((x = cmcfm()) < 0) return(x); /* Confirm the command */
10771 x = cx_net(mynet, /* nettype */
10772 0, /* protocol (not used) */
10775 NULL, /* alternate username */
10776 NULL, /* password */
10777 NULL, /* command to execute */
10781 cx, /* enter CONNECT mode */
10782 sx, /* enter SERVER mode */
10783 zz, /* close connection if open */
10787 #endif /* DECNET */
10790 if (mynet == NET_SSH) { /* SSH connection */
10791 int k, havehost = 0, trips = 0;
10792 int tmpver = -1, tmpxfw = -1, tmpssh_cas;
10794 extern int sl_ssh_xfw, sl_ssh_xfw_saved;
10795 extern int sl_ssh_ver, sl_ssh_ver_saved;
10796 #endif /* SSHTEST */
10797 extern struct keytab sshopnsw[];
10798 extern int nsshopnsw;
10799 extern char *ssh_tmpcmd, *ssh_tmpport;
10800 struct FDB sw, kw, fl;
10802 debug(F110,"setlin SSH service 0",srvbuf,0);
10803 debug(F110,"setlin SSH host s 2",s,0);
10804 if (*s) { /* If they gave a host name... */
10805 debug(F110,"setlin SSH host s 1",s,0);
10807 makestr(&slmsg,"Incoming connections not supported");
10809 "?Sorry, incoming connections not supported for SSH.\n"
10813 ckstrncpy(line,s,LINBUFSIZ);
10815 printf("?hostname required\n");
10819 /* Parse [ port ] [ switches ] */
10820 cmfdbi(&kw, /* Switches */
10822 "Port number or service name,\nor switch",
10831 cmfdbi(&fl, /* Port number or service name */
10842 trips = 0; /* Explained below */
10843 while (1) { /* Parse port and switches */
10844 y = cmfdb(&kw); /* Get a field */
10845 if (y == -3) /* User typed CR so quit from loop */
10847 if (y < 0) /* Other parse error, pass it back */
10849 switch (cmresult.fcode) { /* Field or Keyword? */
10850 case _CMFLD: /* Field */
10851 ckstrncpy(srvbuf,cmresult.sresult,SRVBUFSIZ);
10853 case _CMKEY: /* Keyword */
10854 switch (cmresult.nresult) { /* Which one? */
10857 printf("?This switch requires an argument\n");
10861 if ((y = cmfld("Password","",&s,xxstring)) < 0) {
10863 makestr(&tmpstring,"");
10869 if ((y = (int)strlen(s)) > PWBUFL) {
10870 makestr(&slmsg,"Internal error");
10871 printf("?Sorry, too long - max = %d\n",PWBUFL);
10874 makestr(&tmpstring,s);
10877 case SSHSW_USR: /* /USER: */
10879 printf("?This switch requires an argument\n");
10882 if ((y = cmfld("Username","",&s,xxstring)) < 0)
10885 makestr(&tmpusrid,s);
10888 if ((y = cmnum("Number","",10,&z,xxstring)) < 0)
10890 if (z < 1 || z > 2) {
10891 printf("?Out of range: %d\n",z);
10898 if ((y = cmfld("Text","",&s,xxstring)) < 0)
10900 makestr(&ssh_tmpcmd,s);
10901 tmpssh_cas = (cmresult.nresult == SSHSW_SUB);
10904 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0)
10912 if (trips++ == 0) { /* After first time through */
10913 cmfdbi(&kw, /* only parse switches, not port. */
10926 if ((y = cmcfm()) < 0) /* Get confirmation */
10929 debug(F110,"setlin pre-cx_net line",line,0);
10930 debug(F110,"setlin pre-cx_net srvbuf",srvbuf,0);
10931 x = cx_net( mynet, /* nettype */
10932 0, /* protocol (not used) */
10935 tmpusrid, /* alternate username */
10936 tmpstring, /* password */
10937 ssh_tmpcmd, /* command to execute */
10938 tmpver, /* param1 - ssh version */
10939 tmpssh_cas, /* param2 - ssh cas */
10940 tmpxfw, /* param3 - ssh x11fwd */
10941 cx, /* enter CONNECT mode */
10942 sx, /* enter SERVER mode */
10943 zz, /* close connection if open */
10947 makestr(&tmpusrid,NULL);
10949 makestr(&ssh_tmpcmd,NULL);
10951 #endif /* SSHBUILTIN */
10954 if (mynet == NET_TCPB) { /* TCP/IP connection */
10955 debug(F110,"setlin service 0",srvbuf,0);
10956 debug(F110,"setlin host s 2",s,0);
10957 if (*s) { /* If they gave a host name... */
10958 debug(F110,"setlin host s 1",s,0);
10961 makestr(&slmsg,"Incoming connections not supported");
10963 "?Sorry, incoming connections not supported in this version of Kermit.\n"
10967 #endif /* NOLISTEN */
10969 /* Allow a username if rlogin is requested */
10970 if (mynet == NET_TCPB &&
10971 (ttnproto == NP_RLOGIN || ttnproto == NP_K5LOGIN ||
10972 ttnproto == NP_EK5LOGIN || ttnproto == NP_K4LOGIN ||
10973 ttnproto == NP_EK4LOGIN
10977 /* Check for "host:service" */
10978 for ( ; (*s != '\0') && (*s != ':'); s++) ;
10979 if (*s) { /* Service, save it */
10981 ckstrncpy(srvbuf,++s,SRVBUFSIZ);
10982 } else { /* No :service, then use default. */
10984 switch (ttnproto) {
10986 ckstrncpy(srvbuf,"513",SRVBUFSIZ); /* "login" */
10990 ckstrncpy(srvbuf,"543",SRVBUFSIZ); /* "klogin" */
10994 ckstrncpy(srvbuf,"2105",SRVBUFSIZ); /* "eklogin" */
10998 switch (ttnproto) {
11000 ckstrncpy(srvbuf,"login",SRVBUFSIZ);
11004 ckstrncpy(srvbuf,"klogin",SRVBUFSIZ);
11008 ckstrncpy(srvbuf,"eklogin",SRVBUFSIZ);
11014 y = cmfld("Userid on remote system",
11015 uidbuf,&s,xxstring);
11016 if (y < 0 && y != -3)
11018 if ((int)strlen(s) > 63) {
11019 makestr(&slmsg,"Internal error");
11020 printf("Sorry, too long\n");
11023 makestr(&tmpusrid,s);
11025 } else { /* TELNET or SET HOST */
11026 #endif /* RLOGCODE */
11027 /* Check for "host:service" */
11028 for ( ; (*s != '\0') && (*s != ':'); s++) ;
11029 if (*s) { /* Service, save it */
11031 ckstrncpy(srvbuf,++s,SRVBUFSIZ);
11032 } else if (!confirmed) {
11033 /* No :service, let them type one. */
11034 if (*line != '*') { /* Not incoming */
11035 if (mynet == NET_TCPB && ttnproto == NP_KERMIT) {
11037 "TCP service name or number",
11038 "kermit",&s,xxstring)
11042 } else if (mynet == NET_TCPB &&
11043 ttnproto == NP_RLOGIN) {
11045 "TCP service name or number,\n or carriage return for rlogin (513)",
11046 "login",&s,xxstring)
11049 #ifdef CK_AUTHENTICATION
11051 } else if (mynet == NET_TCPB &&
11052 (ttnproto == NP_K4LOGIN ||
11053 ttnproto == NP_K5LOGIN)) {
11055 "TCP service name or number,\n or carriage return for klogin (543)",
11056 "klogin",&s,xxstring)
11059 } else if (mynet == NET_TCPB &&
11060 (ttnproto == NP_EK4LOGIN ||
11061 ttnproto == NP_EK5LOGIN)) {
11063 "TCP service name or number,\n or carriage return for eklogin (2105)",
11064 "eklogin",&s,xxstring)
11067 #endif /* CK_KERBEROS */
11068 #endif /* CK_AUTHENTICATION */
11069 #endif /* RLOGCODE */
11071 /* Do not set a default value in this call */
11072 /* If you do then it will prevent entries */
11073 /* in the network directory from accessing */
11074 /* alternate ports. */
11077 "TCP service name or number",
11082 } else { /* Incoming connection */
11083 if ((x = cmfld("TCP service name or number",
11088 if (*s) /* If they gave a service, */
11089 ckstrncpy(srvbuf,s,SRVBUFSIZ); /* copy it */
11090 debug(F110,"setlin service 0.5",srvbuf,0);
11094 #endif /* RLOGCODE */
11097 switch (ttnproto) {
11099 defproto = "/rlogin";
11102 defproto = "/k4login";
11105 defproto = "/k5login";
11108 defproto = "/ek4login";
11111 defproto = "/ek5login";
11115 defproto = "/telnet";
11118 defproto = "/default";
11120 if ((x = cmkey(tcprawtab,ntcpraw,"Switch",defproto,
11124 else if ((x = cmcfm()) < 0)
11128 if ((x = cmcfm()) < 0)
11133 debug(F110,"setlin pre-cx_net line",line,0);
11134 debug(F110,"setlin pre-cx_net srvbuf",srvbuf,0);
11135 x = cx_net( mynet, /* nettype */
11136 rawflg /* protocol */,
11139 tmpusrid, /* alternate username */
11140 tmpstring, /* password */
11141 NULL, /* command to execute */
11142 a_type, /* param1 - telnet authtype */
11143 e_type, /* param2 - telnet enctype */
11144 wait, /* param3 - telnet wait */
11145 cx, /* enter CONNECT mode */
11146 sx, /* enter SERVER mode */
11147 zz, /* close connection if open */
11151 #endif /* TCPSOCKET */
11155 makestr(&tmpstring,NULL);
11156 #endif /* CK_SECURITY */
11158 makestr(&tmpusrid,NULL);
11159 debug(F111,"setlin cx_net",line,x);
11161 #endif /* NETCONN */
11164 /* Serial tty device, possibly modem, connection... */
11169 COM1..COM8 = Regular COM port
11170 1..8 = Synonym for COM1..COM8, is translated to COM1..COM8
11171 _n = (n is a number) = open file handle
11172 string = any text string = name of some other kind of device,
11173 taken literally, as given.
11175 s = "Communication device name";
11179 cktapiBuildLineTable(&tapilinetab, &_tapilinetab, &ntapiline);
11180 if (!(tapilinetab && _tapilinetab && ntapiline > 0) &&
11181 xx == XYTAPI_LIN ) {
11182 makestr(&slmsg,"TAPI device not configured");
11183 printf("\nNo TAPI Line Devices are configured for this system\n");
11186 if (xx == XYTAPI_LIN) { /* Default (first) TAPI line */
11187 s = "tapi"; /* (whatever it is) */
11188 } else { /* Query the user */
11189 #endif /* CK_TAPI */
11191 /* Now parse optional switches and then device name */
11194 cmfdbi(&sw,_CMKEY,"Device name, or switch",
11195 "","",npsltab,4,xxstring,psltab,&fl);
11196 cmfdbi(&fl,_CMFLD,"",dftty,"",0,0,xxstring,NULL,NULL);
11199 debug(F101,"setlin cmfdb","",x);
11204 if ((x = cmcfm()) < 0) {
11211 if (cmresult.fcode == _CMFLD) {
11212 s = cmresult.sresult;
11214 } else if (cmresult.fcode == _CMKEY) {
11215 switch (cmresult.nresult) {
11216 case SL_CNX: /* /CONNECT */
11220 case SL_SRV: /* /SERVER */
11224 case SL_SHR: /* /SHARE */
11227 case SL_NSH: /* /NOSHARE */
11235 #endif /* CK_TAPI */
11237 debug(F110,"OS2 SET PORT s",s,0);
11238 y = lookup(os2devtab,s,nos2dev,&x); /* Look up in keyword table */
11239 debug(F101,"OS2 SET PORT x","",x);
11240 debug(F101,"OS2 SET PORT y","",y);
11241 if ((y > -1) && (x >= 0 && x < 8)) { /* User typed a digit 1..8 */
11242 s = os2devtab[x+8].kwd; /* Substitite its real name */
11246 xxslip = xxppp = 0;
11248 debug(F110,"OS2 SET PORT subst s",s,"");
11250 } else if ((y >-1) && (x >= 16 && x < 24)) { /* SLIP access */
11251 s = os2devtab[x-8].kwd; /* Substitite its real name */
11252 debug(F110,"OS2 SET PORT SLIP subst s",s,"");
11255 } else if ((y >-1) && (x >= 24 && x < 32)) { /* PPP access */
11256 s = os2devtab[x-16].kwd; /* Substitite its real name */
11257 debug(F110,"OS2 SET PORT PPP subst s",s,"");
11260 if ((y = cmkey(os2ppptab,
11262 "PPP driver interface",
11267 debug(F101,"OS2 SET PORT PPP INTERFACE y","",y);
11268 xxppp = (y % 10) + 1;
11270 } else if (*s == '_') { /* User used "_" prefix */
11271 s++; /* Remove it */
11272 /* Rest must be numeric */
11273 debug(F110,"OS2 SET PORT HANDLE _subst s",s,0);
11275 makestr(&slmsg,"Invalid file handle");
11276 printf("?Invalid format for file handle\n");
11282 xxslip = xxppp = 0;
11284 } else { /* A normal COMx port or a string */
11285 s = brstrip(s); /* Strip braces if any */
11288 /* Windows TAPI support - Look up in keyword table */
11289 if (tapilinetab && _tapilinetab && ntapiline > 0) {
11290 if (!ckstrcmp(s,"tapi",4,0)) {
11292 /* Find out what the lowest numbered TAPI device is */
11293 /* and use it as the default. */
11294 int j = 9999, k = -1;
11295 for (i = 0; i < ntapiline; i++) {
11296 if (tapilinetab[i].kwval < j) {
11297 j = tapilinetab[i].kwval;
11302 s = _tapilinetab[k].kwd;
11306 if ((y = cmkey(_tapilinetab,ntapiline,
11307 "TAPI device name",s,xxstring)) < 0)
11312 /* Get the non Underscored string */
11313 for (i = 0; i < ntapiline; i++ ) {
11314 if (tapilinetab[i].kwval == y) {
11315 s = tapilinetab[i].kwd;
11322 #endif /* CK_TAPI */
11324 /* not OS/2 SLIP or PPP */
11325 xxslip = xxppp = 0;
11328 ckstrncpy(tmpbuf,s,TMPBUFSIZ); /* Copy to a safe place */
11330 if ((x = cmcfm()) < 0)
11335 cmfdbi(&sw,_CMKEY,"Device name, or switch",
11336 "","",npsltab,4,xxstring,psltab,&tx);
11337 cmfdbi(&tx,_CMTXT,"",dftty,"",0,0,xxstring,NULL,NULL);
11338 while (!confirmed) {
11340 debug(F101,"setlin cmfdb","",x);
11345 if ((x = cmcfm()) < 0) {
11352 switch (cmresult.fcode) {
11354 ckstrncpy(tmpbuf,cmresult.sresult,TMPBUFSIZ);
11356 debug(F110,"setlin CMTXT",tmpbuf,0);
11359 case _CMKEY: /* Switch */
11360 debug(F101,"setlin CMKEY",tmpbuf,cmresult.nresult);
11361 switch (cmresult.nresult) {
11362 case SL_CNX: /* /CONNECT */
11366 case SL_SRV: /* /SERVER */
11371 case SL_SHR: /* /SHARE */
11374 case SL_NSH: /* /NOSHARE */
11381 debug(F101,"setlin bad cmfdb result","",cmresult.fcode);
11382 makestr(&slmsg,"Internal error");
11383 printf("?Internal parsing error\n");
11389 if ((x = cmcfm()) < 0)
11392 debug(F110,"setlin pre-cx_serial s",s,0);
11393 debug(F110,"setlin pre-cx_serial line",line,0);
11394 x = cx_serial(s,cx,sx,shr,zz,0,
11397 (xxtapi ? CX_TAPI : 0)
11399 (xxslip ? CX_SLIP : 0) | (xxppp ? CX_PPP : 0)
11405 debug(F111,"setlin cx_serial",line,x);
11408 #endif /* NOLOCAL */
11412 C-Library based file-i/o package for scripts. This should be portable to
11413 all C-Kermit versions since it uses the same APIs we have always used for
11414 processing command files. The entire channel i/o package is contained
11415 herein, apart from some keyword table entries in the main keyword table
11416 and the help text in the HELP command module.
11418 On platforms like VMS and VOS, this package handles only UNIX-style
11419 stream files. If desired, it can be replaced for those platforms by
11420 <#>ifdef'ing out this code and adding the equivalent replacement routines
11421 to the ck?fio.c module, e.g. for RMS-based file i/o in ckvfio.c.
11425 /* 2010-03-09 SMS. VAX C needs help to find "sys". It's easier not to try. */
11427 #else /* def VMS */
11428 #include <sys/stat.h>
11429 #endif /* def VMS [else] */
11430 #endif /* NOSTAT */
11433 static int z_lt = 1; /* Length of line terminator */
11435 static int z_lt = 2;
11436 #endif /* NLCHAR */
11438 struct ckz_file { /* C-Kermit file struct */
11439 FILE * z_fp; /* Includes the C-Lib file struct */
11440 unsigned int z_flags; /* Plus C-Kermit mode flags, */
11441 CK_OFF_T z_nline; /* current line number if known, */
11442 char z_name[CKMAXPATH+2]; /* and the file's name. */
11444 static struct ckz_file ** z_file = NULL; /* Array of C-Kermit file structs */
11445 static int z_inited = 0; /* Flag for array initialized */
11446 int z_maxchan = Z_MAXCHAN; /* Max number of C-Kermit channels */
11447 int z_openmax = CKMAXOPEN; /* Max number of open files overall */
11448 int z_nopen = 0; /* How many channels presently open */
11449 int z_error = 0; /* Most recent error */
11450 int z_filcount = -1; /* Most recent FILE COUNT result */
11452 #define RD_LINE 0 /* FILE READ options */
11455 #define RD_TRIM 8 /* Like Snobol &TRIM = 1 */
11456 #define RD_UNTA 9 /* Untabify */
11458 #define WR_LINE RD_LINE /* FILE WRITE options */
11459 #define WR_CHAR RD_CHAR
11460 #define WR_SIZE RD_SIZE
11466 extern int ckmaxfiles; /* Filled in by sysinit(). */
11469 /* See ckcker.h for error numbers */
11470 /* See ckcdeb.h for Z_MAXCHAN and CKMAXOPEN definitions */
11471 /* NOTE: For VMS we might be able to fill in ckmaxfiles */
11472 /* from FILLM and CHANNELCNT -- find out about these... */
11474 static char * fopnargs[] = { /* Mode combinations for fopen() */
11476 /* All combinations of rwa */
11477 "", "r", "w", "rw", "a", "ra", "wa", "rwa", /* Text mode */
11478 "b", "rb", "wb", "rwb", "ab", "rab", "wab", "rwab" /* Binary mode */
11480 /* Combinations and syntax permitted by C libraries... */
11481 "", "r", "w", "r+", "a", "", "a", "", /* Text mode */
11483 "", "rb", "wb", "r+b", "ab", "", "ab", "" /* Binary modes for K95 */
11486 "", "rb", "wb", "r+b", "ab", "", "ab", "" /* Binary modes for VMS */
11488 "", "r", "w", "r+", "a", "", "a", "" /* Binary modes for UNIX */
11491 #endif /* COMMENT */
11493 static int nfopnargs = sizeof(fopnargs) / sizeof(char *);
11495 char * /* Error messages */
11496 ckferror(n) int n; {
11498 case FX_NER: return("No error");
11499 case FX_SYS: return(ck_errstr());
11500 case FX_EOF: return("End of file");
11501 case FX_NOP: return("File not open");
11502 case FX_CHN: return("Channel out of range");
11503 case FX_RNG: return("Parameter out of range");
11504 case FX_NMF: return("Too many files open");
11505 case FX_FOP: return("Operation conflicts with OPEN mode");
11506 case FX_NYI: return("OPEN mode not supported");
11507 case FX_BOM: return("Illegal combination of OPEN modes");
11508 case FX_ACC: return("Access denied");
11509 case FX_FNF: return("File not found");
11510 case FX_OFL: return("Buffer overflow");
11511 case FX_LNU: return("Current line number unknown");
11512 case FX_ROO: return("Off limits");
11513 case FX_UNK: return("Operation fails - reason unknown");
11514 default: return("Error number out of range");
11519 Z _ O P E N -- Open a file for the requested type of access.
11522 name: Name of file to be opened.
11523 flags: Any combination of FM_xxx values except FM_EOF (ckcker.h).
11525 >= 0 on success: The assigned channel number
11526 < 0 on failure: A negative FX_xxx error code (ckcker.h).
11529 z_open(name, flags) char * name; int flags; {
11533 debug(F111,"z_open",name,flags);
11534 if (!name) name = ""; /* Check name argument */
11536 return(z_error = FX_BFN);
11537 if (flags & FM_CMD) /* Opening pipes not implemented yet */
11538 return(z_error = FX_NYI); /* (and not portable either) */
11539 debug(F101,"z_open nfopnargs","",nfopnargs);
11540 if (flags < 0 || flags >= nfopnargs) /* Range check flags */
11541 return(z_error = FX_RNG);
11542 mode = fopnargs[flags]; /* Get fopen() arg */
11543 debug(F111,"z_open fopen args",mode,flags);
11544 if (!mode[0]) /* Check for illegal combinations */
11545 return(z_error = FX_BOM);
11546 if (!z_inited) { /* If file structs not inited */
11547 debug(F101,"z_open z_maxchan 1","",z_maxchan);
11549 debug(F101,"z_open ckmaxfiles","",ckmaxfiles);
11550 if (ckmaxfiles > 0) { /* Set in ck?tio.c: sysinit() */
11552 x = ckmaxfiles - ZNFILS - 5;
11553 if (x > z_maxchan) /* sysconf() value greater than */
11554 z_maxchan = x; /* value from header files. */
11555 debug(F101,"z_open z_maxchan 2","",z_maxchan);
11558 if (z_maxchan < Z_MINCHAN) /* Allocate at least this many. */
11559 z_maxchan = Z_MINCHAN;
11560 debug(F101,"z_open z_maxchan 3","",z_maxchan);
11561 /* Note: This could be a pretty big chunk of memory */
11562 /* if z_maxchan is a big number. If this becomes a problem */
11563 /* we'll need to malloc and free each element at open/close time */
11565 /* May 2006 - it's time - in current Linux this about 3MB */
11566 if (!(z_file = (struct ckz_file *)
11567 malloc(sizeof(struct ckz_file) * (z_maxchan + 1))))
11568 return(z_error = FX_NMF);
11569 for (i = 0; i < z_maxchan; i++) {
11570 z_file[i].z_fp = NULL;
11571 z_file[i].z_flags = 0;
11572 z_file[i].z_nline = 0;
11573 *(z_file[i].z_name) = '\0';
11576 /* New economical way, allocate storage for each channel as needed */
11578 z_file = (struct ckz_file **)malloc((z_maxchan + 1) *
11579 sizeof(struct ckz_file *));
11581 return(z_error = FX_NMF);
11582 for (i = 0; i < z_maxchan; i++)
11585 #endif /* COMMENT */
11586 z_inited = 1; /* Remember we initialized */
11588 for (n = -1, i = 0; i < z_maxchan; i++) { /* Find a free channel */
11590 if (!z_file[i].z_fp) {
11596 z_file[i] = (struct ckz_file *) malloc(sizeof(struct ckz_file));
11598 return(z_error = FX_NMF);
11602 #endif /* COMMENT */
11605 if (n < 0 || n >= z_maxchan) /* Any free channels? */
11606 return(z_error = FX_NMF); /* No, fail. */
11609 z_file[n]->z_flags = 0; /* In case of failure... */
11610 z_file[n]->z_fp = NULL; /* Set file pointer to NULL */
11612 t = fopen(name, mode); /* Try to open the file. */
11613 if (!t) { /* Failed... */
11614 debug(F111,"z_open error",name,errno);
11616 if (errno == EMFILE)
11617 return(z_error = FX_NMF);
11618 #endif /* EMFILE */
11621 return(z_error = (errno ? FX_SYS : FX_UNK)); /* Return error code */
11624 #ifdef O_SEQUENTIAL
11625 if (t) /* Caching hint for NT */
11626 _setmode(_fileno(t),O_SEQUENTIAL);
11627 #endif /* O_SEQUENTIAL */
11629 z_nopen++; /* Open, count it. */
11630 z_file[n]->z_fp = t; /* Stash the file pointer */
11631 z_file[n]->z_flags = flags; /* and the flags */
11632 z_file[n]->z_nline = 0; /* Current line number is 0 */
11634 zfnqfp(name,CKMAXPATH,z_file[n]->z_name); /* and the file's full name */
11635 return(n); /* Return the channel number */
11639 z_close(channel) int channel; { /* Close file on given channel */
11642 if (!z_inited) /* Called before any files are open? */
11643 return(z_error = FX_NOP);
11644 if (channel >= z_maxchan) /* Channel out of range? */
11645 return(z_error = FX_CHN);
11646 if (!z_file[channel])
11647 return(z_error = FX_NOP);
11648 if (!(t = z_file[channel]->z_fp)) /* Channel wasn't open? */
11649 return(z_error = FX_NOP);
11650 errno = 0; /* Set errno 0 to get a good reading */
11651 x = fclose(t); /* Try to close */
11652 if (x == EOF) /* On failure */
11653 return(z_error = FX_SYS); /* indicate system error. */
11654 z_nopen--; /* Closed OK, decrement open count */
11655 z_file[channel]->z_fp = NULL; /* Set file pointer to NULL */
11656 z_file[channel]->z_nline = 0; /* Current line number is 0 */
11657 z_file[channel]->z_flags = 0; /* Set flags to 0 */
11658 *(z_file[channel]->z_name) = '\0'; /* Clear name */
11659 free(z_file[channel]);
11660 z_file[channel] = NULL;
11661 return(z_error = 0);
11665 Z _ O U T -- Output string to channel.
11668 channel: Channel number to write to.
11669 s: String to write.
11670 length > -1: How many characters of s to write.
11671 length < 0: Write entire NUL-terminated string.
11672 flags == 0: Supply line termination.
11673 flags > 0: Don't supply line termination.
11674 flags < 0: Write 'length' NUL characters.
11676 If flags > -1 and s is empty or NULL and length == 1, write 1 NUL.
11678 Number of characters written to channel on success, or
11679 negative FX_xxx error code on failure.
11682 z_out(channel,s,length,flags) int channel, flags, length; char * s; {
11687 if (!s) s = ""; /* Guard against null pointer */
11690 debug(F111,"z_out",s,channel);
11691 debug(F101,"z_out length","",length);
11692 debug(F101,"z_out flags","",flags);
11695 if (!z_inited) /* File i/o inited? */
11696 return(z_error = FX_NOP);
11697 if (channel >= z_maxchan) /* Channel in range? */
11698 return(z_error = FX_CHN);
11699 if (!z_file[channel])
11700 return(z_error = FX_NOP);
11701 if (!(t = z_file[channel]->z_fp)) /* File open? */
11702 return(z_error = FX_NOP);
11703 if (!((z_file[channel]->z_flags) & (FM_WRI|FM_APP))) /* In write mode? */
11704 return(z_error = FX_FOP);
11705 n = length; /* Length of string to write */
11706 if (n < 0) { /* Negative means get it ourselves */
11707 if (flags < 0) /* Except when told to write NULs in */
11708 return(z_error = FX_RNG); /* which case args are inconsistent */
11709 n = strlen(s); /* Get length of string arg */
11711 errno = 0; /* Reset errno */
11712 debug(F101,"z_out n","",n);
11713 if (flags < 0) { /* Writing NULs... */
11715 for (i = 0; i < n; i++) {
11716 x = fwrite(&c,1,1,t);
11718 return(z_error = (errno ? FX_SYS : FX_UNK));
11720 z_file[channel]->z_nline = -1; /* Current line no longer known */
11723 } else { /* Writing string arg */
11724 if (n == 1 && !s[0]) /* Writing one char but it's NUL */
11725 x = fwrite(&c,1,1,t);
11726 else /* Writing non-NUL char or string */
11727 x = fwrite(s,1,n,t);
11728 debug(F101,"z_out fwrite",ckitoa(x),errno);
11729 if (x < n) /* Failure to write requested amount */
11730 return(z_error = (errno ? FX_SYS : FX_UNK)); /* Return error */
11731 if (flags == 0) { /* If supplying line termination */
11732 if (fwrite("\n",1,1,t)) /* do that */
11733 x += z_lt; /* count the terminator */
11734 if (z_file[channel]->z_nline > -1) /* count this line */
11735 z_file[channel]->z_nline++;
11737 z_file[channel]->z_nline = -1; /* Current line no longer known */
11744 #define Z_INBUFLEN 64
11747 Z _ I N -- Multichannel i/o file input function.
11750 channel number to read from.
11751 s = address of destination buffer.
11752 buflen = destination buffer length.
11753 length = Number of bytes to read, must be < buflen.
11754 flags: 0 = read a line; nonzero = read the given number of bytes.
11756 Number of bytes read into buffer or a negative error code.
11757 A terminating NUL is deposited after the last byte that was read.
11760 z_in(channel,s,buflen,length,flags)
11761 int channel, buflen, length, flags; char * s;
11767 if (!z_inited) /* Check everything... */
11768 return(z_error = FX_NOP);
11769 if (channel >= z_maxchan)
11770 return(z_error = FX_CHN);
11771 if (!z_file[channel])
11772 return(z_error = FX_NOP);
11773 if (!(t = z_file[channel]->z_fp))
11774 return(z_error = FX_NOP);
11775 if (!((z_file[channel]->z_flags) & FM_REA))
11776 return(z_error = FX_FOP);
11777 if (!s) /* Check destination */
11778 return(z_error = FX_RNG);
11780 if (length == 0) /* Read 0 bytes - easy. */
11781 return(z_error = 0);
11782 debug(F101,"z_in channel","",channel);
11783 debug(F101,"z_in buflen","",buflen);
11784 debug(F101,"z_in length","",length);
11785 debug(F101,"z_in flags","",flags);
11786 if (length < 0 || buflen < 0) /* Check length args */
11787 return(z_error = FX_RNG);
11788 if (buflen <= length)
11789 return(z_error = FX_RNG);
11790 errno = 0; /* Reset errno */
11791 if (flags) { /* Read block or byte */
11792 int n; /* 20050912 */
11793 n = length; /* 20050912 */
11794 i = 0; /* 20050912 */
11795 while (n > 0) { /* 20050912 */
11796 i = fread(s,1,n,t); /* 20050912 */
11799 debug(F111,"z_in block",s,i);
11800 debug(F101,"z_in block errno","",errno);
11801 debug(F101,"z_in block ferror","",ferror(t));
11802 debug(F101,"z_in block feof","",feof(t));
11805 if (i == 0) break; /* 20050912 */
11806 s += i; /* 20050912 */
11807 n -= i; /* 20050912 */
11809 /* Current line no longer known */
11810 z_file[channel]->z_nline = (CK_OFF_T)-1;
11811 } else { /* Read line */
11813 /* This method is used because it's simpler than the others */
11814 /* and also marginally faster. */
11815 debug(F101,"z_in getc loop","",CKFTELL(t));
11816 for (i = 0; i < length; i++) {
11817 if ((x = getc(t)) == EOF) {
11818 debug(F101,"z_in getc error","",CKFTELL(t));
11823 if (s[i] == '\n') {
11828 debug(F111,"z_in line byte loop",ckitoa(errno),i);
11829 debug(F111,"z_in line got",s,z_file[channel]->z_nline);
11830 if (z_file[channel]->z_nline > -1)
11831 z_file[channel]->z_nline++;
11834 /* Straightforward but strlen() slows it down. */
11837 if (fgets(s,length,t)) {
11839 if (i > 0 && s[i-1] == '\n') i--;
11841 debug(F111,"z_in line fgets",ckitoa(errno),i);
11842 if (z_file[channel]->z_nline > -1)
11843 z_file[channel]->z_nline++;
11845 /* This is a do-it-yourself fgets() with its own readahead and */
11846 /* putback. It's a bit faster than real fgets() but not enough */
11847 /* to justify the added complexity or the risk of the ftell() and */
11848 /* fseek() calls failing. */
11851 for (i = 0; !flag && i <= (length - Z_INBUFLEN); i += Z_INBUFLEN) {
11852 k = ((length - i) < Z_INBUFLEN) ? length - i : Z_INBUFLEN;
11853 if ((x = fread(s+i,1,k,t)) < 1)
11856 for (j = 0; j < x; j++) {
11857 if (s[i+j] == '\n') {
11862 pos -= (x - j - 1);
11863 x = CKFSEEK(t, pos, 0);
11867 return(z_error = FX_SYS);
11871 if (z_file[channel]->z_nline > -1)
11872 z_file[channel]->z_nline++;
11873 debug(F111,"z_in line chunk loop",ckitoa(errno),i);
11874 #endif /* COMMENT2 */
11875 #endif /* COMMENT */
11877 debug(F111,"z_in i",ckitoa(errno),i);
11878 if (i < 0) i = 0; /* NUL-terminate result */
11884 if (i == 0 && feof(t)) /* EOF on reading? */
11885 return(z_error = FX_EOF); /* Return EOF code */
11886 return(errno ? (z_error = -1) : i); /* Return length or system error */
11890 z_flush(channel) int channel; { /* Flush output channel */
11893 if (!z_inited) /* Regular checks */
11894 return(z_error = FX_NOP);
11895 if (channel >= z_maxchan)
11896 return(z_error = FX_CHN);
11897 if (!z_file[channel])
11898 return(z_error = FX_NOP);
11899 if (!(t = z_file[channel]->z_fp))
11900 return(z_error = FX_NOP);
11901 if (!((z_file[channel]->z_flags) & (FM_WRI|FM_APP))) /* Write access? */
11902 return(z_error = FX_FOP);
11903 errno = 0; /* Reset errno */
11904 x = fflush(t); /* Try to flush */
11905 return(x ? (z_error = FX_SYS) : 0); /* Return system error or 0 if OK */
11910 z_seek(int channel, CK_OFF_T pos) /* Move file pointer to byte */
11912 z_seek(channel,pos) int channel; CK_OFF_T pos; /* (seek to given position) */
11913 #endif /* CK_ANSIC */
11917 if (!z_inited) /* Check... */
11918 return(z_error = FX_NOP);
11919 if (channel >= z_maxchan)
11920 return(z_error = FX_CHN);
11921 if (!z_file[channel])
11922 return(z_error = FX_NOP);
11923 if (!(t = z_file[channel]->z_fp))
11924 return(z_error = FX_NOP);
11927 pos = (pos == -2) ? -1L : 0L;
11930 rc = CKFSEEK(t,pos,x); /* Try to seek */
11931 debug(F111,"z_seek",ckitoa(errno),rc);
11932 if (rc < 0) /* OK? */
11933 return(z_error = FX_SYS); /* No. */
11934 z_file[channel]->z_nline = ((pos || x) ? -1 : 0);
11935 return(z_error = 0);
11940 z_line(int channel, CK_OFF_T pos) /* Move file pointer to line */
11942 z_line(channel,pos) int channel; CK_OFF_T pos; /* (seek to given position) */
11943 #endif /* CK_ANSIC */
11946 CK_OFF_T current = (CK_OFF_T)0, prev = (CK_OFF_T)-1, old = (CK_OFF_T)-1;
11949 if (!z_inited) /* Check... */
11950 return(z_error = FX_NOP);
11951 if (channel >= z_maxchan)
11952 return(z_error = FX_CHN);
11953 if (!z_file[channel])
11954 return(z_error = FX_NOP);
11955 if (!(t = z_file[channel]->z_fp))
11956 return(z_error = FX_NOP);
11957 debug(F101,"z_line pos","",pos);
11958 if (pos < 0L) { /* EOF wanted */
11960 n = z_file[channel]->z_nline;
11961 debug(F101,"z_line n","",n);
11962 if (n < 0 || pos < 0) {
11966 while (1) { /* This could take a while... */
11967 if ((x = getc(t)) == EOF)
11977 debug(F101,"z_line old","",old);
11978 debug(F101,"z_line prev","",prev);
11980 if ((x = z_seek(channel,old)) < 0)
11981 return(z_error = x);
11985 z_file[channel]->z_nline = n;
11986 return(z_error = 0);
11988 if (pos == 0L) { /* Rewind wanted */
11989 z_file[channel]->z_nline = 0L;
11991 debug(F100,"z_line rewind","",0);
11994 tmpbuf[255] = NUL; /* Make sure buf is NUL terminated */
11995 current = z_file[channel]->z_nline; /* Current line */
11997 If necessary the following could be optimized, e.g. for positioning
11998 to a previous line in a large file without starting over.
12000 if (current < 0 || pos < current) { /* Not known or behind us... */
12001 debug(F101,"z_line rewinding","",pos);
12002 if ((x = z_seek(channel, 0L)) < 0) /* Rewind */
12003 return(z_error = x);
12004 if (pos == 0) /* If 0th line wanted we're done */
12005 return(z_error = 0);
12008 while (current < pos) { /* Search for specified line */
12009 if (fgets(tmpbuf,255,t)) {
12010 len = strlen(tmpbuf);
12011 if (len > 0 && tmpbuf[len-1] == '\n') {
12013 debug(F111,"z_line read",ckitoa(len),current);
12014 } else if (len == 0) {
12015 return(z_error = FX_UNK);
12018 z_file[channel]->z_nline = -1L;
12019 debug(F101,"z_line premature EOF","",current);
12020 return(z_error = FX_EOF);
12023 z_file[channel]->z_nline = current;
12024 debug(F101,"z_line result","",current);
12030 z_getname(channel) int channel; { /* Return name of file on channel */
12036 if (channel >= z_maxchan) {
12040 if (!z_file[channel]) {
12044 if (!(t = z_file[channel]->z_fp)) {
12048 return((char *)(z_file[channel]->z_name));
12052 z_getmode(channel) int channel; { /* Return OPEN modes of channel */
12053 FILE * t; /* 0 if file not open */
12056 struct _stat statbuf;
12058 struct stat statbuf;
12060 #endif /* NOSTAT */
12064 if (channel >= z_maxchan)
12065 return(z_error = FX_CHN);
12066 if (!z_file[channel])
12068 if (!(t = z_file[channel]->z_fp))
12070 x = z_file[channel]->z_flags;
12071 if (feof(t)) { /* This might not work for */
12072 x |= FM_EOF; /* output files */
12074 /* But this does if we can use it. */
12075 } else if (stat(z_file[channel]->z_name,&statbuf) > -1) {
12076 if (CKFTELL(t) == statbuf.st_size)
12078 #endif /* NOSTAT */
12084 z_getpos(channel) int channel; { /* Get file pointer position */
12085 FILE * t; /* on this channel */
12088 return(z_error = FX_NOP);
12089 if (channel >= z_maxchan)
12090 return(z_error = FX_CHN);
12091 if (!z_file[channel])
12092 return(z_error = FX_NOP);
12093 if (!(t = z_file[channel]->z_fp))
12094 return(z_error = FX_NOP);
12096 return((x < 0L) ? (z_error = FX_SYS) : x);
12100 z_getline(channel) int channel; { /* Get current line number */
12101 FILE * t; /* in file on this channel */
12104 return(z_error = FX_NOP);
12105 if (channel >= z_maxchan)
12106 return(z_error = FX_CHN);
12107 if (!z_file[channel])
12108 return(z_error = FX_NOP);
12109 if (!(t = z_file[channel]->z_fp))
12110 return(z_error = FX_NOP);
12111 debug(F101,"z_getline","",z_file[channel]->z_nline);
12112 rc = z_file[channel]->z_nline;
12113 return((rc < 0) ? (z_error = FX_LNU) : rc);
12117 z_getfnum(channel) int channel; { /* Get file number / handle */
12118 FILE * t; /* for file on this channel */
12120 return(z_error = FX_NOP);
12121 if (channel >= z_maxchan)
12122 return(z_error = FX_CHN);
12123 if (!z_file[channel])
12124 return(z_error = FX_NOP);
12125 if (!(t = z_file[channel]->z_fp))
12126 return(z_error = FX_NOP);
12132 Line-oriented counts and seeks are as dumb as they can be at the moment.
12133 Later we can speed them up by building little indexes.
12136 z_count(channel, what) int channel, what; { /* Count bytes or lines in file */
12139 CK_OFF_T pos, count = (CK_OFF_T)0;
12140 if (!z_inited) /* Check stuff... */
12141 return(z_error = FX_NOP);
12142 if (channel >= z_maxchan)
12143 return(z_error = FX_CHN);
12144 if (!z_file[channel])
12145 return(z_error = FX_NOP);
12146 if (!(t = z_file[channel]->z_fp))
12147 return(z_error = FX_NOP);
12148 pos = CKFTELL(t); /* Save current file pointer */
12151 if (what == RD_CHAR) { /* Size in bytes requested */
12153 if (!CKFSEEK(t,0L,2)) { /* Seek to end */
12154 count = CKFTELL(t); /* Get file pointer */
12155 CKFSEEK(t,pos,0); /* Restore file file pointer */
12157 } else /* Fallback in case seek fails */
12158 #endif /* COMMENT */
12159 return(zgetfs(z_file[channel]->z_name));
12161 rewind(t); /* Line count requested - rewind. */
12162 while (1) { /* Count lines. */
12163 if ((x = getc(t)) == EOF) /* Stupid byte loop */
12164 break; /* but it works as well as anything */
12165 if (x == '\n') /* else... */
12168 x = CKFSEEK(t,pos,0); /* Restore file pointer */
12172 /* User interface for generalized channel-oriented file i/o */
12174 struct keytab fctab[] = { /* FILE subcommands */
12175 { "close", FIL_CLS, 0 },
12176 { "count", FIL_COU, 0 },
12177 { "flush", FIL_FLU, 0 },
12178 { "list", FIL_LIS, 0 },
12179 { "open", FIL_OPN, 0 },
12180 { "read", FIL_REA, 0 },
12181 { "rewind", FIL_REW, 0 },
12182 { "seek", FIL_SEE, 0 },
12183 { "status", FIL_STA, 0 },
12184 { "write", FIL_WRI, 0 }
12186 int nfctab = (sizeof (fctab) / sizeof (struct keytab));
12188 static struct keytab fcswtab[] = { /* OPEN modes */
12189 { "/append", FM_APP, 0 },
12190 { "/binary", FM_BIN, 0 },
12192 { "/command", FM_CMD, 0 }, /* Not implemented */
12193 #endif /* COMMENT */
12194 { "/read", FM_REA, 0 },
12195 { "/write", FM_WRI, 0 }
12197 static int nfcswtab = (sizeof (fcswtab) / sizeof (struct keytab));
12199 static struct keytab fclkwtab[] = { /* CLOSE options */
12203 static struct keytab fsekwtab[] = { /* SEEK symbols */
12207 static int nfsekwtab = (sizeof (fsekwtab) / sizeof (struct keytab));
12209 #define SEE_LINE RD_LINE /* SEEK options */
12210 #define SEE_CHAR RD_CHAR
12215 static struct keytab fskswtab[] = {
12216 { "/absolute", SEE_ABS, 0 },
12217 { "/byte", SEE_CHAR, 0 },
12218 { "/character", SEE_CHAR, CM_INV },
12219 { "/find", SEE_FIND, CM_ARG },
12220 { "/line", SEE_LINE, 0 },
12221 { "/relative", SEE_REL, 0 }
12223 static int nfskswtab = (sizeof (fskswtab) / sizeof (struct keytab));
12225 #define COU_LINE RD_LINE /* COUNT options */
12226 #define COU_CHAR RD_CHAR
12230 static struct keytab fcoswtab[] = {
12231 { "/bytes", COU_CHAR, 0 },
12232 { "/characters",COU_CHAR, CM_INV },
12233 { "/lines", COU_LINE, 0 },
12234 { "/list", COU_LIS, 0 },
12235 { "/nolist", COU_NOL, 0 },
12236 { "/quiet", COU_NOL, CM_INV }
12238 static int nfcoswtab = (sizeof (fcoswtab) / sizeof (struct keytab));
12240 static struct keytab frdtab[] = { /* READ types */
12241 { "/block", RD_SIZE, CM_INV|CM_ARG },
12242 { "/byte", RD_CHAR, CM_INV },
12243 { "/character", RD_CHAR, 0 },
12244 { "/line", RD_LINE, 0 },
12245 { "/size", RD_SIZE, CM_ARG },
12246 { "/trim", RD_TRIM, 0 },
12247 { "/untabify", RD_UNTA, 0 }
12249 static int nfrdtab = (sizeof (frdtab) / sizeof (struct keytab));
12251 static struct keytab fwrtab[] = { /* WRITE types */
12252 { "/block", WR_SIZE, CM_INV|CM_ARG },
12253 { "/byte", WR_CHAR, CM_INV },
12254 { "/character", WR_CHAR, 0 },
12255 { "/line", WR_LINE, 0 },
12256 { "/lpad", WR_LPAD, CM_ARG },
12257 { "/rpad", WR_RPAD, CM_ARG },
12258 { "/size", WR_SIZE, CM_ARG },
12259 { "/string", WR_STRI, 0 }
12261 static int nfwrtab = (sizeof (fwrtab) / sizeof (struct keytab));
12263 static char blanks[] = "\040\040\040\040"; /* Some blanks for formatting */
12264 static char * seek_target = NULL;
12267 dofile(op) int op; { /* Do the FILE command */
12268 char vnambuf[VNAML]; /* Buffer for variable names */
12269 char *vnp = NULL; /* Pointer to same */
12270 char zfilnam[CKMAXPATH+2];
12272 struct FDB fl, sw, nu;
12274 int rsize, filmode = 0, relative = -1, eofflg = 0;
12275 int rc, x, y, cx, n, getval, dummy, confirmed, listing = -1;
12276 int charflag = 0, sizeflag = 0;
12277 int pad = 32, wr_lpad = 0, wr_rpad = 0, rd_trim = 0, rd_untab = 0;
12279 makestr(&seek_target,NULL);
12281 if (op == XXFILE) { /* FILE command was given */
12282 /* Get subcommand */
12283 if ((cx = cmkey(fctab,nfctab,"Operation","",xxstring)) < 0) {
12285 printf("?File operation required\n");
12290 } else { /* Shorthand command was given */
12292 case XXF_CL: cx = FIL_CLS; break; /* FCLOSE */
12293 case XXF_FL: cx = FIL_FLU; break; /* FFLUSH */
12294 case XXF_LI: cx = FIL_LIS; break; /* FLIST */
12295 case XXF_OP: cx = FIL_OPN; break; /* etc... */
12296 case XXF_RE: cx = FIL_REA; break;
12297 case XXF_RW: cx = FIL_REW; break;
12298 case XXF_SE: cx = FIL_SEE; break;
12299 case XXF_ST: cx = FIL_STA; break;
12300 case XXF_WR: cx = FIL_WRI; break;
12301 case XXF_CO: cx = FIL_COU; break;
12302 default: return(-2);
12305 switch (cx) { /* Do requested subcommand */
12306 case FIL_OPN: /* OPEN */
12307 cmfdbi(&sw, /* Switches */
12308 _CMKEY, /* fcode */
12309 "Variable or switch", /* hlpmsg */
12311 "", /* addtl string data */
12312 nfcswtab, /* addtl numeric data 1: tbl size */
12313 4, /* addtl numeric data 2: 4 = cmswi */
12314 xxstring, /* Processing function */
12315 fcswtab, /* Keyword table */
12316 &fl /* Pointer to next FDB */
12318 cmfdbi(&fl, /* Anything that doesn't match */
12319 _CMFLD, /* fcode */
12320 "Variable", /* hlpmsg */
12330 x = cmfdb(&sw); /* Parse something */
12333 printf("?Variable name and file name required\n");
12338 if (cmresult.fcode == _CMFLD)
12340 else if (cmresult.fcode == _CMKEY) {
12344 (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
12345 printf("?This switch does not take an argument\n");
12349 /* Uncomment if we add any switches here that take args */
12350 if (!getval && (cmgkwflgs() & CM_ARG)) {
12351 printf("?This switch requires an argument\n");
12352 return(-9); /* (none do...) */
12354 #endif /* COMMENT */
12355 filmode |= cmresult.nresult; /* OR in the file mode */
12359 /* Not a switch - get the string */
12360 ckstrncpy(vnambuf,cmresult.sresult,VNAML);
12361 if (!vnambuf[0] || chknum(vnambuf)) { /* (if there is one...) */
12362 printf("?Variable name required\n");
12365 vnp = vnambuf; /* Check variable-name syntax */
12366 if (vnambuf[0] == CMDQ &&
12367 (vnambuf[1] == '%' || vnambuf[1] == '&'))
12370 if (*vnp == '%' || *vnp == '&') {
12371 if ((y = parsevar(vnp,&x,&dummy)) < 0) {
12372 printf("?Syntax error in variable name\n");
12376 /* Assign a negative channel number in case we fail */
12377 addmac(vnambuf,"-1");
12379 if (!(filmode & FM_RWA)) /* If no access mode specified */
12380 filmode |= FM_REA; /* default to /READ. */
12382 y = 0; /* Now parse the filename */
12383 if ((filmode & FM_RWA) == FM_WRI) {
12384 x = cmofi("Name of new file","",&s,xxstring);
12385 } else if ((filmode & FM_RWA) == FM_REA) {
12386 x = cmifi("Name of existing file","",&s,&y,xxstring);
12388 x = cmiofi("Filename","",&s,&y,xxstring);
12389 debug(F111,"fopen /append x",s,x);
12393 printf("?Filename required\n");
12398 if (y) { /* No wildcards */
12399 printf("?Wildcards not allowed here\n");
12402 if (filmode & (FM_APP|FM_WRI)) { /* Check output access */
12404 if (zchko(s) < 0) { /* and set error code if denied */
12406 printf("?Write access denied - \"%s\"\n",s);
12411 ckstrncpy(zfilnam,s,CKMAXPATH); /* Is OK - make safe copy */
12412 if ((x = cmcfm()) < 0) /* Get confirmation of command */
12414 if ((n = z_open(zfilnam,filmode)) < 0) {
12415 printf("?OPEN failed - %s: %s\n",zfilnam,ckferror(n));
12418 addmac(vnambuf,ckitoa(n)); /* Assign channel number to variable */
12419 return(success = 1);
12421 case FIL_REW: /* REWIND */
12422 if ((x = cmnum("Channel number","",10,&n, xxstring)) < 0) {
12424 printf("?Channel number required\n");
12429 if ((x = cmcfm()) < 0)
12431 if (n == -9) return(success = 0);
12432 if (n == -8) return(success = 1);
12434 if ((rc = z_seek(n,0L)) < 0) {
12435 printf("?REWIND failed - Channel %d: %s\n",n,ckferror(rc));
12438 return(success = 1);
12440 case FIL_CLS: /* CLOSE */
12441 #ifdef COMMENT /* fdc 20100804 - bad idea */
12443 int i, j, k; /* Supply default if only one open */
12445 for (k = 0, j = 0, i = 0; i < z_maxchan; i++) {
12448 if (z_file[i]->z_fp) { k++; j = i; }
12450 if (k == 1) s = ckitoa(j);
12452 #endif /* COMMENT */
12453 cmfdbi(&nu, /* Second FDB - channel number */
12454 _CMNUM, /* fcode */
12455 "Channel number or ALL", /* Help message */
12457 "", /* addtl string data */
12458 10, /* addtl numeric data 1: radix */
12459 0, /* addtl numeric data 2: 0 */
12460 xxstring, /* Processing function */
12461 NULL, /* Keyword table */
12462 &sw /* Pointer to next FDB */
12463 ); /* Pointer to next FDB */
12464 cmfdbi(&sw, /* First FDB - command switches */
12465 _CMKEY, /* fcode */
12466 "", /* help message */
12468 "", /* No addtl string data */
12469 1, /* addtl numeric data 1: tbl size */
12470 0, /* addtl numeric data 2: 4 = cmswi */
12471 xxstring, /* Processing function */
12472 fclkwtab, /* Keyword table */
12473 NULL /* Last in chain */
12475 x = cmfdb(&nu); /* Parse something */
12478 printf("?Channel number or ALL required\n");
12483 if (cmresult.fcode == _CMNUM)
12484 n = cmresult.nresult;
12485 else if (cmresult.fcode == _CMKEY)
12487 if ((x = cmcfm()) < 0)
12489 if (n == -9) return(success = 0);
12490 if (n == -8) return(success = 1);
12496 for (i = 0; i < z_maxchan; i++) {
12499 printf("?CLOSE failed - Channel %d: %s\n",n,ckferror(x));
12504 debug(F101,"FILE CLOSE ALL","",count);
12505 } else if ((x = z_close(n)) < 0) {
12506 printf("?CLOSE failed - Channel %d: %s\n",n,ckferror(x));
12509 return(success = rc);
12511 case FIL_REA: /* READ */
12512 case FIL_WRI: /* WRITE */
12514 cmfdbi(&sw, /* Switches */
12515 _CMKEY, /* fcode */
12516 "Channel or switch", /* hlpmsg */
12518 "", /* addtl string data */
12519 (cx == FIL_REA) ? nfrdtab : nfwrtab,
12520 4, /* addtl numeric data 2: 4 = cmswi */
12521 xxstring, /* Processing function */
12522 (cx == FIL_REA) ? frdtab : fwrtab, /* Keyword table */
12523 &nu /* Pointer to next FDB */
12525 cmfdbi(&nu, /* Channel number */
12526 _CMNUM, /* fcode */
12529 "", /* addtl string data */
12530 10, /* addtl numeric data 1: radix */
12531 0, /* addtl numeric data 2: 0 */
12532 xxstring, /* Processing function */
12533 NULL, /* Keyword table */
12534 NULL /* Pointer to next FDB */
12537 x = cmfdb(&sw); /* Parse something */
12540 printf("?Channel number required\n");
12545 if (cmresult.fcode == _CMNUM) /* Channel number */
12547 else if (cmresult.fcode == _CMKEY) { /* Switch */
12551 (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
12552 printf("?This switch does not take an argument\n");
12555 if (!getval && (cmgkwflgs() & CM_ARG)) {
12556 printf("?This switch requires an argument\n");
12559 switch (cmresult.nresult) {
12571 if ((x = cmnum("Bytes","",10,&rsize, xxstring)) < 0) {
12573 printf("?Number required\n");
12578 if (rsize > LINBUFSIZ) {
12579 printf("?Maximum FREAD/FWRITE size is %d\n",LINBUFSIZ);
12593 if ((x = cmnum("Numeric ASCII character value",
12594 "32",10,&pad, xxstring)) < 0)
12596 if (cmresult.nresult == WR_LPAD)
12608 debug(F101,"FILE READ rsize 2","",rsize);
12612 (cmresult.fcode == _CMKEY);
12614 n = cmresult.nresult; /* Channel */
12615 debug(F101,"FILE READ/WRITE channel","",n);
12617 if (cx == FIL_WRI) { /* WRITE */
12619 if ((x = cmtxt("Text","",&s,xxstring)) < 0)
12621 if (n == -9) return(success = 0);
12622 if (n == -8) return(success = 1);
12624 ckstrncpy(line,s,LINBUFSIZ); /* Make a safe copy */
12626 s = brstrip(s); /* Strip braces */
12627 if (charflag) { /* Write one char */
12628 len = 1; /* So length = 1 */
12629 rsize = 1; /* Don't supply terminator */
12630 } else if (!sizeflag) { /* Write a string */
12631 len = -1; /* So length is unspecified */
12632 } else { /* Write a block of given size */
12634 if (rsize > TMPBUFSIZ) {
12636 printf("?Buffer overflow\n");
12639 len = rsize; /* rsize is really length */
12640 rsize = 1; /* Don't supply a terminator */
12641 xx = strlen(s); /* Size of given string */
12642 if (xx >= len) { /* Bigger or equal */
12644 } else if (wr_lpad) { /* Smaller, left-padding requested */
12645 for (i = 0; i < len - xx; i++) /* Must make a copy */
12647 ckstrncpy(tmpbuf+i,s,TMPBUFSIZ-i);
12649 s = tmpbuf; /* Redirect write source */
12650 } else if (wr_rpad) { /* Smaller with right-padding */
12651 for (i = xx; i < len; i++)
12656 if ((rc = z_out(n,s,len,rsize)) < 0) { /* Try to write */
12657 printf("?Channel %d WRITE error: %s\n",n,ckferror(rc));
12660 } else { /* FIL_REA READ */
12663 x = cmfld("Variable name","",&s,NULL);
12664 debug(F111,"FILE READ cmfld",s,x);
12666 if (x == -3 || !*s) {
12667 if ((x = cmcfm()) < 0)
12674 ckstrncpy(vnambuf,s,VNAML);
12675 debug(F111,"FILE READ vnambuf",vnambuf,confirmed);
12676 if (vnambuf[0]) { /* Variable name given, check it */
12685 if (vnambuf[0] == CMDQ &&
12686 (vnambuf[1] == '%' || vnambuf[1] == '&'))
12689 if (*vnp == '%' || *vnp == '&') {
12690 if ((y = parsevar(vnp,&x,&dummy)) < 0) {
12691 printf("?Syntax error in variable name\n");
12696 debug(F111,"FILE READ variable",vnambuf,confirmed);
12699 if ((x = cmcfm()) < 0)
12702 if (n == -9) return(success = 0);
12703 if (n == -8) return(success = 1);
12705 line[0] = NUL; /* Clear destination buffer */
12707 if (rsize >= LINBUFSIZ) /* Don't overrun it */
12708 rsize = LINBUFSIZ - 1;
12709 #endif /* COMMENT */
12711 if (rsize == 0) { /* Read a line */
12712 rc = z_in(n,line,LINBUFSIZ,LINBUFSIZ-1,0);
12714 rc = z_in(n,line,LINBUFSIZ,rsize,1); /* Read a block */
12716 if (rc < 0) { /* Error... */
12717 debug(F101,"FILE READ error","",rc);
12718 debug(F101,"FILE READ errno","",errno);
12719 if (rc == FX_EOF) { /* EOF - fail but no error message */
12720 return(success = 0);
12721 } else { /* Other error - fail and print msg */
12722 printf("?READ error: %s\n",ckferror(rc));
12726 if (rsize == 0) { /* FREAD /LINE postprocessing */
12727 if (rd_trim) { /* Trim */
12731 for (i = k-1; i > 0; i--) {
12732 if (line[i] == SP || line[i] == '\t')
12739 if (rd_untab) { /* Untabify */
12740 if (untabify(line,tmpbuf,TMPBUFSIZ) > -1)
12741 ckstrncpy(line,tmpbuf,LINBUFSIZ);
12744 debug(F110,"FILE READ data",line,0);
12745 if (vnambuf[0]) /* Read OK - If variable name given */
12746 addmac(vnambuf,line); /* Assign result to variable */
12747 else /* otherwise */
12748 printf("%s\n",line); /* just print it */
12750 return(success = 1);
12752 case FIL_SEE: /* SEEK */
12753 case FIL_COU: /* COUNT */
12754 rsize = RD_CHAR; /* Defaults to /BYTE */
12755 cmfdbi(&sw, /* Switches */
12756 _CMKEY, /* fcode */
12757 "Channel or switch", /* hlpmsg */
12759 "", /* addtl string data */
12760 ((cx == FIL_SEE) ? nfskswtab : nfcoswtab),
12761 4, /* addtl numeric data 2: 4 = cmswi */
12762 xxstring, /* Processing function */
12763 ((cx == FIL_SEE) ? fskswtab : fcoswtab),
12764 &nu /* Pointer to next FDB */
12766 cmfdbi(&nu, /* Channel number */
12767 _CMNUM, /* fcode */
12770 "", /* addtl string data */
12771 10, /* addtl numeric data 1: radix */
12772 0, /* addtl numeric data 2: 0 */
12773 xxstring, /* Processing function */
12774 NULL, /* Keyword table */
12775 NULL /* Pointer to next FDB */
12778 x = cmfdb(&sw); /* Parse something */
12781 printf("?Channel number required\n");
12786 if (cmresult.fcode == _CMNUM) /* Channel number */
12788 else if (cmresult.fcode == _CMKEY) { /* Switch */
12792 (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
12793 printf("?This switch does not take an argument\n");
12796 if (cx == FIL_SEE) {
12797 switch (cmresult.nresult) {
12798 case SEE_REL: relative = 1; break;
12799 case SEE_ABS: relative = 0; break;
12802 y = cmfld("string or pattern","",&s,xxstring);
12805 makestr(&seek_target,brstrip(s));
12809 default: rsize = cmresult.nresult;
12811 } else if (cx == FIL_COU) {
12812 switch (cmresult.nresult) {
12813 case COU_LIS: listing = 1; break;
12814 case COU_NOL: listing = 0; break;
12815 default: rsize = cmresult.nresult;
12820 (cmresult.fcode == _CMKEY);
12822 n = cmresult.nresult; /* Channel */
12823 debug(F101,"FILE SEEK/COUNT channel","",n);
12824 if (cx == FIL_COU) {
12825 if ((x = cmcfm()) < 0)
12827 if (n == -9) return(success = 0);
12828 if (n == -8) return(success = 1);
12830 z_filcount = z_count(n,rsize);
12831 if (z_filcount < 0) {
12833 printf("?COUNT error: %s\n",ckferror(rc));
12837 listing = !xcmdsrc;
12839 printf(" %ld %s%s\n",
12841 ((rsize == RD_CHAR) ? "byte" : "line"),
12842 ((z_filcount == 1L) ? "" : "s")
12844 return(success = (z_filcount > -1) ? 1 : 0);
12846 m = (rsize == RD_CHAR) ?
12847 "Number of bytes;\n or keyword" :
12848 "Number of lines;\n or keyword";
12849 cmfdbi(&sw, /* SEEK symbolic targets (EOF) */
12850 _CMKEY, /* fcode */
12853 "", /* addtl string data */
12854 nfsekwtab, /* addtl numeric data 1: table size */
12855 0, /* addtl numeric data 2: 4 = cmswi */
12856 xxstring, /* Processing function */
12857 fsekwtab, /* Keyword table */
12858 &nu /* Pointer to next FDB */
12860 cmfdbi(&nu, /* Byte or line number */
12861 _CMNUW, /* fcode */
12864 "", /* addtl string data */
12865 10, /* addtl numeric data 1: radix */
12866 0, /* addtl numeric data 2: 0 */
12867 xxstring, /* Processing function */
12868 NULL, /* Keyword table */
12869 NULL /* Pointer to next FDB */
12871 x = cmfdb(&sw); /* Parse something */
12874 printf("?Channel number or EOF required\n");
12879 if (cmresult.fcode == _CMNUW) {
12880 z = cmresult.wresult;
12881 debug(F110,"FILE SEEK atmbuf",atmbuf,0);
12882 if (relative < 0) {
12883 if (cx == FIL_SEE && (atmbuf[0] == '+' || atmbuf[0] == '-'))
12888 } else if (cmresult.fcode == _CMKEY) {
12889 eofflg = cmresult.nresult;
12893 if ((x = cmcfm()) < 0)
12895 if (n == -9) return(success = 0);
12896 if (n == -8) return(success = 1);
12897 y = 1; /* Recycle this */
12899 debug(F101,"FILE SEEK relative","",relative);
12900 debug(F101,"FILE SEEK rsize","",rsize);
12902 if (rsize == RD_CHAR) { /* Seek to byte position */
12903 if (relative > 0) {
12906 if (pos < (CK_OFF_T)0) {
12908 printf("?Relative SEEK failed: %s\n",ckferror(rc));
12913 if (z < 0 && !eofflg) { /* Negative arg but not relative */
12914 y = 0; /* Remember this was bad */
12915 z = 0; /* but substitute 0 */
12918 debug(F101,"FILE SEEK /CHAR z","",z);
12919 if (z < 0 && !eofflg) {
12921 return(success = 0);
12923 if ((rc = z_seek(n,z)) < 0) {
12924 if (rc == FX_EOF) return(success = 0);
12925 printf("?SEEK /BYTE failed - Channel %d: %s\n",n,ckferror(rc));
12928 } else { /* Seek to line */
12929 if (relative > 0) {
12931 pos = z_getline(n);
12932 debug(F101,"FILE SEEK /LINE pos","",pos);
12935 printf("?Relative SEEK failed: %s\n",ckferror(rc));
12940 debug(F101,"FILE SEEK /LINE z","",z);
12941 debug(F101,"FILE SEEK /LINE eofflg","",eofflg);
12942 if (z < 0 && !eofflg) {
12944 return(success = 0);
12946 if ((rc = z_line(n,z)) < 0) {
12947 if (rc == FX_EOF) return(success = 0);
12948 printf("?SEEK /LINE failed - Channel %d: %s\n",n,ckferror(rc));
12953 Now, having sought to the desired starting spot, if a /FIND:
12954 target was specified, look for it now.
12957 int flag = 0, ispat = 0, matchresult = 0;
12959 y = z_in(n,line,LINBUFSIZ,LINBUFSIZ-1,0);
12964 if (ispattern(seek_target)) {
12965 matchresult = ckmatch(seek_target,line,inpcas[cmdlvl],1+4);
12967 /* This is faster */
12968 matchresult = ckindex(seek_target,line,0,0,inpcas[cmdlvl]);
12976 debug(F111,"FSEEK HAVE MATCH",seek_target,z_getline(n));
12977 /* Back up to beginning of line where target found */
12978 if ((y = z_line(n,z_getline(n)-1)) < 0) {
12979 if (rc == FX_EOF) return(success = 0);
12980 printf("?SEEK /LINE failed - Channel %d: %s\n",
12984 debug(F101,"FSEEK LINE","",y);
12987 return(success = (y < 0) ? 0 : 1);
12989 case FIL_LIS: { /* LIST open files */
12991 extern int cmd_rows, cmd_cols;
12992 #endif /* CK_TTGWSIZ */
12993 extern int xaskmore;
12994 int i, x, n = 0, paging = 0;
12997 if ((x = cmcfm()) < 0)
13001 if (cmd_rows > 0 && cmd_cols > 0)
13002 #endif /* CK_TTGWSIZ */
13005 printf("System open file limit:%5d\n", z_openmax);
13006 printf("Maximum for FILE OPEN: %5d\n", z_maxchan);
13007 printf("Files currently open: %5d\n\n", z_nopen);
13009 for (i = 0; i < z_maxchan; i++) {
13010 s = z_getname(i); /* Got one? */
13014 printf("%2d. %s",i,s); /* Print name */
13015 n++; /* Count it */
13016 x = z_getmode(i); /* Get modes & print them */
13018 if (x & FM_REA) ckstrncat(m,"R",8);
13019 if (x & FM_WRI) ckstrncat(m,"W",8);
13020 if (x & FM_APP) ckstrncat(m,"A",8);
13021 if (x & FM_BIN) ckstrncat(m,"B",8);
13026 else /* And file position too */
13027 printf(" %s",ckfstoa(z_getpos(i)));
13031 if (paging > 0) { /* Pause at end of screen */
13032 if (n > cmd_rows - 3) {
13039 #endif /* CK_TTGWSIZ */
13042 return(success = 1);
13045 case FIL_FLU: /* FLUSH */
13046 if ((x = cmnum("Channel number","",10,&n, xxstring)) < 0) {
13048 printf("?Channel number required\n");
13053 if ((x = cmcfm()) < 0)
13055 if (n == -9) return(success = 0);
13056 if (n == -8) return(success = 1);
13057 if ((rc = z_flush(n)) < 0) {
13058 printf("?FLUSH failed - Channel %d: %s\n",n,ckferror(rc));
13061 return(success = 1);
13063 case FIL_STA: /* STATUS */
13065 int i, j, k; /* Supply default if only one open */
13067 for (k = 0, j = 0, i = 0; i < z_maxchan; i++) {
13070 if (z_file[i]->z_fp) { k++; j = i; }
13072 if (k == 1) s = ckitoa(j);
13074 if ((x = cmnum("Channel number",s,10,&n, xxstring)) < 0) {
13077 printf("?%d files open - please supply channel number\n",
13084 if ((y = cmcfm()) < 0)
13086 if ((!z_file || z_nopen == 0) && x == -3) {
13087 printf("No files open\n");
13088 return(success = 1);
13090 p = blanks + 3; /* Tricky formatting... */
13094 if ((rc = z_getmode(n)) < 0) {
13095 printf("Channel %d:%s%s\n",n,p,ckferror(rc));
13096 return(success = 0);
13098 printf("Channel %d:%sNot open\n",n,p);
13099 return(success = 0);
13103 if (!s) s = "(name unknown)";
13104 printf("Channel %d:%sOpen\n",n,p);
13105 printf(" File: %s\n Modes: ",s);
13106 if (rc & FM_REA) printf(" /READ");
13107 if (rc & FM_WRI) printf(" /WRITE");
13108 if (rc & FM_APP) printf(" /APPEND");
13109 if (rc & FM_BIN) printf(" /BINARY");
13110 if (rc & FM_CMD) printf(" /COMMAND");
13111 if (rc & FM_EOF) printf(" [EOF]");
13112 printf("\n Size: %s\n",ckfstoa(z_count(n,RD_CHAR)));
13113 printf(" At byte: %s\n",ckfstoa(z_getpos(n)));
13115 if (xx > (CK_OFF_T)-1)
13116 printf(" At line: %s\n",ckfstoa(xx));
13117 return(success = 1);
13123 #endif /* CKCHANNELIO */
13126 /* Save Key maps and in OS/2 Mouse maps */
13128 savkeys(name,disp) char * name; int disp; {
13130 static struct filinfo xx;
13131 int savfil, i, j, k;
13137 xx.bs = 0; xx.cs = 0; xx.rl = 0; xx.org = 0; xx.cc = 0;
13138 xx.typ = 0; xx.dsp = XYFZ_A; xx.os_specific = "";
13140 savfil = zopeno(ZMFILE,name,NULL,&xx);
13141 } else savfil = zopeno(ZMFILE,name,NULL,NULL);
13146 zsout(ZMFILE, "; Kermit 95 SAVE KEYMAP file: ");
13150 "if eq \"\\v(program)\" \"C-Kermit\" set mskermit keycodes on");
13153 "if NOT eq \"\\v(program)\" \"C-Kermit\" stop 1 C-Kermit required.");
13154 zsoutl(ZMFILE,"set mskermit keycodes off");
13159 zsout(ZMFILE, "; C-Kermit SAVE KEYMAP file: ");
13163 zsoutl(ZMFILE,"; Clear previous keyboard mappings ");
13164 zsoutl(ZMFILE,"set key clear");
13166 for (k = 0; k < nttkey; k++) {
13167 if (!ttkeytab[k].flgs) {
13169 "set terminal key ",
13174 zsoutl(ZMFILE,buf);
13180 for (i = 0; i < KMSIZE; i++) {
13182 int len = strlen((char *)macrotab[i]);
13187 ckitoa(mskkeys ? cktomsk(i) : i),
13201 for (j = 0; j < len; j++) {
13202 char ch = macrotab[i][j];
13203 if (ch <= SP || ch >= DEL ||
13204 ch == '-' || ch == ',' ||
13205 ch == '{' || ch == '}' ||
13206 ch == ';' || ch == '?' ||
13207 ch == '.' || ch == '\'' ||
13208 ch == '\\' || ch == '/' ||
13210 ckmakmsg(buf,1024,"\\{",ckitoa((int)ch),"}",NULL);
13213 ckmakmsg(buf,1024,ckctoa((char)ch),NULL,NULL,NULL);
13218 ckmakmsg(buf,1024,"\t; ",keyname(i),NULL,NULL);
13219 zsoutl(ZMFILE,buf);
13223 } else if ( keymap[i] != i ) {
13225 if (IS_KVERB(keymap[i])) {
13226 for (j = 0; j < nkverbs; j++)
13227 if (kverbs[j].kwval == (keymap[i] & ~F_KVERB))
13229 if (j != nkverbs) {
13232 sprintf(buf, "set key \\%d \\K%s\t; %s",
13233 mskkeys ? cktomsk(i) : i,
13234 kverbs[j].kwd, keyname(i)
13237 ckmakxmsg(buf, /* 12 string args */
13240 ckitoa(mskkeys ? cktomsk(i) : i),
13245 NULL, NULL, NULL, NULL, NULL, NULL);
13246 #endif /* COMMENT */
13247 zsoutl(ZMFILE,buf);
13250 sprintf(buf, "set key \\%d \\K%s", i, kverbs[j].kwd);
13258 #endif /* COMMENT */
13259 zsoutl(ZMFILE,buf);
13263 #endif /* NOKVERBS */
13267 sprintf(buf, "set key \\%d \\{%d}\t; %s",
13268 mskkeys ? cktomsk(i) : i,
13273 ckmakxmsg(buf, /* 8 string args */
13276 ckitoa(mskkeys ? cktomsk(i) : i),
13281 NULL,NULL,NULL,NULL,NULL,NULL);
13282 #endif /* COMMENT */
13283 zsoutl(ZMFILE,buf);
13286 sprintf(buf, "set key \\%d \\{%d}", i, keymap[i]);
13288 ckmakxmsg(buf,1024,
13294 NULL,NULL,NULL,NULL,NULL,NULL,NULL);
13295 #endif /* COMMENT */
13296 zsoutl(ZMFILE,buf);
13302 /* OS/2 also has the SET TERMINAL KEY <termtype> defines */
13303 for (k = 0; k < nttkey; k++) {
13304 extern struct keynode * ttkeymap[];
13305 struct keynode * pnode = NULL;
13307 if (ttkeytab[k].flgs) /* Don't process CM_INV or CM_ABR */
13311 ckmakmsg(buf,1024,"; SET TERMINAL KEY ",ttkeytab[k].kwd,NULL,NULL);
13312 zsoutl(ZMFILE,buf);
13314 for (pnode = ttkeymap[ttkeytab[k].kwval];
13316 pnode = pnode->next
13318 switch (pnode->def.type) {
13321 sprintf(buf, "set terminal key %s \\%d \\{%d}\t; %s",
13323 mskkeys ? cktomsk(pnode->key) : pnode->key,
13324 pnode->def.key.scancode,
13325 keyname(pnode->key)
13330 "set terminal key ",
13334 cktomsk(pnode->key) :
13337 ckitoa(pnode->def.key.scancode),
13339 keyname(pnode->key),
13340 NULL,NULL,NULL,NULL
13342 #endif /* COMMENT */
13343 zsoutl(ZMFILE,buf);
13346 for (j = 0; j < nkverbs; j++)
13347 if (kverbs[j].kwval == (pnode->def.kverb.id & ~F_KVERB))
13349 if (j != nkverbs) {
13351 sprintf(buf, "set terminal key %s \\%d \\K%s\t; %s",
13353 mskkeys ? cktomsk(pnode->key) : pnode->key,
13354 kverbs[j].kwd, keyname(pnode->key)
13359 "set terminal key ",
13363 cktomsk(pnode->key) :
13368 keyname(pnode->key),
13369 NULL,NULL,NULL,NULL
13371 #endif /* COMMENT */
13372 zsoutl(ZMFILE,buf);
13376 int len = strlen((char *)pnode->def.macro.string);
13378 sprintf(buf,"set terminal key %s \\%d ",
13380 mskkeys ? cktomsk(pnode->key) : pnode->key);
13384 "set terminal key ",
13388 cktomsk(pnode->key) :
13391 NULL,NULL,NULL,NULL,NULL,NULL,NULL
13393 #endif /* COMMENT */
13396 for (j = 0; j < len; j++) {
13397 char ch = pnode->def.macro.string[j];
13398 if (ch <= SP || ch >= DEL ||
13399 ch == '-' || ch == ',' ||
13400 ch == '{' || ch == '}' ||
13401 ch == ';' || ch == '?' ||
13402 ch == '.' || ch == '\'' ||
13403 ch == '\\' || ch == '/' ||
13406 "\\{",ckitoa((int)ch),"}",NULL);
13410 ckctoa((char)ch),NULL,NULL,NULL);
13414 ckmakmsg(buf,1024,"\t; ",keyname(pnode->key),NULL,NULL);
13415 zsoutl(ZMFILE,buf);
13419 int len = strlen((char *)pnode->def.literal.string);
13421 sprintf(buf,"set terminal key %s /literal \\%d ",
13423 mskkeys ? cktomsk(pnode->key) : pnode->key);
13427 "set terminal key ",
13431 cktomsk(pnode->key) :
13434 NULL,NULL,NULL,NULL,NULL,NULL,NULL);
13435 #endif /* COMMENT */
13438 for (j = 0; j < len; j++) {
13439 char ch = pnode->def.literal.string[j];
13440 if (ch <= SP || ch >= DEL ||
13441 ch == '-' || ch == ',' ||
13442 ch == '{' || ch == '}' ||
13443 ch == ';' || ch == '?' ||
13444 ch == '.' || ch == '\'' ||
13445 ch == '\\' || ch == '/' ||
13448 "\\{",ckitoa((int)ch),"}",NULL);
13452 ckctoa((char)ch),NULL,NULL,NULL);
13456 ckmakmsg(buf,1024,"\t; ",keyname(pnode->key),NULL,NULL);
13457 zsoutl(ZMFILE,buf);
13463 "set terminal key %s /literal \\%d \\{%d}\\{%d}\t; %s",
13465 mskkeys ? cktomsk(pnode->key) : pnode->key,
13466 ISDG200(ttkeytab[k].kwval) ? 30 : 27,
13467 pnode->def.esc.key & ~F_ESC,
13468 keyname(pnode->key)
13473 "set terminal key ",
13477 cktomsk(pnode->key) :
13480 ckitoa(ISDG200(ttkeytab[k].kwval) ? 30 : 27),
13482 ckitoa(pnode->def.esc.key & ~F_ESC),
13484 keyname(pnode->key),
13487 #endif /* COMMENT */
13488 zsoutl(ZMFILE,buf);
13493 "set terminal key %s /literal \\%d \\{27}[\\{%d}\t; %s",
13495 mskkeys ? cktomsk(pnode->key) : pnode->key,
13496 pnode->def.csi.key & ~F_CSI,
13497 keyname(pnode->key)
13502 "set terminal key ",
13506 cktomsk(pnode->key) :
13509 ckitoa(pnode->def.csi.key & ~F_CSI),
13511 keyname(pnode->key),
13512 NULL,NULL,NULL,NULL
13514 #endif /* COMMENT */
13515 zsoutl(ZMFILE,buf);
13525 zsoutl(ZMFILE,"; End");
13527 return(success = 1);
13529 return(success = 0);
13532 #endif /* NOSETKEY */
13539 static struct keytab trmtrmopt[] = {
13540 { "scrollback", SV_SCRL, 0 }
13542 #endif /* NOLOCAL */
13545 static struct keytab cmdtrmopt[] = {
13547 { "history", SV_HIST, 0 },
13548 #endif /* CK_RECALL */
13551 { "scrollback", SV_SCRL, 0 },
13552 #endif /* NOLOCAL */
13556 static int ncmdtrmopt = (sizeof (cmdtrmopt) / sizeof (struct keytab)) - 1;
13560 _PROTOTYP(int savscrbk, (int, char *, int));
13561 #endif /* NOLOCAL */
13565 _PROTOTYP(int savhistory, (char *, int));
13566 #endif /* CK_RECALL */
13569 dosave(xx) int xx; {
13570 int x, y = 0, disp;
13572 extern struct keytab disptb[];
13574 struct zfnfp * fnp;
13575 #endif /* ZFNQFP */
13578 if (xx == XSKEY) { /* SAVE KEYMAP.. */
13579 z = cmofi("Name of Kermit command file","keymap.ksc",&s,xxstring);
13581 #endif /* NOSETKEY */
13583 case XSCMD: /* SAVE COMMAND.. */
13584 if ((y = cmkey(cmdtrmopt, ncmdtrmopt, "What to save",
13595 case XSTERM: /* SAVE TERMINAL.. */
13596 if ((y = cmkey(trmtrmopt,1,
13597 "What to save","scrollback",xxstring)) < 0)
13600 #endif /* NOLOCAL */
13603 z = cmofi("Filename",
13604 ((y == SV_SCRL) ? "scrollbk.txt" : "history.txt"),
13610 #endif /* NOSETKEY */
13611 if (z < 0) /* Check output-file parse results */
13614 printf("?Sorry, %s is a directory name\n",s);
13618 if ((fnp = zfnqfp(s,TMPBUFSIZ - 1,tmpbuf))) {/* Convert to full pathname */
13620 if ((int) strlen(fnp->fpath) > 0)
13623 #endif /* ZFNQFP */
13625 ckstrncpy(line,s,LINBUFSIZ); /* Make safe copy of pathname */
13630 /* Get NEW/APPEND disposition */
13631 if ((z = cmkey(disptb,2,"Disposition","new",xxstring)) < 0)
13635 if ((x = cmcfm()) < 0) /* Get confirmation */
13638 switch (xx) { /* Do action.. */
13640 case XSKEY: /* SAVE KEYMAP */
13641 return (savkeys(s,disp));
13642 #endif /* NOSETKEY */
13644 case XSCMD: /* SAVE COMMAND.. */
13647 if (y == SV_SCRL) /* .. SCROLLBACK */
13648 return(success = savscrbk(VCMD,s,disp));
13649 #endif /* NOLOCAL */
13652 if (y == SV_HIST) /* .. HISTORY */
13653 return(success = savhistory(s,disp));
13654 #endif /* NORECALL */
13659 case XSTERM: /* SAVE TERMINAL SCROLLBACK */
13660 return(success = savscrbk(VTERM,s,disp));
13661 #endif /* NOLOCAL */
13671 Read text with a custom prompt into given buffer using command parser but
13672 with no echoing or entry into recall buffer.
13675 readtext(prmpt, buffer, bufsiz) char * prmpt; char * buffer; int bufsiz; {
13677 extern int on_recall; /* Around Password prompting */
13678 #endif /* CK_RECALL */
13683 extern int startflags;
13684 int vmode_sav = vmode;
13686 if (!prmpt) prmpt = "";
13688 if (win95_popup && !(startflags & 96)
13693 return(popup_readtext(vmode,NULL,prmpt,buffer,bufsiz,0));
13695 if (vmode == VTERM) {
13697 VscrnIsDirty(VTERM);
13698 VscrnIsDirty(VCMD);
13701 #endif /* NOLOCAL */
13705 #endif /* CK_RECALL */
13706 cmsavp(psave,PROMPTL); /* Save old prompt */
13707 cmsetp(prmpt); /* Make new prompt */
13708 concb((char)escape); /* Put console in cbreak mode */
13709 cmini(1); /* and echo mode */
13710 if (pflag) prompt(xxstring); /* Issue prompt if at top level */
13711 cmres(); /* Reset the parser */
13712 for (rc = -1; rc < 0; ) { /* Prompt till they answer */
13713 rc = cmtxt("","",&s,NULL); /* Get a literal line of text */
13714 cmres(); /* Reset the parser again */
13716 ckstrncpy(buffer,s,bufsiz);
13717 cmsetp(psave); /* Restore original prompt */
13721 if (vmode != vmode_sav) {
13723 VscrnIsDirty(VCMD);
13724 VscrnIsDirty(VTERM);
13727 #endif /* NOLOCAL */
13732 /* A general function to allow a Password or other information */
13733 /* to be read from the command prompt without it going into */
13734 /* the recall buffer or being echo'd. */
13737 readpass(prmpt, buffer, bufsiz) char * prmpt; char * buffer; int bufsiz; {
13740 if (!prmpt) prmpt = "";
13741 printf("%s", prmpt);
13743 /* Some linkers won't allow this because it's unsafe */
13745 #else /* COMMENT */
13747 int c, i; char * p;
13749 for (i = 0; i < bufsiz-1; i++) {
13750 if ((c = getchar()) == EOF)
13758 #endif /* COMMENT */
13762 extern int on_recall; /* around Password prompting */
13763 #endif /* CK_RECALL */
13768 extern int startflags;
13769 int vmode_sav = vmode;
13771 #endif /* NOLOCAL */
13774 #endif /* CKSYSLOG */
13775 if (!prmpt) prmpt = "";
13777 debok = 0; /* Don't log */
13779 if (win95_popup && !(startflags & 96)
13784 x = popup_readpass(vmode,NULL,prmpt,buffer,bufsiz,0);
13789 #endif /* NOLOCAL */
13792 savlog = ckxsyslog; /* Save and turn off syslogging */
13794 #endif /* CKSYSLOG */
13797 if (vmode == VTERM) {
13799 VscrnIsDirty(VTERM);
13800 VscrnIsDirty(VCMD);
13803 #endif /* NOLOCAL */
13806 #endif /* CK_RECALL */
13807 cmsavp(psave,PROMPTL); /* Save old prompt */
13808 cmsetp(prmpt); /* Make new prompt */
13809 concb((char)escape); /* Put console in cbreak mode */
13810 cmini(0); /* and no-echo mode */
13811 if (pflag) prompt(xxstring); /* Issue prompt if at top level */
13812 cmres(); /* Reset the parser */
13813 for (rc = -1; rc < 0; ) { /* Prompt till they answer */
13814 rc = cmtxt("","",&s,NULL); /* Get a literal line of text */
13815 cmres(); /* Reset the parser again */
13817 ckstrncpy(buffer,s,bufsiz);
13818 printf("\r\n"); /* Echo a CRLF */
13819 cmsetp(psave); /* Restore original prompt */
13820 cmini(1); /* Restore echo mode */
13823 if (vmode != vmode_sav) {
13825 VscrnIsDirty(VCMD);
13826 VscrnIsDirty(VTERM);
13829 #endif /* NOLOCAL */
13831 ckxsyslog = savlog; /* Restore syslogging */
13832 #endif /* CKSYSLOG */
13839 struct keytab authtab[] = { /* Available authentication types */
13841 { "k4", AUTH_KRB4, CM_INV },
13842 { "k5", AUTH_KRB5, CM_INV },
13843 { "kerberos4", AUTH_KRB4, 0 },
13844 { "kerberos5", AUTH_KRB5, 0 },
13845 { "krb4", AUTH_KRB4, CM_INV },
13846 { "krb5", AUTH_KRB5, CM_INV },
13847 #endif /* CK_KERBEROS */
13849 { "ntlm", AUTH_NTLM, 0 },
13852 { "srp", AUTH_SRP, 0 },
13853 #endif /* CK_SRP */
13855 { "ssl", AUTH_SSL, 0 },
13856 #endif /* CK_SSL */
13859 int authtabn = sizeof(authtab)/sizeof(struct keytab)-1;
13862 struct keytab kerbtab[] = { /* Kerberos authentication types */
13863 { "k4", AUTH_KRB4, CM_INV },
13864 { "k5", AUTH_KRB5, CM_INV },
13865 { "kerberos4", AUTH_KRB4, 0 },
13866 { "kerberos5", AUTH_KRB5, 0 },
13867 { "krb4", AUTH_KRB4, CM_INV },
13868 { "krb5", AUTH_KRB5, CM_INV }
13870 int kerbtabn = sizeof(kerbtab)/sizeof(struct keytab);
13872 static struct keytab krb_s_tbl[] = { /* AUTHENTICATE command switches: */
13873 { "/cache", KRB_S_CA, CM_ARG }
13875 static int krb_s_n = sizeof(krb_s_tbl)/sizeof(struct keytab);
13877 static struct keytab krb_v_tbl[] = { /* KERBEROS version values: */
13879 { "5", 5, 0 }, /* (add others as needed...) */
13880 { "auto", 0, 0 } /* Note: 0 = auto */
13882 static int krb_v_n = sizeof(krb_v_tbl)/sizeof(struct keytab);
13884 static struct keytab krb_a_tbl[] = { /* KERBEROS actions: */
13885 { "destroy", KRB_A_DE, 0 },
13886 { "initialize", KRB_A_IN, 0 },
13887 { "list-credentials", KRB_A_LC, 0 }
13889 static int krb_a_n = sizeof(krb_a_tbl)/sizeof(struct keytab);
13891 static struct keytab krb4_i_tbl[] = { /* KERBEROS 4 INITIALIZE switches: */
13892 { "/brief", KRB_I_BR, 0 }, /* /BRIEF */
13893 { "/instance", KRB_I_IN, CM_ARG }, /* /INSTANCE: */
13894 { "/lifetime", KRB_I_LF, CM_ARG }, /* /LIFETIME: */
13895 { "/not-preauth", KRB_I_NPA, 0 }, /* /NOT-PREAUTH */
13896 { "/password", KRB_I_PW, CM_ARG }, /* /PASSWORD: */
13898 { "/popup", KRB_I_POP, 0 }, /* /POPUP */
13900 { "/preauth", KRB_I_PA, 0 }, /* /PREAUTH */
13901 { "/realm", KRB_I_RL, CM_ARG }, /* /REALM: */
13902 { "/verbose", KRB_I_VB, 0 }, /* /VERBOSE */
13905 static int krb4_i_n = sizeof(krb4_i_tbl)/sizeof(struct keytab) - 1;
13907 static struct keytab krb5_i_tbl[] = { /* KERBEROS 5 INITIALIZE switches: */
13908 { "/addresses", KRB_I_ADR, CM_ARG },
13909 { "/forwardable", KRB_I_FW, 0 }, /* /FORWARDABLE */
13910 { "/instance", KRB_I_IN, CM_ARG }, /* /INSTANCE: */
13911 { "/k4", KRB_I_K4, CM_INV }, /* /KERBEROS4 */
13912 { "/kerberos4", KRB_I_K4, 0 }, /* /KERBEROS4 */
13913 { "/krb4", KRB_I_K4, CM_INV }, /* /KERBEROS4 */
13914 { "/lifetime", KRB_I_LF, CM_ARG }, /* /LIFETIME: */
13915 { "/no-addresses", KRB_I_NAD, 0 }, /* /NO-ADDRESSES */
13916 { "/no-k4", KRB_I_NK4, CM_INV },/* /NO-KERBEROS4 */
13917 { "/no-kerberos4", KRB_I_NK4, 0 }, /* /NO-KERBEROS4 */
13918 { "/no-krb4", KRB_I_NK4, CM_INV },/* /NO-KERBEROS4 */
13919 { "/not-forwardable", KRB_I_NFW, 0 }, /* /NOT-FORWARDABLE */
13920 { "/not-proxiable", KRB_I_NPR, 0 }, /* /NOT-PROXIABLE */
13921 { "/password", KRB_I_PW, CM_ARG }, /* /PASSWORD: */
13923 { "/popup", KRB_I_POP, 0 }, /* /POPUP */
13925 { "/postdate", KRB_I_PD, CM_ARG }, /* /POSTDATE: */
13926 { "/pr", KRB_I_PR, CM_INV|CM_ABR }, /* to allow for */
13927 { "/pro", KRB_I_PR, CM_INV|CM_ABR }, /* different spellings */
13928 { "/prox", KRB_I_PR, CM_INV|CM_ABR },
13929 { "/proxiable", KRB_I_PR, 0 }, /* /PROXIABLE */
13930 { "/proxyable", KRB_I_PR, CM_INV }, /* /PROXYABLE */
13931 { "/realm", KRB_I_RL, CM_ARG }, /* /REALM: */
13932 { "/renew", KRB_I_RN, 0 }, /* /RENEW */
13933 { "/renewable", KRB_I_RB, CM_ARG }, /* /RENEWABLE: */
13934 { "/service", KRB_I_SR, CM_ARG }, /* /SERVICE: */
13935 { "/validate", KRB_I_VA, 0 }, /* /VALIDATE */
13938 static int krb5_i_n = sizeof(krb5_i_tbl)/sizeof(struct keytab) - 1;
13940 static struct keytab klctab[] = { /* List Credentials switches*/
13941 { "/addresses", XYKLCAD, 0 },
13942 { "/encryption", XYKLCEN, 0 },
13943 { "/flags", XYKLCFL, 0 }
13945 static int nklctab = sizeof(klctab)/sizeof(struct keytab);
13947 extern int krb_action;
13948 extern struct krb_op_data krb_op;
13950 extern struct krb5_list_cred_data krb5_lc;
13951 extern struct krb5_init_data krb5_init;
13952 extern char * krb5_d_principal; /* Default principal */
13953 extern char * krb5_d_instance;
13954 extern char * krb5_d_realm; /* Default realm */
13955 extern char * krb5_d_cc; /* Default credentials cache */
13956 extern char * krb5_d_srv; /* Default service name */
13957 extern int krb5_d_lifetime; /* Default lifetime */
13958 extern int krb5_d_forwardable;
13959 extern int krb5_d_proxiable;
13960 extern int krb5_d_renewable;
13961 extern int krb5_autoget;
13962 extern int krb5_autodel;
13963 extern int krb5_d_getk4;
13964 extern int krb5_d_no_addresses;
13965 extern int krb5_checkaddrs;
13966 extern char * krb5_d_addrs[];
13967 extern char * k5_keytab; /* Keytab file */
13969 extern struct krb4_init_data krb4_init;
13970 extern char * krb4_d_principal; /* Default principal */
13971 extern char * krb4_d_realm; /* Default realm */
13972 extern char * krb4_d_srv; /* Default service name */
13973 extern int krb4_d_lifetime; /* Default lifetime */
13974 extern int krb4_d_preauth;
13975 extern char * krb4_d_instance;
13976 extern int krb4_autoget;
13977 extern int krb4_autodel;
13978 extern int krb4_checkaddrs;
13979 extern char * k4_keytab; /* Keytab file */
13980 #endif /* CK_KERBEROS */
13987 extern int ckxsyslog, ckxwtmp, ckxanon;
13989 extern int ckxpriv;
13992 extern int ckxperms;
13993 #endif /* CK_PERMS */
13994 extern char * anonfile, * userfile, * anonroot;
13996 extern char * anonacct;
13999 extern char * iks_domain;
14001 #endif /* CK_LOGIN */
14003 extern char * wtmpfile;
14004 #endif /* CKWTMP */
14006 extern char * dbfile;
14007 extern int dbenabled;
14010 extern int logintimo;
14011 #endif /* CK_LOGIN */
14012 extern int srvcdmsg, success, iksdcf, noinit, arg_x;
14013 extern char * cdmsgfile[], * cdmsgstr, *kermrc;
14014 char * bannerfile = NULL;
14015 char * helpfile = NULL;
14016 extern int xferlog;
14017 extern char * xferfile;
14021 printf("?Command disabled\r\n");
14022 return(success = 0);
14025 printf("IKS Settings\r\n");
14028 printf(" Anonymous Account: %s\r\n",anonacct?anonacct:"<none>");
14030 printf(" Anonymous Initfile: %s\r\n",anonfile?anonfile:"<none>");
14031 printf(" Anonymous Login: %d\r\n",ckxanon);
14032 printf(" Anonymous Root: %s\r\n",anonroot?anonroot:"<none>");
14033 #endif /* CK_LOGIN */
14034 printf(" Bannerfile: %s\r\n",bannerfile?bannerfile:"<none>");
14035 printf(" CDfile: %s\r\n",cdmsgfile[0]?cdmsgfile[0]:"<none>");
14036 for ( i=1;i<16 && cdmsgfile[i];i++ )
14037 printf(" CDfile: %s\r\n",cdmsgfile[i]);
14038 printf(" CDMessage: %d\r\n",srvcdmsg);
14040 printf(" DBfile: %s\r\n",dbfile?dbfile:"<none>");
14041 printf(" DBenabled: %d\r\n",dbenabled);
14045 printf(" Default-domain: %s\r\n",iks_domain?iks_domain:".");
14047 #endif /* CK_LOGIN */
14048 printf(" Helpfile: %s\r\n",helpfile?helpfile:"<none>");
14049 printf(" Initfile: %s\r\n",kermrc?kermrc:"<none>");
14050 printf(" No-Initfile: %d\r\n",noinit);
14053 printf(" Permission code: %0d\r\n",ckxperms);
14054 #endif /* CK_PERM */
14056 printf(" Privileged Login: %d\r\n",ckxpriv);
14058 #endif /* CK_LOGIN */
14059 printf(" Server-only: %d\r\n",arg_x);
14060 printf(" Syslog: %d\r\n",ckxsyslog);
14061 printf(" Timeout (seconds): %d\r\n",logintimo);
14062 printf(" Userfile: %s\r\n",userfile?userfile:"<none>");
14065 printf(" Wtmplog: %d\r\n",ckxwtmp);
14066 printf(" Wtmpfile: %s\r\n",wtmpfile?wtmpfile:"<none>");
14067 #endif /* CKWTMP */
14068 #endif /* CK_LOGIN */
14069 printf(" Xferfile: %s\r\n",xferfile?xferfile:"<none>");
14070 printf(" Xferlog: %d\r\n",xferlog);
14071 #else /* IKSDCONF */
14072 printf("?Nothing to show.\r\n");
14073 #endif /* IKSDCONF */
14074 return(success = 1);
14077 #ifdef CK_AUTHENTICATION
14079 sho_auth(cx) int cx; {
14080 extern int auth_type_user[], cmd_rows;
14083 int kv = 0, all = 0, n = 0;
14086 if (inserver && isguest) {
14087 printf("?Sorry, command disabled.\r\n");
14088 return(success = 0);
14093 } else if (auth_type_user[0] != AUTHTYPE_AUTO) {
14094 kv = auth_type_user[0];
14097 kv = AUTHTYPE_KERBEROS_V4;
14101 case AUTHTYPE_KERBEROS_V4:
14102 kv = all ? AUTHTYPE_KERBEROS_V5 : 0;
14103 if (ck_krb4_is_installed()) {
14104 printf(" Authentication: Kerberos 4\n");
14105 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14107 printf(" Authentication: Kerberos 4 (not installed)\n");
14108 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14112 printf(" Keytab file: %s\n",
14113 k4_keytab ? k4_keytab : "(none)");
14114 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14115 if (krb_action < 0) {
14118 for (p = "", i = 0; i < krb_a_n; i++) {
14119 if (krb_action == krb_a_tbl[i].kwval) {
14120 p = krb_a_tbl[i].kwd;
14125 printf(" Action: %s\n", p);
14126 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14127 printf(" Default lifetime %d\n",krb4_d_lifetime);
14128 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14129 printf(" Lifetime: %d (minutes)\n",krb4_init.lifetime);
14130 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14131 printf(" Default preauth: %d\n",krb4_d_preauth);
14132 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14133 printf(" Preauth: %d\n",krb4_init.preauth);
14134 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14135 printf(" Default principal: \"%s\"\n",
14136 krb4_d_principal ? krb4_d_principal : "");
14137 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14138 printf(" Principal: \"%s\"\n",
14139 krb4_init.principal ? krb4_init.principal : "");
14140 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14141 printf(" Default realm: \"%s\"\n",
14142 krb4_d_realm ? krb4_d_realm : "");
14143 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14144 printf(" Realm: \"%s\"\n",
14145 krb4_init.realm ? krb4_init.realm : "");
14146 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14147 printf(" Default instance: \"%s\"\n",
14148 krb4_d_instance ? krb4_d_instance : "");
14149 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14150 printf(" Instance: \"%s\"\n",
14151 krb4_init.instance ? krb4_init.instance : "");
14152 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14153 printf(" Auto-Get TGTs: %d\n",krb4_autoget);
14154 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14155 printf(" Auto-Destroy TGTs: %s\n",
14156 krb4_autodel==KRB_DEL_NO?"never":
14157 krb4_autodel==KRB_DEL_CL?"on-close":"on-exit");
14158 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14159 printf(" Check IP Addresses: %d\n",krb4_checkaddrs);
14160 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14162 printf(" Password: \"%s\"\n",
14163 krb4_init.password ? krb4_init.password : "");
14164 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14165 #endif /* COMMENT */
14166 #endif /* CK_KERBEROS */
14168 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14170 case AUTHTYPE_KERBEROS_V5:
14171 kv = all ? AUTHTYPE_SSL : 0;
14172 if (ck_krb5_is_installed()) {
14173 if (ck_gssapi_is_installed())
14174 printf(" Authentication: Kerberos 5 plus GSSAPI\n");
14176 printf(" Authentication: Kerberos 5\n");
14177 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14179 printf(" Authentication: Kerberos 5 (not installed)\n");
14180 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14185 printf(" Cache file: %s\n",
14186 krb_op.cache ? krb_op.cache : "(none)");
14187 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14188 printf(" Default cache: %s\n",
14189 krb5_d_cc ? krb5_d_cc : "(none)");
14190 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14191 printf(" Keytab file: %s\n",
14192 k5_keytab ? k5_keytab : "(none)");
14193 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14194 if (krb_action < 0) {
14197 for (p = "", i = 0; i < krb_a_n; i++) {
14198 if (krb_action == krb_a_tbl[i].kwval) {
14199 p = krb_a_tbl[i].kwd;
14204 printf(" Action: %s\n", p);
14205 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14207 printf(" Default forwardable %d\n",krb5_d_forwardable);
14208 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14209 printf(" Forwardable: %d\n",krb5_init.forwardable);
14210 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14211 printf(" Default lifetime %d\n",krb5_d_lifetime);
14212 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14213 printf(" Lifetime: %d (minutes)\n",krb5_init.lifetime);
14214 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14215 printf(" Postdate: \"%s\"\n",
14216 krb5_init.postdate ? krb5_init.postdate: "");
14217 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14218 printf(" Default proxiable: %d\n",krb5_d_proxiable);
14219 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14220 printf(" Proxiable: %d\n",krb5_init.proxiable);
14221 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14222 printf(" Renew: %d\n",krb5_init.renew);
14223 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14224 printf(" Default renewable: %d (minutes)\n",krb5_d_renewable);
14225 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14226 printf(" Renewable: %d (minutes)\n",krb5_init.renewable);
14227 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14228 printf(" Service: \"%s\"\n",
14229 krb5_init.service ? krb5_init.service : "");
14230 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14231 printf(" Validate: %d\n",krb5_init.validate);
14232 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14233 printf(" Default principal: \"%s\"\n",
14234 krb5_d_principal ? krb5_d_principal : "");
14235 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14236 printf(" Principal: \"%s\"\n",
14237 krb5_init.principal ? krb5_init.principal : "");
14238 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14239 printf(" Default instance: \"%s\"\n",
14240 krb5_d_instance ? krb5_d_instance : "");
14241 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14242 printf(" Default realm: \"%s\"\n",
14243 krb5_d_realm ? krb5_d_realm : "");
14244 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14245 printf(" Realm: \"%s\"\n",
14246 krb5_init.realm ? krb5_init.realm : "");
14247 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14248 printf(" Auto-Get TGTs: %d\n",krb5_autoget);
14249 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14250 printf(" Auto-Destroy TGTs: %s\n",
14251 krb5_autodel==KRB_DEL_NO?"never":
14252 krb5_autodel==KRB_DEL_CL?"on-close":"on-exit");
14253 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14254 printf(" Default get K4 TGTs: %d\n",krb5_d_getk4);
14255 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14256 printf(" Get K4 TGTs: %d\n",krb5_init.getk4);
14257 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14258 printf(" Check IP Addresses: %d\n",krb5_checkaddrs);
14259 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14260 printf(" No IP Addresses: %d\n",krb5_d_no_addresses);
14261 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14262 printf(" IP-Addresses: ");
14263 if (krb5_init.addrs && krb5_init.addrs[0]) {
14264 for (i = 0; krb5_init.addrs[i]; i++) {
14267 printf("%s",krb5_init.addrs[i]);
14269 } else if (krb5_d_addrs[0]) {
14270 for (i = 0;i < KRB5_NUM_OF_ADDRS && krb5_d_addrs[i];i++) {
14273 printf("%s",krb5_d_addrs[i]);
14276 printf("(use default)");
14279 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14281 printf(" Password: \"%s\"\n",
14282 krb5_init.password ? krb5_init.password : "");
14283 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14284 #endif /* COMMENT */
14285 #endif /* CK_KERBEROS */
14287 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14291 kv = all ? AUTHTYPE_SRP : 0;
14292 if (ck_ssleay_is_installed()) {
14293 printf(" Authentication: SSL/TLS (%s)\n",
14294 SSLeay_version(SSLEAY_VERSION));
14295 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14297 printf(" Authentication: SSL/TLS (not installed)\n");
14298 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14301 printf(" RSA Certs file: %s\n",ssl_rsa_cert_file?
14302 ssl_rsa_cert_file:"(none)");
14303 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14304 printf(" RSA Certs Chain file: %s\n",ssl_rsa_cert_chain_file?
14305 ssl_rsa_cert_chain_file:"(none)");
14306 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14307 printf(" RSA Key file: %s\n",ssl_rsa_key_file?
14308 ssl_rsa_key_file:"(none)");
14309 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14310 printf(" DSA Certs file: %s\n",ssl_dsa_cert_file?
14311 ssl_dsa_cert_file:"(none)");
14312 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14313 printf(" DSA Certs Chain file: %s\n",ssl_dsa_cert_chain_file?
14314 ssl_dsa_cert_chain_file:"(none)");
14315 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14316 printf(" DH Key file: %s\n",ssl_dh_key_file?
14317 ssl_dh_key_file:"(none)");
14318 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14319 printf(" DH Param file: %s\n",ssl_dh_param_file?
14320 ssl_dh_param_file:"(none)");
14321 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14322 printf(" CRL file: %s\n",ssl_crl_file?
14323 ssl_crl_file:"(none)");
14324 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14325 printf(" CRL dir: %s\n",ssl_crl_dir?
14326 ssl_crl_dir:"(none)");
14327 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14328 printf(" Random file: %s\n",ssl_rnd_file?
14329 ssl_rnd_file:"(none)");
14330 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14331 printf(" Verify file: %s\n",ssl_verify_file?
14332 ssl_verify_file:"(none)");
14333 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14334 printf(" Verify dir: %s\n",ssl_verify_dir?
14335 ssl_verify_dir:"(none)");
14336 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14337 printf(" Cipher list: %s\n",ssl_cipher_list ? ssl_cipher_list :
14338 DEFAULT_CIPHER_LIST);
14339 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14340 if (ssl_con == NULL) {
14341 SSL_library_init();
14342 ssl_ctx = (SSL_CTX *)
14343 SSL_CTX_new((SSL_METHOD *)TLSv1_method());
14344 if (ssl_ctx != NULL)
14345 ssl_con= (SSL *) SSL_new(ssl_ctx);
14347 if (ssl_con != NULL) {
14351 for (i = 0; ; i++) {
14352 p = (CHAR *) SSL_get_cipher_list(ssl_con,i);
14356 if (++n > cmd_rows - 3)
14357 if (!askmore()) return(0); else n = 0;
14360 printf(" Certs OK? %s\n",ssl_certsok_flag? "yes" : "no");
14361 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14362 printf(" Debug mode: %s\n", ssl_debug_flag ? "on" : "off");
14363 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14364 printf(" Verbose mode: %s\n", ssl_verbose_flag ? "on" : "off");
14365 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14366 printf(" Verify mode: %s\n",
14367 ssl_verify_flag == SSL_VERIFY_NONE ? "none" :
14368 ssl_verify_flag == SSL_VERIFY_PEER ? "peer-cert" :
14369 "fail-if-no-peer-cert");
14370 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14371 printf(" SSL only? %s\n", ssl_only_flag ? "yes" : "no");
14372 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14373 printf(" TLS only? %s\n", tls_only_flag ? "yes" : "no");
14374 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14375 #endif /* CK_SSL */
14377 case AUTHTYPE_NTLM:
14379 if (ck_ntlm_is_installed()) {
14380 printf(" Authentication: NTLM\n");
14381 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14382 printf(" No options\n");
14383 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14385 printf(" Authentication: NTLM (not installed)\n");
14386 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14390 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14393 kv = all ? AUTHTYPE_NTLM : 0;
14394 if (ck_srp_is_installed()) {
14395 if (ck_krypto_is_installed())
14396 printf(" Authentication: SRP plus Krypto API\n");
14398 printf(" Authentication: SRP\n");
14399 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14400 printf(" No options\n");
14401 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14403 printf(" Authentication: SRP (not installed)\n");
14404 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14408 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14412 return(success = 1);
14414 #endif /* CK_AUTHENTICATION */
14415 #endif /* NOSHOW */
14419 /* C P _ A U T H -- AUTHENTICATE command parsing */
14422 cp_auth() { /* Command_Parse AUTHENTICATE */
14423 int c, i, n; /* Workers */
14424 int rc = 0; /* Return code */
14425 int getval; /* Parsing helpers */
14426 int tmpauth = 0; /* Temporary authentication type */
14427 int kv = 0; /* Temporary Kerberos version */
14428 int tmp_action = -1; /* Temporary Kerberos action */
14429 int tmp_klc = 0; /* Temporary list-credentials */
14430 char tmphlp[256]; /* For building help message */
14432 char * tmppswd = NULL; /* Password */
14433 char * tmpprinz = NULL; /* Principal */
14434 char * tmprealm = NULL; /* Realm */
14435 char * tmpcache = NULL; /* Cache file */
14436 char * tmpinst = NULL; /* K4 Instance */
14437 char * tmpaddrs[KRB5_NUM_OF_ADDRS];
14439 extern int on_recall; /* around Password prompting */
14440 #endif /* CK_RECALL */
14441 struct stringint pv[KRB_I_MAX+1]; /* Temporary array for switch values */
14442 struct FDB kw, sw, fl; /* FDBs for each parse function */
14444 krb_action = -1; /* Initialize Kerberos action. */
14445 tmp_action = -1; /* And our local copy. */
14446 for (i = 0; i < KRB5_NUM_OF_ADDRS; i++)
14447 tmpaddrs[i] = NULL;
14449 if ((y = cmkey(kerbtab,kerbtabn,"authentication type","",xxstring)) < 0)
14452 printf("?Authentication type not specified - nothing happens\n");
14456 debug(F101,"kerberos authentication","",tmpauth);
14458 case AUTH_KRB4: kv = 4; break; /* Don't assume values are the same */
14459 case AUTH_KRB5: kv = 5; break;
14461 printf("?Authentication type not supported: \"%s\"\n",atmbuf);
14465 /* From here down is Kerberos */
14466 ini_kerb(); /* Reset Init data to defaults */
14468 if (kv == 4) { /* Set K4 defaults */
14470 makestr(&tmprealm,krb4_d_realm);
14471 if (krb4_d_principal)
14472 makestr(&tmpprinz,krb4_d_principal);
14473 if (krb4_d_instance)
14474 makestr(&tmpinst,krb4_d_instance);
14475 } else if (kv == 5) { /* Set K5 defaults */
14477 makestr(&tmpcache,krb5_d_cc);
14479 makestr(&tmprealm,krb5_d_realm);
14480 if (krb5_d_principal)
14481 makestr(&tmpprinz,krb5_d_principal);
14482 if (krb5_d_instance)
14483 makestr(&tmpinst,krb5_d_instance);
14485 for (i = 0; i <= KRB_I_MAX; i++) { /* Initialize switch values */
14486 pv[i].sval = NULL; /* to null pointers */
14487 pv[i].ival = 0; /* and 0 int values */
14488 pv[i].wval = (CK_OFF_T)-1; /* and -1 wide values */
14490 if (kv == 4) { /* Kerberos 4 */
14491 pv[KRB_I_LF].ival = krb4_d_lifetime;
14492 pv[KRB_I_PA].ival = krb4_d_preauth;
14494 if ((n = cmkey(krb_a_tbl,krb_a_n,"Kerberos 4 action","",xxstring)) < 0)
14497 printf("?Action not specified - nothing happens.\n");
14500 } else if (kv == 5) { /* Kerberos 5 */
14501 pv[KRB_I_FW].ival = krb5_d_forwardable;
14502 pv[KRB_I_PR].ival = krb5_d_proxiable;
14503 pv[KRB_I_LF].ival = krb5_d_lifetime;
14504 pv[KRB_I_RB].ival = krb5_d_renewable;
14505 pv[KRB_I_K4].ival = krb5_d_getk4;
14506 pv[KRB_I_NAD].ival = krb5_d_no_addresses;
14508 /* Make help message that shows switches and action keywords */
14509 ckstrncpy(tmphlp,"Kerberos 5 action, one of the following:\n ",256);
14510 for (i = 0; i < krb_a_n; i++) {
14511 ckstrncat(tmphlp,krb_a_tbl[i].kwd,sizeof(tmphlp));
14512 if (i == krb_a_n - 1)
14513 ckstrncat(tmphlp,"\nor switch",sizeof(tmphlp));
14515 ckstrncat(tmphlp," ",sizeof(tmphlp));
14517 /* Set up first set of chained FDB's */
14519 cmfdbi(&sw, /* First FDB - command switches */
14520 _CMKEY, /* fcode */
14521 tmphlp, /* hlpmsg */
14522 "", /* default (none) */
14523 "", /* addtl string data */
14524 krb_s_n, /* Switch table size */
14525 4, /* addtl numeric data 2: 4 = cmswi */
14526 xxstring, /* Processing function */
14527 krb_s_tbl, /* Switch table */
14528 &kw /* Pointer to next FDB */
14530 cmfdbi(&kw, /* Second FDB - action keywords */
14531 _CMKEY, /* fcode */
14532 "Kerberos action", /* hlpmsg */
14533 "", /* default (none) */
14534 "", /* addtl string data */
14535 krb_a_n, /* Switch table size */
14536 0, /* addtl num data (0 = NOT switch) */
14537 xxstring, /* Processing function */
14538 krb_a_tbl, /* Keyword table */
14539 NULL /* Pointer to next FDB (none) */
14544 while (1) { /* Parse 0 or more switches */
14545 rc = cmfdb(&sw); /* Parse something */
14546 debug(F101,"kerberos cmfdb 1 rc","",rc);
14547 if (rc < 0) { /* Error */
14549 printf("?Action not specified - nothing happens.\n");
14550 return(rc); /* or reparse needed */
14552 if (cmresult.fdbaddr != &sw) /* Break out if not a switch */
14554 c = cmgbrk(); /* Have switch - get break character */
14555 getval = (c == ':' || c == '='); /* Must parse an agument? */
14556 if (getval && !(cmresult.kflags & CM_ARG)) {
14557 printf("?This switch does not take arguments\n");
14558 return(-9); /* OK because nothing malloc'd yet */
14560 if (!getval && (cmgkwflgs() & CM_ARG)) {
14561 printf("?This switch requires an argument\n");
14564 n = cmresult.nresult; /* Numeric result = switch value */
14565 debug(F101,"kerberos command switch","",n);
14567 switch (n) { /* Handle the switch */
14568 case KRB_S_CA: /* /CACHE:<filename> */
14569 p = krb5_d_cc ? krb5_d_cc : "";
14570 if ((y = cmofi("Name of cache file",p,&s,xxstring)) < 0) {
14576 makestr(&tmpcache,s);
14579 printf("?Unexpected switch value - internal error\n");
14580 return(-9); /* (if) nothing malloc'd yet. */
14583 if (cmresult.fdbaddr != &kw) { /* Checking... */
14584 printf("?Unexpected result - internal error\n");
14585 return(-9); /* Nothing malloc'd yet. */
14587 n = cmresult.nresult; /* Get keyword value */
14589 printf("?Unexpected Kerberos version - Internal error\n");
14592 debug(F101,"kerberos action","",n);
14594 case KRB_A_IN: /* INITIALIZE */
14595 case KRB_A_DE: /* DESTROY */
14596 case KRB_A_LC: /* LIST-CREDENTIALS */
14597 tmp_action = n; /* OK, set */
14599 default: /* Not OK, punt. */
14600 printf("?Unexpected action - internal error\n");
14603 if (tmp_action == KRB_A_IN) { /* Action is INITIALIZE */
14605 cmfdbi(&sw, /* INITIALIZE switches */
14606 _CMKEY, /* fcode */
14607 "Principal,\n or optional INITIALIZE switch(es)", /* hlpmsg */
14608 "", /* default (none) */
14609 "", /* addtl string data */
14610 kv == 4 ? krb4_i_n : krb5_i_n, /* Switch table size */
14611 4, /* addtl numeric data 2: 4 = cmswi */
14612 xxstring, /* Processing function */
14613 kv == 4 ? krb4_i_tbl : krb5_i_tbl, /* Switch table */
14614 &fl /* Pointer to next FDB */
14616 cmfdbi(&fl, /* 3rd FDB - command to send from */
14617 _CMFLD, /* fcode */
14618 "Principal", /* hlpmsg */
14619 kv == 4 ? krb4_d_principal : krb5_d_principal, /* principal */
14620 "", /* addtl string data */
14621 0, /* addtl numeric data 1 */
14622 0, /* addtl numeric data 2 */
14627 while (1) { /* Parse INIT switches or principal */
14629 debug(F101,"kerberos cmfdb 2 rc","",rc);
14632 printf("?Principal name required\n");
14635 debug(F101,"kerberos cmfdb 2 fcode","",cmresult.fcode);
14636 if (cmresult.fcode != _CMKEY) /* Not a switch, quit switch loop */
14638 c = cmgbrk(); /* Switch - get break character */
14639 debug(F101,"kerberos cmfdb 2 cmgbrk","",c);
14640 getval = (c == ':' || c == '=');
14641 if (getval && !(cmresult.kflags & CM_ARG)) {
14642 printf("?This switch does not take arguments\n");
14643 return(-9); /* OK because nothing malloc'd yet */
14645 if (!getval && (cmgkwflgs() & CM_ARG)) {
14646 printf("?This switch requires an argument\n");
14649 n = cmresult.nresult; /* Numeric result = switch value */
14651 /* These don't take args... */
14652 case KRB_I_PA: /* /PREAUTH */
14653 case KRB_I_FW: /* /FORWARDABLE */
14654 case KRB_I_PR: /* /PROXIABLE */
14655 case KRB_I_RN: /* /RENEW */
14656 case KRB_I_VA: /* /VALIDATE */
14657 case KRB_I_NPA: /* /NOT-PREAUTH */
14658 case KRB_I_NFW: /* /NOT-FORWARDABLE */
14659 case KRB_I_NPR: /* /NOT-PROXIABLE */
14660 case KRB_I_VB: /* /VERBOSE */
14661 case KRB_I_BR: /* /BRIEF */
14662 case KRB_I_K4: /* /KERBEROS4 */
14663 case KRB_I_NK4: /* /NO-KERBEROS4 */
14664 case KRB_I_POP: /* /POPUP */
14665 case KRB_I_NAD: /* /NO-ADDRESSES */
14667 printf("?This switch does not take a value\n");
14673 pv[KRB_I_PA].ival = 0;
14676 pv[KRB_I_FW].ival = 0;
14679 pv[KRB_I_PR].ival = 0;
14682 pv[KRB_I_BR].ival = 0;
14685 pv[KRB_I_K4].ival = 0;
14692 /* These do take arguments */
14694 case KRB_I_RB: /* /RENEWABLE:<minutes> */
14696 if (!getval) break;
14697 if ((rc = cmnum("Minutes",ckitoa(krb5_init.renewable),
14698 10,&y, xxstring)) < 0)
14703 case KRB_I_LF: /* /LIFETIME:<minutes> */
14705 /* Default is previous value */
14706 sprintf(tmpbuf,"%d", /* SAFE */
14708 krb4_init.lifetime :
14711 if (!getval) break;
14712 if ((rc = cmnum("Minutes",tmpbuf,10,&y, xxstring)) < 0)
14717 case KRB_I_PD: /* /POSTDATE:<timestamp> */
14722 if (!getval) break;
14723 if ((rc = cmdate("date-time","",&s,0,xxstring)) < 0)
14725 makestr(&(pv[n].sval),s);
14728 case KRB_I_SR: /* /SERVICE:<name> */
14733 if (!getval) break;
14734 if ((rc = cmfld("Service-name","",&s,xxstring)) < 0)
14736 makestr(&(pv[n].sval),s);
14739 case KRB_I_RL: /* /REALM:<name> */
14744 if (!getval) break;
14746 p = krb4_d_realm ? krb4_d_realm : "";
14748 p = krb5_d_realm ? krb5_d_realm : "";
14749 if ((rc = cmfld("Realm",p,&s,xxstring)) < 0)
14751 makestr(&(pv[n].sval),s);
14754 case KRB_I_IN: /* /INSTANCE:<name> */
14759 if (!getval) break;
14761 p = krb4_d_instance ? krb4_d_instance : "";
14763 p = krb5_d_instance ? krb5_d_instance : "";
14764 if ((rc = cmfld("Instance",p,&s,xxstring)) < 0)
14766 makestr(&(pv[n].sval),s);
14769 case KRB_I_PW: /* /PASSWORD:<password> */
14775 if (!getval) break;
14776 if ((rc = cmfld("Password","",&s,xxstring)) < 0)
14779 makestr(&(pv[n].sval),s);
14782 case KRB_I_ADR: /* /ADDRESSES:{<address-list>} */
14787 if (!getval) break;
14788 if ((rc = cmfld("List of IP addresses","",&s,xxstring)) < 0)
14790 makelist(s,tmpaddrs,KRB5_NUM_OF_ADDRS);
14791 for (i = 0; i < KRB5_NUM_OF_ADDRS && tmpaddrs[i]; i++) {
14792 if (inet_addr(tmpaddrs[i]) == 0xffffffff) {
14793 printf("invalid ip address: %s\n",tmpaddrs[i]);
14798 pv[KRB_I_NAD].ival = 0;
14802 printf("?Unexpected switch value - internal error\n");
14807 if (cmresult.fcode != _CMFLD) {
14808 printf("?Unexected result - internal error\n");
14812 /* cmresult.sresult may be of the form PRINCIPAL@REALM */
14813 i = ckindex("@",cmresult.sresult,0,0,0);
14815 makestr(&tmprealm,&cmresult.sresult[i]);
14816 cmresult.sresult[i-1] = '\0';
14818 makestr(&tmpprinz,cmresult.sresult); /* Principal (user) */
14820 if ((rc = cmcfm()) < 0) { /* Now get confirmation */
14822 printf("?Principal name required\n");
14826 if (!tmpprinz || !tmpprinz[0]) {
14827 printf("?Principal name required\n");
14830 if (!pv[KRB_I_RN].ival && !pv[KRB_I_VA].ival) {
14831 /* Don't use a password if Validating or Renewing */
14832 if (pv[KRB_I_PW].sval) { /* If they gave a /PASSWORD switch */
14833 makestr(&tmppswd,pv[KRB_I_PW].sval); /* use this value */
14836 /* Password prompting has been moved to ck_krb[45]_initTGT() */
14837 else { /* Otherwise must prompt for it */
14839 if (pv[KRB_I_RL].sval)
14840 sprintf(prmpt,"%s@%s's Password: ",
14841 tmpprinz,pv[KRB_I_RL].sval);
14843 sprintf(prmpt,"%s@%s's Password: ",
14844 tmpprinz,tmprealm);
14846 sprintf(prmpt,"%s's Password: ",tmpprinz);
14848 if (pv[KRB_I_POP].ival) {
14849 char passwd[80]="";
14850 readpass(prmpt,passwd,80);
14851 makestr(&tmppswd,passwd);
14852 memset(passwd,0,80);
14858 #endif /* CK_RECALL */
14859 cmsavp(psave,PROMPTL); /* Save old prompt */
14860 cmsetp(prmpt); /* Make new prompt */
14861 concb((char)escape); /* Put console in cbreak mode */
14862 cmini(0); /* and no-echo mode */
14863 /* Issue prompt if at top level */
14864 if (pflag) prompt(xxstring);
14865 cmres(); /* Reset the parser */
14866 for (rc = -1; rc < 0; ) { /* Prompt till they answer */
14867 /* Get a literal line of text */
14868 rc = cmtxt("","",&s,NULL);
14869 cmres(); /* Reset the parser again */
14871 makestr(&tmppswd,s);
14872 printf("\n"); /* Echo a CRLF */
14873 cmsetp(psave); /* Restore original prompt */
14876 x = 0; /* Check for password */
14881 printf("?Password required\n");
14884 #endif /* COMMENT */
14886 } else if (kv == 5 && tmp_action == KRB_A_LC) { /* LIST-CREDENTIALS */
14889 if ((x = cmkey(klctab,nklctab,"Switch","",xxstring)) < 0) {
14891 if ((rc = cmcfm()) < 0)
14902 } else if ((rc = cmcfm()) < 0) /* DESTROY, just confirm */
14905 /* Done - Move confirmed data to final locations */
14907 krb_action = tmp_action; /* Action requested */
14908 krb_op.version = kv; /* Kerberos version */
14909 krb_op.cache = tmpcache; /* Cache file */
14910 tmpcache = NULL; /* So we don't free it */
14912 switch (krb_action) {
14913 case KRB_A_IN: /* INITIALIZE */
14915 krb5_init.forwardable = pv[KRB_I_FW].ival;
14916 krb5_init.proxiable = pv[KRB_I_PR].ival;
14917 krb5_init.lifetime = pv[KRB_I_LF].ival;
14918 krb5_init.renew = pv[KRB_I_RN].ival;
14919 krb5_init.renewable = pv[KRB_I_RB].ival;
14920 krb5_init.validate = pv[KRB_I_VA].ival;
14922 /* Here we just reassign the pointers and then set them to NULL */
14923 /* so they won't be freed below. */
14925 krb5_init.postdate = pv[KRB_I_PD].sval; pv[KRB_I_PD].sval = NULL;
14926 krb5_init.service = pv[KRB_I_SR].sval; pv[KRB_I_SR].sval = NULL;
14927 if (pv[KRB_I_RL].sval) {
14928 krb5_init.realm = pv[KRB_I_RL].sval; pv[KRB_I_RL].sval = NULL;
14929 } else if (tmprealm) {
14930 krb5_init.realm = tmprealm; tmprealm = NULL;
14932 if (pv[KRB_I_IN].sval) {
14933 krb5_init.instance = pv[KRB_I_IN].sval;
14934 pv[KRB_I_IN].sval = NULL;
14935 } else if ( tmpinst ) {
14936 krb5_init.instance = tmpinst;
14940 krb5_init.principal = tmpprinz;
14943 krb5_init.password = tmppswd;
14946 krb5_init.getk4 = pv[KRB_I_K4].ival;
14947 if (krb5_init.getk4) {
14948 krb4_init.lifetime = pv[KRB_I_LF].ival;
14949 if (krb5_init.realm)
14950 makestr(&krb4_init.realm,krb5_init.realm);
14951 krb4_init.preauth = krb4_d_preauth;
14952 krb4_init.verbose = pv[KRB_I_BR].ival ? 0 : 1;
14953 if (krb5_init.principal)
14954 makestr(&krb4_init.principal,krb5_init.principal);
14955 if (krb5_init.principal)
14956 makestr(&krb4_init.password,krb5_init.password);
14958 krb5_init.no_addresses = pv[KRB_I_NAD].ival;
14960 for (i = 0; i < KRB5_NUM_OF_ADDRS; i++) {
14961 if (krb5_init.addrs[i]) {
14962 free(krb5_init.addrs[i]);
14963 krb5_init.addrs[i] = NULL;
14965 krb5_init.addrs[i] = tmpaddrs[i];
14966 tmpaddrs[i] = NULL;
14969 } else if (kv == 4) { /* Same deal for Kerberos 4 */
14970 krb4_init.lifetime = pv[KRB_I_LF].ival;
14971 if (pv[KRB_I_RL].sval) {
14972 krb4_init.realm = pv[KRB_I_RL].sval;
14973 pv[KRB_I_RL].sval = NULL;
14974 } else if ( tmprealm ) {
14975 krb4_init.realm = tmprealm;
14978 if (pv[KRB_I_IN].sval) {
14979 krb4_init.instance = pv[KRB_I_IN].sval;
14980 pv[KRB_I_IN].sval = NULL;
14981 } else if ( tmpinst ) {
14982 krb4_init.instance = tmpinst;
14985 krb4_init.preauth = pv[KRB_I_PA].ival;
14986 krb4_init.verbose = pv[KRB_I_BR].ival ? 0 : 1;
14989 krb4_init.principal = tmpprinz;
14992 krb4_init.password = tmppswd;
14996 case KRB_A_LC: /* List Credentials */
14997 krb5_lc.encryption = tmp_klc & XYKLCEN;
14998 krb5_lc.flags = tmp_klc & XYKLCFL;
14999 krb5_lc.addr = tmp_klc & XYKLCAD;
15003 /* Common exit - Free temporary storage */
15006 for (i = 0; i <= KRB_I_MAX; i++) { /* Free malloc'd switch data */
15010 for (i = 0; i < KRB5_NUM_OF_ADDRS; i++) {
15014 if (tmpprinz) free(tmpprinz); /* And these too. */
15015 if (tmppswd) free(tmppswd);
15016 if (tmpcache) free(tmpcache);
15017 if (tmprealm) free(tmprealm);
15018 if (tmpinst) free(tmpinst);
15020 return(rc); /* Return the return code */
15022 #endif /* CK_KERBEROS */
15027 ckxlogin(CHAR * userid, CHAR * passwd, CHAR * acct, int promptok)
15028 #else /* CK_ANSIC */
15029 ckxlogin(userid, passwd, acct, promptok)
15030 CHAR * userid; CHAR * passwd; CHAR * acct; int promptok;
15031 #endif /* CK_ANSIC */
15034 extern int on_recall; /* around Password prompting */
15035 #endif /* CK_RECALL */
15038 #endif /* COMMENT */
15039 int rprompt = 0; /* Restore prompt */
15042 #endif /* CKSYSLOG */
15044 extern int what, srvcdmsg;
15046 int x = 0, ok = 0, rc = 0;
15047 CHAR * _u = NULL, * _p = NULL, * _a = NULL;
15049 debug(F111,"ckxlogin userid",userid,promptok);
15050 debug(F110,"ckxlogin passwd",passwd,0);
15052 isguest = 0; /* Global "anonymous" flag */
15054 if (!userid) userid = (CHAR *)"";
15055 if (!passwd) passwd = (CHAR *)"";
15057 debug(F111,"ckxlogin userid",userid,what);
15061 #endif /* CK_RECALL */
15064 savlog = ckxsyslog; /* Save and turn off syslogging */
15065 #endif /* CKSYSLOG */
15067 if ((!*userid || !*passwd) && /* Need to prompt for missing info */
15069 cmsavp(psave,PROMPTL); /* Save old prompt */
15070 debug(F110,"ckxlogin saved",psave,0);
15076 cmsetp("Username: "); /* Make new prompt */
15077 concb((char)escape); /* Put console in cbreak mode */
15080 /* Flush typeahead */
15084 "ckxlogin TELOPT_SB(TELOPT_KERMIT).kermit.me_start",
15086 TELOPT_SB(TELOPT_KERMIT).kermit.me_start
15088 #endif /* IKS_OPTION */
15090 while (ttchk() > 0) {
15092 debug(F101,"ckxlogin flush user x","",x);
15094 doexit(GOOD_EXIT,0); /* Connection lost */
15098 x = tn_doop((CHAR)(x & 0xff),ckxech,ttinc);
15099 debug(F101,"ckxlogin user tn_doop","",x);
15102 "ckxlogin user TELOPT_SB(TELOPT_KERMIT).kermit.me_start",
15104 TELOPT_SB(TELOPT_KERMIT).kermit.me_start
15106 #endif /* IKS_OPTION */
15111 case 1: ckxech = 1; break; /* Turn on echoing */
15112 case 2: ckxech = 0; break; /* Turn off echoing */
15114 case 4: /* IKS event */
15115 if (!TELOPT_SB(TELOPT_KERMIT).kermit.me_start)
15116 break; /* else fall thru... */
15117 #endif /* IKS_OPTION */
15118 case 6: /* Logout */
15123 #endif /* TNCODE */
15125 if (pflag) prompt(xxstring); /* Issue prompt if at top level */
15126 cmres(); /* Reset the parser */
15127 for (x = -1; x < 0;) { /* Prompt till they answer */
15128 /* Get a literal line of text */
15129 x=cmtxt("Your username, or \"ftp\", or \"anonymous\"","",&s,NULL);
15130 if (x == -4 || x == -10) {
15131 printf("\r\n%sLogin cancelled\n",
15132 x == -10 ? "Timed out: " : "");
15134 ckxsyslog = savlog;
15135 #endif /* CKSYSLOG */
15136 doexit(GOOD_EXIT,0);
15138 if (sstate) /* Did a packet come instead? */
15140 cmres(); /* Reset the parser again */
15142 if ((_u = (CHAR *)malloc((int)strlen(s) + 1)) == NULL) {
15143 printf("?Internal error: malloc\n");
15146 strcpy((char *)_u,s); /* safe */
15150 ok = zvuser((char *)userid); /* Verify username */
15151 debug(F111,"ckxlogin zvuser",userid,ok);
15153 if (!*passwd && promptok
15156 #endif /* COMMENT */
15161 savlog = ckxsyslog; /* Save and turn off syslogging */
15163 #endif /* CKSYSLOG */
15165 /* Flush typeahead again */
15167 while (ttchk() > 0) {
15169 debug(F101,"ckxlogin flush user x","",x);
15173 x = tn_doop((CHAR)(x & 0xff),ckxech,ttinc);
15174 debug(F101,"ckxlogin pass tn_doop","",x);
15177 "ckxlogin pass TELOPT_SB(TELOPT_KERMIT).kermit.me_start",
15179 TELOPT_SB(TELOPT_KERMIT).kermit.me_start
15181 #endif /* IKS_OPTION */
15185 case 1: ckxech = 1; break; /* Turn on echoing */
15186 case 2: ckxech = 0; break; /* Turn off echoing */
15187 case 4: /* IKS event */
15188 if (!TELOPT_SB(TELOPT_KERMIT).kermit.me_start)
15189 break; /* else fall thru... */
15190 case 6: /* Logout */
15195 #endif /* TNCODE */
15197 if (!strcmp((char *)userid,"anonymous") ||
15198 !strcmp((char *)userid,"ftp")) {
15201 ckstrncpy(prmpt,"Enter e-mail address as Password: ",80);
15202 } else if (*userid && strlen((char *)userid) < 60) {
15204 extern CHAR * pReferenceDomainName;
15205 if (pReferenceDomainName)
15209 pReferenceDomainName,
15213 NULL,NULL,NULL,NULL,NULL,NULL,NULL
15217 ckmakmsg(prmpt,80,"Enter ",(char *)userid,"'s Password: ",NULL);
15219 ckstrncpy(prmpt,"Enter Password: ",80);
15220 cmsetp(prmpt); /* Make new prompt */
15221 concb((char)escape); /* Put console in cbreak mode */
15222 if (strcmp((char *)userid,"anonymous") &&
15223 strcmp((char *)userid,"ftp")) { /* and if not anonymous */
15225 cmini(0); /* and no-echo mode */
15229 if (pflag) prompt(xxstring); /* Issue prompt if at top level */
15230 cmres(); /* Reset the parser */
15231 for (x = -1; x < 0;) { /* Prompt till they answer */
15234 #endif /* CK_PAM */
15235 x = cmtxt("","",&s,NULL); /* Get a literal line of text */
15236 if (x == -4 || x == -10) {
15237 printf("\r\n%sLogin cancelled\n",
15238 x == -10 ? "Timed out: " : "");
15240 ckxsyslog = savlog;
15241 #endif /* CKSYSLOG */
15242 doexit(GOOD_EXIT,0);
15246 gotemptypasswd = 1;
15247 #endif /* CK_PAM */
15248 if (sstate) /* In case of a Kermit packet */
15250 cmres(); /* Reset the parser again */
15252 printf("\r\n"); /* Echo a CRLF */
15253 if ((_p = (CHAR *)malloc((int)strlen(s) + 1)) == NULL) {
15254 printf("?Internal error: malloc\n");
15257 strcpy((char *)_p,s); /* safe */
15263 cmres(); /* Reset the parser */
15265 /* We restore the prompt now because the PAM engine will call */
15266 /* readpass() which will overwrite psave. */
15268 cmsetp(psave); /* Restore original prompt */
15269 debug(F110,"ckxlogin restored",psave,0);
15273 #endif /* CK_PAM */
15276 ckxsyslog = savlog;
15277 #endif /* CKSYSLOG */
15280 ok = zvpass((char *)passwd); /* Check password */
15281 debug(F101,"ckxlogin zvpass","",ok);
15284 /* Fake pam password failure for nonexistent users */
15286 printf("Authentication failure\n");
15287 #endif /* CK_PAM */
15290 if (ok > 0 && isguest) {
15293 #endif /* NOPUSH */
15296 rc = ok; /* Set the return code */
15297 if ((char *)uidbuf != (char *)userid)
15298 ckstrncpy(uidbuf,(char *)userid,UIDBUFLEN); /* Remember username */
15300 XCKXLOG: /* Common exit */
15302 ckxsyslog = savlog; /* In case of GOTO above */
15303 #endif /* CKSYSLOG */
15305 cmsetp(psave); /* Restore original prompt */
15306 debug(F110,"ckxlogin restored",psave,0);
15308 if (_u || _p || _a) {
15318 doexit(GOOD_EXIT,0); /* doexit calls zvlogout */
15319 return(0); /* not reached */
15321 #endif /* CK_LOGIN */