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, 2004,
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)
71 #ifdef CK_AUTHENTICATION
73 #endif /* CK_AUTHENTICATION */
79 #endif /* SSHBUILTIN */
80 #ifdef STRATUS /* Stratus Computer, Inc. VOS */
84 #define putchar(x) conoc(x)
88 #define getchar(x) coninc(0)
93 static int x, y = 0, z;
97 extern int g_matchdot, hints, xcmdsrc, rcdactive;
99 extern char * k_info_dir;
103 int gotemptypasswd = 0; /* distinguish empty passwd from none given */
105 #endif /* CK_LOGIN */
109 extern struct mtab *mactab;
114 extern short ctlp[]; /* Control-char prefixing table */
115 #endif /* CK_SPEED */
118 extern char * sndfilter, * g_sfilter;
119 extern char * rcvfilter, * g_rfilter;
120 #endif /* PIPESEND */
122 extern char * snd_move;
123 extern char * snd_rename;
124 extern char * g_snd_move;
125 extern char * g_snd_rename;
126 extern char * rcv_move;
127 extern char * rcv_rename;
128 extern char * g_rcv_move;
129 extern char * g_rcv_rename;
132 extern char *binpatterns[], *txtpatterns[];
134 #endif /* PATTERNS */
136 extern char * remdest;
139 #endif /* CK_TMPDIR */
141 extern struct ck_p ptab[];
143 extern int protocol, remfile, rempipe, remappd, reliable, xreliable, fmask,
144 fncnv, frecl, maxrps, wslotr, bigsbsiz, bigrbsiz, urpsiz, rpsiz, spsiz,
145 bctr, npad, timef, timint, spsizr, spsizf, maxsps, spmax, nfils, displa,
146 atcapr, pkttim, rtimo, fncact, mypadn, fdispla, f_save, pktpaus, setreliable,
147 fnrpath, fnspath, atenci, atenco, atdati, atdato, atleni, atleno, atblki,
148 atblko, attypi, attypo, atsidi, atsido, atsysi, atsyso, atdisi, atdiso;
152 extern int atfrmi, atfrmo;
154 extern int atcrei, atcreo, atacti, atacto;
157 extern int atlpri, atlpro, atgpri, atgpro;
158 #endif /* CK_PERMS */
161 sstate, eol, seol, stchr, mystch, mypadc, padch, ctlq, myctlq;
167 #endif /* IKSDCONF */
170 extern char *cmarg, *cmarg2;
173 extern char optbuf[]; /* Buffer for MAIL or PRINT options */
174 extern int rprintf; /* REMOTE PRINT flag */
175 #endif /* NOFRILLS */
179 extern char * tt_trigger[];
180 #endif /* CK_TRIGGER */
182 extern int tcs_transp;
184 extern int tt_pcterm;
192 int sl_ssh_xfw_saved = 0;
194 int sl_ssh_ver_saved = 0;
195 #endif /* SSHBUILTIN */
197 #ifdef CK_AUTHENTICATION
198 extern int auth_type_user[];
199 int sl_auth_type_user[AUTHTYPLSTSZ] = {AUTHTYPE_NULL, AUTHTYPE_NULL};
200 int sl_auth_saved = 0;
201 int sl_topt_a_su = 0;
202 int sl_topt_a_s_saved = 0;
203 int sl_topt_a_cm = 0;
204 int sl_topt_a_c_saved = 0;
205 #endif /* CK_AUTHENTICATION */
210 int sl_topt_e_su = 0;
211 int sl_topt_e_sm = 0;
212 int sl_topt_e_s_saved = 0;
213 int sl_topt_e_cu = 0;
214 int sl_topt_e_cm = 0;
215 int sl_topt_e_c_saved = 0;
216 #endif /* CK_ENCRYPTION */
217 extern char uidbuf[];
218 static int uidflag = 0;
219 char sl_uidbuf[UIDBUFLEN] = { NUL, NUL };
220 int sl_uid_saved = 0;
227 extern int tn_wait_flg;
232 #ifdef CK_AUTHENTICATION
235 for (x = 0; x < AUTHTYPLSTSZ; x++)
236 auth_type_user[x] = sl_auth_type_user[x];
239 if (sl_topt_a_s_saved) {
240 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = sl_topt_a_su;
241 sl_topt_a_s_saved = 0;
243 if (sl_topt_a_c_saved) {
244 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = sl_topt_a_cm;
245 sl_topt_a_c_saved = 0;
247 #endif /* CK_AUTHENTICATION */
250 cx_type = sl_cx_type;
253 if (sl_topt_e_s_saved) {
254 TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = sl_topt_e_su;
255 TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = sl_topt_e_sm;
256 sl_topt_e_s_saved = 0;
258 if (sl_topt_e_c_saved) {
259 TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = sl_topt_e_cu;
260 TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = sl_topt_e_cm;
261 sl_topt_e_c_saved = 0;
263 #endif /* CK_ENCRYPTION */
265 ckstrncpy(uidbuf,sl_uidbuf,UIDBUFLEN);
270 tn_wait_flg = sl_tn_wait;
275 if (sl_ssh_xfw_saved) {
276 ssh_xfw = sl_ssh_xfw;
277 sl_ssh_xfw_saved = 0;
279 if (sl_ssh_ver_saved) {
280 ssh_ver = sl_ssh_ver;
281 sl_ssh_ver_saved = 0;
283 #endif /* SSHBUILTIN */
286 int oldplex = -1; /* Duplex holder around network */
290 extern int locus, autolocus;
296 /* Note: gcc -Wall wants braces around each keyword table entry. */
298 static struct keytab psltab[] = { /* SET LINE/PORT command options */
299 { "/connect", SL_CNX, 0 },
301 { "/noshare", SL_NSH, 0 },
302 #endif /* OS2ORVMS */
303 { "/server", SL_SRV, 0 },
305 { "/share", SL_SHR, 0 },
306 #endif /* OS2ORVMS */
309 static int npsltab = sizeof(psltab)/sizeof(struct keytab) - 1;
312 static struct keytab shtab[] = { /* SET HOST command options */
314 /* (COMMAND is also a network type) */
315 { "/command", SL_CMD, CM_INV },
317 { "/connect", SL_CNX, 0 },
318 { "/network-type", SL_NET, CM_ARG },
319 { "/nowait", SL_NOWAIT, 0 },
321 #ifdef CK_AUTHENTICATION
322 { "/password", SL_PSW, CM_ARG },
323 #endif /* CK_AUTHENTICATION */
326 { "/pipe", SL_CMD, 0 },
329 { "/pty", SL_PTY, 0 },
331 { "/server", SL_SRV, 0 },
332 { "/timeout", SL_TMO, CM_ARG },
333 { "/userid", SL_UID, CM_ARG },
334 { "/wait", SL_WAIT, 0 },
337 static int nshtab = sizeof(shtab)/sizeof(struct keytab) - 1;
339 static struct keytab shteltab[] = { /* TELNET command options */
340 #ifdef CK_AUTHENTICATION
341 { "/auth", SL_AUTH, CM_ARG },
342 #endif /* CK_AUTHENTICATION */
344 { "/encrypt", SL_ENC, CM_ARG },
345 #endif /* CK_ENCRYPTION */
346 { "/nowait", SL_NOWAIT, 0 },
348 #ifdef CK_AUTHENTICATION
349 { "/password", SL_PSW, CM_ARG },
350 #endif /* CK_AUTHENTICATION */
352 { "/timeout", SL_TMO, CM_ARG },
353 { "/userid", SL_UID, CM_ARG },
354 { "/wait", SL_WAIT, 0 },
357 static int nshteltab = sizeof(shteltab)/sizeof(struct keytab) - 1;
360 static struct keytab shrlgtab[] = { /* SET HOST RLOGIN command options */
363 { "/encrypt", SL_ENC, 0 },
364 #endif /* CK_ENCRYPTION */
365 { "/k4", SL_KRB4, CM_INV },
366 { "/k5", SL_KRB5, CM_INV },
367 { "/kerberos4", SL_KRB4, 0 },
368 { "/kerberos5", SL_KRB5, 0 },
369 { "/kerberos_iv", SL_KRB4, CM_INV },
370 { "/kerberos_v", SL_KRB5, CM_INV },
371 { "/krb4", SL_KRB4, CM_INV },
372 { "/krb5", SL_KRB5, CM_INV },
373 #endif /* CK_KERBEROS */
376 static int nshrlgtab = sizeof(shrlgtab)/sizeof(struct keytab)-1;
377 #endif /* RLOGCODE */
379 extern struct keytab netcmd[];
383 extern int nnetdir; /* Network services directory */
384 extern char *netdir[];
385 _PROTOTYP( VOID ndreset, (void) );
386 char *nh_p[MAXDNUMS + 1]; /* Network directory entry pointers */
387 char *nh_p2[MAXDNUMS + 1]; /* Network directory entry nettype */
388 char *nh_px[4][MAXDNUMS + 1]; /* Network-specific stuff... */
392 char * n_name = NULL; /* Network name pointer */
395 _PROTOTYP(int remtxt, (char **) );
396 _PROTOTYP(VOID rmsg, (void) );
397 _PROTOTYP(static int remcfm, (void) );
401 int mdmsav = -1; /* Save modem type around network */
402 extern int isguest; /* Global flag for anonymous login */
404 extern xx_strp xxstring;
406 extern int success, binary, b_save, ckwarn, msgflg, quiet, cmask, pflag, local,
407 nettype, escape, mdmtyp, duplex, dfloc, network, cdtimo, autoflow, tnlm,
408 sosi, tlevel, lf_opts, backgrd, flow, debses, parity, ttnproto, ckxech,
409 x_ifnum, cmflgs, haveline, cxtype, cxflow[], maclvl;
412 extern struct cmdptr *cmdstk; /* The command stack itself */
414 extern struct cmdptr cmdstk[]; /* The command stack itself */
416 extern FILE * tfile[];
417 extern char * macp[];
419 extern char psave[]; /* For saving & restoring prompt */
420 extern int sprmlen, rprmlen;
423 static struct keytab strmkeytab[] = {
427 static int nstrmkeytab = sizeof(strmkeytab)/sizeof(struct keytab);
429 static struct keytab strmswitab[] = {
432 static int nstrmswitab = sizeof(strmswitab)/sizeof(struct keytab);
434 static struct keytab normrev[] = {
435 { "dark-display", 0, 0 },
436 { "light-display", 1, 0 },
441 static struct keytab prnmtab[] = {
445 { "on", 1, CM_INV }, /* Compatibility with XPRINT version */
447 { "transparent", 3, CM_INV } /* not really transparent */
449 static int nprnmtab = sizeof(prnmtab)/sizeof(struct keytab);
451 extern int tt_diff_upd;
454 #define stricmp _stricmp
455 extern int tt_attr_bug;
457 extern int tt_rows[], tt_cols[];
458 extern int tt_cols_usr;
459 extern int tt_szchng[VNUM];
460 int tt_modechg = TVC_ENA;
461 extern int tt_url_hilite, tt_url_hilite_attr;
462 extern struct _vtG G[4];
465 int send_c1_usr = FALSE;
466 extern int sgrcolors;
467 extern int marginbell, marginbellcol;
468 extern int autoscroll, wy_autopage;
470 extern int dec_nrc, dec_lang, dec_kbd;
472 extern int tt_rows, tt_cols;
475 extern int tt_escape;
480 extern char *tp, *lp; /* Temporary buffer & pointers */
481 extern char ttname[];
484 int tttapi = 0; /* is Line TAPI? */
485 struct keytab * tapilinetab = NULL;
486 struct keytab * _tapilinetab = NULL;
490 #ifdef NETCONN /* Network items */
493 extern int revcall, closgr, cudata, nx25;
495 extern struct keytab x25tab[];
498 extern CHAR padparms[];
499 extern struct keytab padx3tab[];
506 extern bool ttslip,ttppp;
510 extern char pipename[];
514 static struct keytab tcprawtab[] = { /* SET HOST options */
515 { "/default", NP_DEFAULT, CM_INV },
516 #ifdef CK_AUTHENTICATION
519 { "/ek4login", NP_EK4LOGIN, 0 },
520 { "/ek5login", NP_EK5LOGIN, 0 },
521 { "/k4login", NP_K4LOGIN, 0 },
522 { "/k5login", NP_K5LOGIN, 0 },
523 #endif /* RLOGCODE */
525 { "/k5user2user", NP_K5U2U, 0 },
526 #endif /* KRB5_U2U */
527 #endif /* CK_KERBEROS */
528 #endif /* CK_AUTHENTICATION */
529 { "/no-telnet-init", NP_NONE, 0 },
530 { "/none", NP_NONE, CM_INV },
531 { "/raw-socket", NP_TCPRAW, 0 },
533 { "/rlogin", NP_RLOGIN, 0 },
534 #endif /* RLOGCODE */
536 { "/ssl", NP_SSL, 0 },
537 { "/ssl-telnet", NP_SSL_TELNET, 0 },
539 { "/telnet", NP_TELNET, 0 },
541 { "/tls", NP_TLS, 0 },
542 { "/tls-telnet", NP_TLS_TELNET, 0 },
546 static int ntcpraw = (sizeof(tcprawtab) / sizeof(struct keytab)) - 1;
549 _PROTOTYP( int rlog_naws, (void) );
550 #endif /* RLOGCODE */
551 #endif /* TCPSOCKET */
554 extern char slat_pwd[18];
555 #endif /* SUPERLAT */
562 #define mapkey(x) keymap[x]
564 extern MACRO *macrotab;
566 extern struct keytab kverbs[];
568 #endif /* NOKVERBS */
569 #endif /* NOSETKEY */
573 extern MACRO *macrotab;
575 extern struct keytab kverbs[];
577 #endif /* NOKVERBS */
578 #endif /* NOSETKEY */
581 #ifdef OS2 /* AUTODOWNLOAD parameters */
582 extern int adl_kmode, adl_zmode; /* Match Packet to signal download */
583 extern char * adl_kstr; /* KERMIT Download String */
584 extern char * adl_zstr; /* ZMODEM Download String */
585 extern int adl_kc0, adl_zc0; /* Process ADL C0s in emulation */
588 /* Keyword tables ... */
590 extern struct keytab onoff[], rltab[];
594 static struct keytab fdfltab[] = {
595 { "7bit-character-set", 7, 0 },
596 { "8bit-character-set", 8, 0 }
598 static int nfdflt = (sizeof(fdfltab) / sizeof(struct keytab));
601 /* SET FILE parameters */
603 static struct keytab filtab[] = {
606 { "binary-patterns", XYFIBP, 0 },
607 #endif /* PATTERNS */
608 { "bytesize", XYFILS, 0 },
610 { "character-set", XYFILC, 0 },
612 { "collision", XYFILX, 0 },
613 { "default", XYF_DFLT, 0 },
614 { "destination", XYFILY, 0 },
615 { "display", XYFILD, CM_INV },
617 { "download-directory", XYFILG, 0 },
618 #endif /* CK_TMPDIR */
620 { "end-of-line", XYFILA, 0 },
621 { "eol", XYFILA, CM_INV },
623 { "eof", XYFILV, 0 },
624 #endif /* CK_CTRLZ */
626 { "fastlookups", 9997, CM_INV },
627 { "incomplete", XYFILI, 0 },
629 { "inspection", XYF_INSP, CM_INV },
630 #endif /* datageneral */
632 { "label", XYFILL, 0 },
633 #endif /* CK_LABELED */
637 { "listsize", XYF_LSIZ, 0 },
641 { "names", XYFILN, 0 },
643 { "output", XYFILH, 0 },
646 { "patterns", XYFIPA, 0 },
647 #endif /* PATTERNS */
648 #ifdef COMMENT /* Not implemented (but see CHMOD) */
649 { "permissions", XYF_PRM, CM_INV },
650 { "protection", XYF_PRM, 0 },
653 { "record-length", XYFILR, 0 },
656 { "scan", XYF_INSP, 0 },
657 #endif /* datageneral */
661 { "stringspace", XYF_SSPA, 0 },
666 { "t", XYFILT, CM_INV|CM_ABR },
667 { "text-patterns", XYFITP, 0 },
668 #endif /* PATTERNS */
670 { "type", XYFILT, 0 },
672 { "ucs", XYFILU, 0 },
675 { "warning", XYFILW, CM_INV }
678 static int nfilp = (sizeof(filtab) / sizeof(struct keytab));
680 struct keytab pathtab[] = {
681 { "absolute", PATH_ABS, 0 },
682 { "none", PATH_OFF, CM_INV },
683 { "off", PATH_OFF, 0 },
684 { "on", PATH_ABS, CM_INV },
685 { "relative", PATH_REL, 0 }
687 int npathtab = (sizeof(pathtab) / sizeof(struct keytab));
689 struct keytab rpathtab[] = {
690 { "absolute", PATH_ABS, 0 },
691 { "auto", PATH_AUTO, 0 },
692 { "none", PATH_OFF, CM_INV },
693 { "off", PATH_OFF, 0 },
694 { "on", PATH_ABS, CM_INV },
695 { "relative", PATH_REL, 0 }
697 int nrpathtab = (sizeof(rpathtab) / sizeof(struct keytab));
700 struct keytab eoftab[] = { /* EOF detection method */
703 { "noctrl-z", 0, CM_INV }
705 #endif /* CK_CTRLZ */
707 struct keytab fttab[] = { /* File types for SET FILE TYPE */
708 { "ascii", XYFT_T, CM_INV },
710 { "b", XYFT_B, CM_INV|CM_ABR },
712 { "binary", XYFT_B, 0 },
714 { "block", XYFT_I, CM_INV },
715 { "image", XYFT_I, 0 },
718 { "labeled", XYFT_L, 0 },
719 #endif /* CK_LABELED */
721 { "macbinary", XYFT_M, 0 },
723 { "text", XYFT_T, 0 }
725 int nfttyp = (sizeof(fttab) / sizeof(struct keytab));
727 static struct keytab rfttab[] = { /* File types for REMOTE SET FILE */
728 { "ascii", XYFT_T, CM_INV },
729 { "binary", XYFT_B, 0 },
731 { "labeled", XYFT_L, 0 },
734 { "labeled", XYFT_L, 0 },
737 { "text", XYFT_T, 0 }
739 static int nrfttyp = (sizeof(rfttab) / sizeof(struct keytab));
746 static struct keytab zoftab[] = {
747 { "blocking", ZOF_BLK, 0 },
748 { "buffered", ZOF_BUF, 0 },
749 { "nonblocking", ZOF_NBLK, 0 },
750 { "unbuffered", ZOF_NBUF, 0 }
752 static int nzoftab = (sizeof(zoftab) / sizeof(struct keytab));
753 #endif /* OS2ORUNIX */
755 extern int query; /* Global flag for QUERY active */
759 static struct keytab vartyp[] = { /* Variable types for REMOTE QUERY */
760 { "global", (int) 'G', CM_INV },
761 { "kermit", (int) 'K', 0 },
762 { "system", (int) 'S', 0 },
763 { "user", (int) 'G', 0 }
765 static int nvartyp = (sizeof(vartyp) / sizeof(struct keytab));
770 static struct keytab timotab[] = { /* Timer types */
774 #endif /* CK_TIMERS */
777 extern char *atxbuf, *atmbuf; /* Atom buffer */
778 extern char *cmdbuf; /* Command buffer */
779 extern char *line, *tmpbuf; /* Character buffers for anything */
780 extern int *intime; /* INPUT TIMEOUT */
782 #else /* Not DCMDBUF ... */
784 extern char atxbuf[], atmbuf[]; /* Atom buffer */
785 extern char cmdbuf[]; /* Command buffer */
786 extern char line[], tmpbuf[]; /* Character buffer for anything */
792 extern struct keytab fcstab[]; /* For SET FILE CHARACTER-SET */
793 extern struct csinfo fcsinfo[]; /* File character set info. */
794 extern struct keytab ttcstab[];
795 extern int nfilc, fcharset, tcharset, ntermc, tcsr, tcsl, dcset7, dcset8;
800 _PROTOTYP( int os2setcp, (int) );
801 _PROTOTYP( int os2getcp, (void) );
802 _PROTOTYP( void os2debugoff, (void) );
806 extern int cmdlvl; /* Overall command level */
810 extern int *inpcas; /* INPUT CASE setting on cmd stack */
818 _PROTOTYP(int tgetent,(char *, char *));
821 _PROTOTYP(int tgetent,(char *, char *));
824 #endif /* CK_CURSES */
827 #define XMITF 0 /* SET TRANSMIT values */
828 #define XMITL 1 /* (Local to this module) */
837 extern int xmitf, xmitl, xmitp, xmitx, xmits, xmitw, xmitt;
838 char xmitbuf[XMBUFL+1] = { NUL }; /* TRANSMIT eof string */
840 struct keytab xmitab[] = { /* SET TRANSMIT */
841 { "echo", XMITX, 0 },
843 { "fill", XMITF, 0 },
844 { "linefeed", XMITL, 0 },
845 { "locking-shift", XMITS, 0 },
846 { "pause", XMITW, 0 },
847 { "prompt", XMITP, 0 },
848 { "timeout", XMITT, 0 }
850 int nxmit = (sizeof(xmitab) / sizeof(struct keytab));
853 /* For SET FILE COLLISION */
854 /* Some of the following may be possible for some C-Kermit implementations */
855 /* but not others. Those that are not possible for your implementation */
856 /* should be ifdef'd out. */
858 struct keytab colxtab[] = { /* SET FILE COLLISION options */
860 { "append", XYFX_A, 0 }, /* append to old file */
863 { "ask", XYFX_Q, 0 }, /* ask what to do (not implemented) */
865 { "backup", XYFX_B, 0 }, /* rename old file */
867 /* This crashes Mac Kermit. */
868 { "discard", XYFX_D, 0 }, /* don't accept new file */
869 { "no-supersede", XYFX_D, CM_INV }, /* ditto (MSK compatibility) */
871 { "overwrite", XYFX_X, 0 }, /* overwrite the old file */
872 { "rename", XYFX_R, 0 }, /* rename the incoming file */
873 #ifndef MAC /* This crashes Mac Kermit. */
874 { "update", XYFX_U, 0 }, /* replace if newer */
878 int ncolx = (sizeof(colxtab) / sizeof(struct keytab)) - 1;
880 static struct keytab rfiltab[] = { /* for REMOTE SET FILE */
882 { "character-set", XYFILC, 0 },
884 { "collision", XYFILX, 0 },
885 { "incomplete", XYFILI, 0 },
886 { "names", XYFILN, 0 },
887 { "record-length", XYFILR, 0 },
888 { "type", XYFILT, 0 }
890 int nrfilp = (sizeof(rfiltab) / sizeof(struct keytab));
892 struct keytab eoltab[] = { /* File eof delimiters */
894 { "crlf", XYFA_2, 0 },
897 static int neoltab = (sizeof(eoltab) / sizeof(struct keytab));
899 struct keytab fntab[] = { /* File naming */
900 { "converted", XYFN_C, 0 },
901 { "literal", XYFN_L, 0 },
902 { "standard", XYFN_C, CM_INV }
904 int nfntab = (sizeof(fntab) / sizeof(struct keytab));
907 /* Terminal parameters table */
908 static struct keytab trmtab[] = {
910 { "answerback", XYTANS, 0 },
913 { "apc", XYTAPC, 0 },
916 { "arrow-keys", XYTARR, 0 },
919 { "at", XYTATTR, CM_INV|CM_ABR },
920 { "att", XYTATTR, CM_INV|CM_ABR },
921 { "attr", XYTATTR, CM_INV|CM_ABR },
922 { "attr-bug", XYTATTBUG, CM_INV },
925 { "attribute", XYTATTR, 0 },
929 { "autodownload", XYTAUTODL, 0, },
930 #endif /* CK_AUTODL */
933 { "autopage", XYTAPAGE, 0 },
934 { "autoscroll", XYTASCRL, 0 },
935 { "bell", XYTBEL, CM_INV },
937 { "bytesize", XYTBYT, 0 },
939 { "character-set", XYTCS, 0 },
942 { "code-page", XYTCPG, 0 },
943 { "color", XYTCOL, 0 },
944 { "controls", XYTCTRL, 0 },
946 { "cr-display", XYTCRD, 0 },
948 { "cursor", XYTCUR, 0 },
950 { "debug", XYTDEB, 0 },
952 { "dg-unix-mode", XYTUNX, 0 },
954 { "echo", XYTEC, 0 },
955 { "escape-character", XYTESC, 0 },
958 { "font", XYTFON, 0 },
961 { "font", XYTFON, 0 },
965 { "height", XYTHIG, 0 },
967 { "idle-action", XYTIACT, 0 },
968 { "idle-limit", XYTITMO, CM_INV },
969 { "idle-send", XYTIDLE, CM_INV },
970 { "idle-timeout", XYTITMO, 0 },
974 { "kbd-follows-gl/gr", XYTKBDGL, 0 },
976 { "key", XYTKEY, 0 },
977 { "keyboard-mode", XYTKBMOD, 0 },
978 { "keypad-mode", XYTKPD, 0 },
983 { "line-spacing", XYTLSP, CM_INV },
984 { "local-character-set", XYTLCS, 0 },
986 { "line-spacing", XYTLSP, 0 },
987 { "local-character-set", XYTLCS, CM_INV },
990 { "local-character-set", XYTLCS, CM_INV },
993 { "locking-shift", XYTSO, 0 },
995 { "margin-bell", XYTMBEL, 0 },
998 { "mouse", XYTMOU, CM_INV },
999 #endif /* OS2MOUSE */
1000 { "newline-mode", XYTNL, 0 },
1002 { "output-pacing", XYTPAC, 0 },
1004 { "pcterm", XYTPCTERM, 0 },
1008 { "print", XYTPRN, 0 },
1009 #endif /* OS2ORUNIX */
1012 { "remote-character-set", XYTRCS, 0 },
1014 { "remote-character-set", XYTRCS, CM_INV },
1016 #endif /* NOCSETS */
1018 { "roll-mode", XYTROL, 0 },
1019 { "s", XYTUPD, CM_ABR|CM_INV },
1020 { "sc", XYTUPD, CM_ABR|CM_INV },
1021 { "scr", XYTUPD, CM_ABR|CM_INV },
1022 { "scree", XYTUPD, CM_ABR|CM_INV },
1023 { "screen", XYTUPD, CM_ABR|CM_INV },
1024 { "screen-", XYTUPD, CM_ABR|CM_INV },
1025 { "screen-mode", XYTSCNM, 0 },
1026 { "screen-optimize", XYTOPTI, 0 },
1027 { "screen-update", XYTUPD, 0 },
1028 { "scrollback", XYSCRS, 0 },
1029 { "send-data", XYTSEND, 0 },
1030 { "send-end-of-block", XYTSEOB, 0 },
1031 { "sgr-colors", XYTSGRC, 0 },
1032 { "sni-ch.code", XYTSNICC, 0 },
1033 { "sni-firmware-versions", XYTSNIFV, 0 },
1034 { "sni-language", XYTVTLNG, 0 },
1035 { "sni-pagemode", XYTSNIPM, CM_INV },
1036 { "sni-scrollmode", XYTSNISM, CM_INV },
1037 { "spacing-attribute-character", XYTSAC, CM_INV },
1038 { "statusline", XYTSTAT, 0 },
1039 { "tra", XYTCTS, CM_INV|CM_ABR },
1040 { "transmit-timeout", XYTCTS, 0 },
1044 { "transparent-print", XYTPRN, CM_INV },
1045 #endif /* OS2ORUNIX */
1048 { "trigger", XYTRIGGER,0 },
1049 #endif /* CK_TRIGGER */
1051 { "type", XYTTYP, 0 },
1053 { "type", XYTTYP, CM_INV },
1059 { "unicode", XYTUNI, CM_INV },
1061 #endif /* UNICODE */
1062 #endif /* NOCSETS */
1064 { "unix-mode", XYTUNX, CM_INV },
1065 { "url-highlight", XYTURLHI, 0 },
1067 { "video-change", XYTVCH, 0 },
1069 { "vt-language", XYTVTLNG, 0 },
1070 { "vt-nrc-mode", XYTVTNRC, 0 },
1072 { "width", XYTWID, 0 },
1074 { "wrap", XYTWRP, 0 },
1078 int ntrm = (sizeof(trmtab) / sizeof(struct keytab)) - 1;
1081 struct keytab termctrl[] = { /* SET TERM CONTROLS */
1085 int ntermctrl = (sizeof(termctrl) / sizeof(struct keytab));
1087 struct keytab curontab[] = { /* SET TERM CURSOR */
1089 { "noblink", 2, 0 },
1091 { "noblink", 2, CM_INV },
1096 int ncuron = (sizeof(curontab) / sizeof(struct keytab));
1098 struct keytab rolltab[] = { /* Set TERM Roll Options */
1099 { "insert", TTR_INSERT, 0 },
1100 { "keystrokes",TTR_KEYS, 0 },
1101 { "off", TTR_OVER, CM_INV },
1102 { "on", TTR_INSERT, CM_INV },
1103 { "overwrite", TTR_OVER, 0 }
1105 int nroll = (sizeof(rolltab) / sizeof(struct keytab));
1107 struct keytab rollkeytab[] = { /* Set TERM ROLL KEYSTROKES */
1108 { "ignore", TTRK_IGN, 0 },
1109 { "restore-and-send", TTRK_RST, 0 },
1110 { "send", TTRK_SND, 0 }
1112 int nrollkey = (sizeof(rollkeytab) / sizeof(struct keytab));
1120 struct keytab graphsettab[] = { /* DEC VT Graphic Sets */
1121 { "all", TT_GR_ALL, 0 },
1122 { "g0", TT_GR_G0, 0 },
1123 { "g1", TT_GR_G1, 0 },
1124 { "g2", TT_GR_G2, 0 },
1125 { "g3", TT_GR_G3, 0 },
1126 { "keyboard", TT_GR_KBD, 0 }
1128 int ngraphset = (sizeof(graphsettab) / sizeof(struct keytab));
1131 struct keytab adltab[] = { /* Autodownload Options */
1132 { "ask", TAD_ASK, 0 },
1133 { "error", TAD_ERR, 0 },
1135 { "kermit", TAD_K, 0 },
1137 { "off", TAD_OFF, 0 },
1138 { "on", TAD_ON, 0 },
1140 { "zmodem", TAD_Z, 0 },
1144 int nadltab = (sizeof(adltab) / sizeof(struct keytab)) - 1;
1146 struct keytab adlerrtab[] = { /* Autodownload Error Options */
1147 { "continue", 0, 0 },
1148 { "go", 0, CM_INV },
1151 int nadlerrtab = (sizeof(adlerrtab) / sizeof(struct keytab));
1154 struct keytab adlxtab[] = { /* Autodownload Options */
1155 { "c0-conflicts", TAD_X_C0, 0 },
1156 { "detection-method", TAD_X_DETECT, 0 },
1157 { "string", TAD_X_STR, 0 }
1159 int nadlxtab = (sizeof(adlxtab) / sizeof(struct keytab));
1161 struct keytab adldtab[] = { /* Auto-dl Detection Methods */
1162 { "packet", ADL_PACK, 0 },
1163 { "string", ADL_STR, 0 }
1165 int nadldtab = (sizeof(adldtab) / sizeof(struct keytab));
1167 struct keytab adlc0tab[] = { /* Auto-dl Detection Methods */
1168 { "ignored-by-emulator", 0, 0 },
1169 { "processed-by-emulator", 1, 0 }
1171 int nadlc0tab = (sizeof(adlc0tab) / sizeof(struct keytab));
1174 struct keytab vtlangtab[] = {
1175 { "belgian", VTL_BELGIAN , 0 },
1176 { "british", VTL_BRITISH , 0 },
1177 { "canadian", VTL_CANADIAN, 0 },
1178 { "czech", VTL_CZECH , 0 },
1179 { "danish", VTL_DANISH , 0 },
1180 { "dutch", VTL_DUTCH , 0 },
1181 { "finnish", VTL_FINNISH , 0 },
1182 { "french", VTL_FRENCH , 0 },
1183 { "french-canadian",VTL_FR_CAN , 0 },
1184 { "german", VTL_GERMAN , 0 },
1185 { "greek", VTL_GREEK , 0 },
1186 { "hebrew", VTL_HEBREW , 0 },
1187 { "hungarian", VTL_HUNGARIA, 0 },
1188 { "italian", VTL_ITALIAN , 0 },
1189 { "latin-american", VTL_LATIN_AM, 0 },
1190 { "north-american", VTL_NORTH_AM, 0 },
1191 { "norwegian", VTL_NORWEGIA, 0 },
1192 { "polish", VTL_POLISH , 0 },
1193 { "portugese", VTL_PORTUGES, 0 },
1194 { "romanian", VTL_ROMANIAN, 0 },
1195 { "russian", VTL_RUSSIAN , 0 },
1196 { "scs", VTL_SCS , CM_INV },
1197 { "slovak", VTL_SLOVAK , 0 },
1198 { "spanish", VTL_SPANISH , 0 },
1199 { "swedish", VTL_SWEDISH , 0 },
1200 { "swiss-french", VTL_SW_FR , 0 },
1201 { "swiss-german", VTL_SW_GR , 0 },
1202 { "turkish-f", VTL_TURK_F , CM_INV },
1203 { "turkish-q", VTL_TURK_Q , CM_INV }
1205 int nvtlangtab = (sizeof(vtlangtab) / sizeof(struct keytab));
1206 #endif /* NOCSETS */
1209 struct keytab crdtab[] = { /* Carriage-return display */
1213 extern int tt_crd; /* Carriage-return display variable */
1216 extern int apcstatus, apcactive;
1217 static struct keytab apctab[] = { /* Terminal APC parameters */
1218 { "no-input", APC_ON|APC_NOINP,0 },
1219 { "off", APC_OFF, 0 },
1220 { "on", APC_ON, 0 },
1221 { "unchecked", APC_ON|APC_UNCH, 0 },
1222 { "unchecked-no-input", APC_ON|APC_NOINP|APC_UNCH, 0 }
1224 int napctab = (sizeof(apctab) / sizeof(struct keytab));
1226 #endif /* NOLOCAL */
1228 extern int autodl, adl_err, adl_ask;
1230 struct keytab beltab[] = { /* Terminal bell mode */
1232 { "audible", XYB_AUD, 0 },
1233 { "none", XYB_NONE, 0 },
1235 { "audible", XYB_AUD, CM_INV },
1236 { "none", XYB_NONE, CM_INV },
1239 { "off", XYB_NONE, CM_INV },
1240 { "on", XYB_AUD, CM_INV },
1242 { "off", XYB_NONE, 0 },
1243 { "on", XYB_AUD, 0 },
1246 { "visible", XYB_VIS, 0 },
1250 int nbeltab = sizeof(beltab)/sizeof(struct keytab) - 1;
1252 int tt_unicode = 1; /* Use Unicode if possible */
1254 int tt_idlesnd_tmo = 0; /* Idle Send Timeout, disabled */
1255 char * tt_idlesnd_str = NULL; /* Idle Send String, none */
1256 char * tt_idlestr = NULL;
1257 extern int tt_idleact, tt_idlelimit;
1258 #endif /* CKTIDLE */
1263 OS/2 serial communication devices.
1265 struct keytab os2devtab[] = {
1266 { "1", 1, CM_INV }, /* Invisible synonyms, like */
1267 { "2", 2, CM_INV }, /* "set port 1" */
1274 { "com1", 1, 0 }, /* Real device names */
1283 { "slipcom1", 1, 0 }, /* For use with SLIP driver */
1284 { "slipcom2", 2, 0 }, /* shared access */
1285 { "slipcom3", 3, 0 },
1286 { "slipcom4", 4, 0 },
1287 { "slipcom5", 5, 0 },
1288 { "slipcom6", 6, 0 },
1289 { "slipcom7", 7, 0 },
1290 { "slipcom8", 8, 0 },
1291 { "pppcom1", 1, 0 }, /* For use with PPP driver */
1292 { "pppcom2", 2, 0 }, /* shared access */
1293 { "pppcom3", 3, 0 },
1294 { "pppcom4", 4, 0 },
1295 { "pppcom5", 5, 0 },
1296 { "pppcom6", 6, 0 },
1297 { "pppcom7", 7, 0 },
1299 #endif /* OS2ONLY */
1301 int nos2dev = (sizeof(os2devtab) / sizeof(struct keytab)) - 1;
1304 struct keytab os2ppptab[] = {
1306 { "1", 1, CM_INV }, /* Invisible synonyms, like */
1307 { "2", 2, CM_INV }, /* "set port 1" */
1316 { "ppp1", 1, 0 }, /* For use with PPP driver */
1317 { "ppp2", 2, 0 }, /* shared access */
1326 int nos2ppp = (sizeof(os2ppptab) / sizeof(struct keytab));
1327 #endif /* OS2ONLY */
1330 Terminal parameters that can be set by SET commands.
1331 Used by the ck?con.c terminal emulator code.
1332 For now, only used for #ifdef OS2. Should add these for Macintosh.
1334 int tt_arrow = TTK_NORM; /* Arrow key mode: normal (cursor) */
1335 int tt_keypad = TTK_NORM; /* Keypad mode: normal (numeric) */
1336 int tt_shift_keypad = 0; /* Keypad Shift mode: Off */
1337 int tt_wrap = 1; /* Terminal wrap, 1 = On */
1338 int tt_type = TT_VT320; /* Terminal type, initially VT320 */
1339 int tt_type_mode = TT_VT320; /* Terminal type set by host command */
1340 int tt_cursor = 0; /* Terminal cursor, 0 = Underline */
1341 int tt_cursor_usr = 0; /* Users Terminal cursor type */
1342 int tt_cursorena_usr = 1; /* Users Terminal cursor enabled */
1343 int tt_cursor_blink = 1; /* Terminal Cursor Blink */
1344 int tt_answer = 0; /* Terminal answerback (disabled) */
1345 int tt_scrsize[VNUM] = {512,512,512,1}; /* Terminal scrollback buffer size */
1346 int tt_roll[VNUM] = {1,1,1,1}; /* Terminal roll (on) */
1347 int tt_rkeys[VNUM] = {1,1,1,1}; /* Terminal roll keys (send) */
1348 int tt_pacing = 0; /* Terminal output-pacing (none) */
1349 int tt_ctstmo = 15; /* Terminal transmit-timeout */
1350 int tt_codepage = -1; /* Terminal code-page */
1351 int tt_update = 100; /* Terminal screen-update interval */
1352 int tt_updmode = TTU_FAST; /* Terminal screen-update mode FAST */
1355 int tt_status[VNUM] = {1,1,0,0}; /* Terminal status line displayed */
1356 int tt_status_usr[VNUM] = {1,1,0,0};
1358 extern CKFLOAT floatval;
1359 CKFLOAT tt_linespacing[VNUM] = {1.0,1.0,1.0,1.0};
1361 int tt_status[VNUM] = {1,1,0,0}; /* Terminal status line displayed */
1362 int tt_status_usr[VNUM] = {1,1,0,0};
1364 int tt_status[VNUM] = {0,0,0,0}; /* Terminal status line displayed */
1365 int tt_status_usr[VNUM] = {0,0,0,0};
1368 int tt_senddata = 0; /* Let host read terminal data */
1369 extern int wy_blockend; /* Terminal Send Data EOB type */
1370 int tt_hidattr = 1; /* Attributes are hidden */
1372 extern unsigned char colornormal, colorselect,
1373 colorunderline, colorstatus, colorhelp, colorborder,
1374 colorgraphic, colordebug, colorreverse, coloritalic;
1376 extern int trueblink, trueunderline, truereverse, trueitalic, truedim;
1378 extern int bgi, fgi;
1379 extern int scrninitialized[];
1381 struct keytab audibletab[] = { /* Terminal Bell Audible mode */
1382 { "beep", XYB_BEEP, 0 }, /* Values ORd with bell mode */
1383 { "system-sounds", XYB_SYS, 0 }
1385 int naudibletab = sizeof(audibletab)/sizeof(struct keytab);
1387 struct keytab akmtab[] = { /* Arrow key mode */
1388 { "application", TTK_APPL, 0 },
1389 { "cursor", TTK_NORM, 0 }
1391 struct keytab kpmtab[] = { /* Keypad mode */
1392 { "application", TTK_APPL, 0 },
1393 { "numeric", TTK_NORM, 0 }
1396 struct keytab ttcolmodetab[] = {
1397 { "current-color", 0, 0 },
1398 { "default-color", 1, 0 }
1400 int ncolmode = sizeof(ttcolmodetab)/sizeof(struct keytab);
1415 struct keytab ttycoltab[] = { /* Terminal Screen coloring */
1416 { "border", TTCOLBOR, 0 }, /* Screen border color */
1417 { "debug-terminal", TTCOLDEB, 0 }, /* Debug color */
1418 { "erase", TTCOLERA, 0 }, /* Erase mode */
1419 { "graphic", TTCOLGRP, 0 }, /* Graphic Color */
1420 { "help-text", TTCOLHLP, 0 }, /* Help screens */
1421 { "italic", TTCOLITA, 0 }, /* Italic Color */
1422 { "normal", TTCOLNOR, CM_INV }, /* Normal screen text */
1423 { "reset-on-esc[0m", TTCOLRES, 0 }, /* Reset on ESC [ 0 m */
1424 { "reverse-video", TTCOLREV, 0 }, /* Reverse video */
1425 { "status-line", TTCOLSTA, 0 }, /* Status line */
1426 { "selection", TTCOLSEL, 0 }, /* Selection color */
1427 { "terminal-screen", TTCOLNOR, 0 }, /* Better name than "normal" */
1428 { "underlined-text", TTCOLUND, 0 } /* Underlined text */
1430 int ncolors = (sizeof(ttycoltab) / sizeof(struct keytab));
1443 struct keytab ttyattrtab[] = {
1444 { "blink", TTATTBLI, 0 },
1445 { "dim", TTATTDIM, 0 },
1446 { "italic", TTATTITA, 0 },
1447 { "protected", TTATTPRO, 0 },
1448 { "reverse", TTATTREV, 0 },
1449 { "underline", TTATTUND, 0 }
1451 int nattrib = (sizeof(ttyattrtab) / sizeof(struct keytab));
1453 struct keytab ttyprotab[] = {
1454 { "blink", TTATTBLI, 0 },
1455 { "bold", TTATTBLD, 0 },
1456 { "dim", TTATTDIM, 0 },
1457 { "done", TTATTDONE, CM_INV },
1458 { "invisible", TTATTINV, 0 },
1459 { "italic", TTATTITA, 0 },
1460 { "normal", TTATTNOR, 0 },
1461 { "reverse", TTATTREV, 0 },
1462 { "underlined", TTATTUND, 0 }
1465 int nprotect = (sizeof(ttyprotab) / sizeof(struct keytab));
1467 struct keytab ttyseobtab[] = {
1468 { "crlf_etx", 1, 0 },
1472 struct keytab ttyclrtab[] = { /* Colors */
1477 { "darkgray", 8, CM_INV },
1480 { "lblue", 9, CM_INV },
1481 { "lcyan", 11, CM_INV },
1482 { "lgray", 7, CM_INV },
1483 { "lgreen", 10, CM_INV },
1484 { "lightblue", 9, 0 },
1485 { "lightcyan", 11, 0 },
1486 { "lightgray", 7, 0 },
1487 { "lightgreen", 10, 0 },
1488 { "lightmagenta", 13, 0 },
1489 { "lightred", 12, 0 },
1490 { "lmagenta", 13, CM_INV },
1491 { "lred", 12, CM_INV },
1492 { "magenta", 5, 0 },
1497 int nclrs = (sizeof (ttyclrtab) / sizeof (struct keytab));
1499 struct keytab ttycurtab[] = {
1500 { "full", TTC_BLOCK, 0 },
1501 { "half", TTC_HALF, 0 },
1502 { "underline", TTC_ULINE, 0 }
1506 struct keytab ttyptab[] = {
1507 { "aaa", TT_AAA, CM_INV }, /* AnnArbor */
1508 { "adm3a", TT_ADM3A, 0 }, /* LSI ADM-3A */
1509 { "adm5", TT_ADM5, 0 }, /* LSI ADM-5 */
1510 { "aixterm", TT_AIXTERM, 0 }, /* IBM AIXterm */
1511 { "annarbor", TT_AAA, 0 }, /* AnnArbor */
1512 { "ansi-bbs", TT_ANSI, 0 }, /* ANSI.SYS (BBS) */
1513 { "at386", TT_AT386, 0 }, /* Unixware ANSI */
1514 { "avatar/0+",TT_ANSI, 0 }, /* AVATAR/0+ */
1515 { "ba80", TT_BA80, 0 }, /* Nixdorf BA80 */
1516 { "be", TT_BEOS, CM_INV|CM_ABR },
1517 { "beos-ansi",TT_BEOS, CM_INV }, /* BeOS ANSI */
1518 { "beterm", TT_BEOS, 0 }, /* BeOS Terminal (as of PR2 ) */
1519 { "d200", TT_DG200, CM_INV|CM_ABR }, /* Data General DASHER 200 */
1520 { "d210", TT_DG210, CM_INV|CM_ABR }, /* Data General DASHER 210 */
1521 { "d217", TT_DG217, CM_INV|CM_ABR }, /* Data General DASHER 217 */
1522 { "dg200", TT_DG200, 0 }, /* Data General DASHER 200 */
1523 { "dg210", TT_DG210, 0 }, /* Data General DASHER 210 */
1524 { "dg217", TT_DG217, 0 }, /* Data General DASHER 217 */
1525 { "h1500", TT_HZL1500, CM_INV }, /* Hazeltine 1500 */
1526 { "h19", TT_H19, CM_INV }, /* Heath-19 */
1527 { "heath19", TT_H19, 0 }, /* Heath-19 */
1528 { "hft", TT_HFT, 0 }, /* IBM High Function Terminal */
1529 { "hp2621a", TT_HP2621, 0 }, /* HP 2621A */
1530 { "hpterm", TT_HPTERM, 0 }, /* HP TERM */
1531 { "hz1500", TT_HZL1500, 0 }, /* Hazeltine 1500 */
1532 { "ibm3151", TT_IBM31, 0 }, /* IBM 3101-xx,3161 */
1533 { "linux", TT_LINUX, 0 }, /* Linux */
1534 { "qansi", TT_QANSI, 0 }, /* QNX ANSI */
1535 { "qnx", TT_QNX, 0 }, /* QNX Console */
1536 { "scoansi", TT_SCOANSI, 0 }, /* SCO ANSI */
1537 { "sni-97801",TT_97801, 0 }, /* SNI 97801 */
1538 { "sun", TT_SUN, 0 }, /* SUN Console */
1540 The idea of NONE is to let the console driver handle the escape sequences,
1541 which, in theory at least, would give not only ANSI emulation, but also any
1542 other kind of emulation that might be provided by alternative console
1543 drivers, if any existed.
1545 For this to work, ckocon.c would need to be modified to make higher-level
1546 calls, like VioWrtTTY(), DosWrite(), or (simply) write(), rather than
1547 VioWrt*Cell() and similar, and it would also have to give up its rollback
1548 feature, and its status line and help screens would also have to be
1549 forgotten or else done in an ANSI way.
1551 As matters stand, we already have perfectly good ANSI emulation built in,
1552 and there are no alternative console drivers available, so there is no point
1553 in having a terminal type of NONE, so it is commented out. However, should
1554 you uncomment it, it will work like a "glass tty" -- no escape sequence
1555 interpretation at all; somewhat similar to debug mode, except without the
1556 debugging (no highlighting of control chars or escape sequences); help
1557 screens, status line, and rollback will still work.
1561 { "tek4014", TT_TEK40, 0 },
1562 #endif /* COMMENT */
1564 { "tty", TT_NONE, 0 },
1565 { "tvi910+", TT_TVI910, 0 },
1566 { "tvi925", TT_TVI925, 0 },
1567 { "tvi950", TT_TVI950, 0 },
1568 { "vc404", TT_VC4404, 0 },
1569 { "vc4404", TT_VC4404, CM_INV },
1570 { "vip7809", TT_VIP7809,0 },
1571 { "vt100", TT_VT100, 0 },
1572 { "vt102", TT_VT102, 0 },
1573 { "vt220", TT_VT220, 0 },
1574 { "vt220pc", TT_VT220PC,0 },
1575 { "vt320", TT_VT320, 0 },
1576 { "vt320pc", TT_VT320PC,0 },
1577 { "vt52", TT_VT52, 0 },
1579 { "vtnt", TT_VTNT, 0 },
1581 { "vtnt", TT_VTNT, CM_INV },
1583 { "wy160", TT_WY160, 0 },
1584 { "wy30", TT_WY30, 0 },
1585 { "wy370", TT_WY370, 0 },
1586 { "wy50", TT_WY50, 0 },
1587 { "wy60", TT_WY60, 0 },
1588 { "wyse30", TT_WY30, CM_INV },
1589 { "wyse370", TT_WY370, CM_INV },
1590 { "wyse50", TT_WY50, CM_INV },
1591 { "wyse60", TT_WY60, CM_INV }
1593 int nttyp = (sizeof(ttyptab) / sizeof(struct keytab));
1595 struct keytab ttkeytab[] = {
1596 { "aaa", TT_AAA, CM_INV }, /* AnnArbor */
1597 { "adm3a", TT_ADM3A, 0 }, /* LSI ADM-3A */
1598 { "adm5", TT_ADM5, 0 }, /* LSI ADM-5 */
1599 { "aixterm", TT_AIXTERM, 0 }, /* IBM AIXterm */
1600 { "annarbor", TT_AAA, 0 }, /* AnnArbor */
1601 { "ansi-bbs", TT_ANSI, 0 }, /* ANSI.SYS (BBS) */
1602 { "at386", TT_AT386, 0 }, /* Unixware ANSI */
1603 { "avatar/0+", TT_ANSI, 0 }, /* AVATAR/0+ */
1604 { "ba80", TT_BA80, 0 }, /* Nixdorf BA80 */
1605 { "be", TT_BEOS, CM_INV|CM_ABR },
1606 { "beos-ansi", TT_BEOS, CM_INV }, /* BeOS ANSI */
1607 { "beterm", TT_BEOS, 0 }, /* BeOS Terminal (DR2) */
1608 { "d200", TT_DG200, CM_INV|CM_ABR }, /* DG DASHER 200 */
1609 { "d210", TT_DG210, CM_INV|CM_ABR }, /* DG DASHER 210 */
1610 { "d217", TT_DG217, CM_INV|CM_ABR }, /* DG DASHER 217 */
1611 { "dg200", TT_DG200, 0 }, /* DG DASHER 200 */
1612 { "dg210", TT_DG210, 0 }, /* DG DASHER 210 */
1613 { "dg217", TT_DG217, 0 }, /* DG DASHER 217 */
1614 { "emacs", TT_KBM_EMACS, 0 }, /* Emacs mode */
1615 { "h19", TT_H19, CM_INV }, /* Heath-19 */
1616 { "heath19", TT_H19, 0 }, /* Heath-19 */
1617 { "hebrew", TT_KBM_HEBREW, 0 }, /* Hebrew mode */
1618 { "hft", TT_HFT, 0 }, /* IBM High Function Term */
1619 { "hp2621a", TT_HP2621, 0 }, /* HP 2621A */
1620 { "hpterm", TT_HPTERM, 0 }, /* HP TERM */
1621 { "hz1500", TT_HZL1500, 0 }, /* Hazeltine 1500 */
1622 { "ibm3151", TT_IBM31, 0 }, /* IBM 3101-xx,3161 */
1623 { "linux", TT_LINUX, 0 }, /* Linux */
1624 { "qansi", TT_QANSI, 0 }, /* QNX ANSI */
1625 { "qnx", TT_QNX, 0 }, /* QNX */
1626 { "russian", TT_KBM_RUSSIAN,0 }, /* Russian mode */
1627 { "scoansi", TT_SCOANSI, 0 }, /* SCO ANSI */
1628 { "sni-97801", TT_97801, 0 }, /* SNI 97801 */
1629 { "sun", TT_SUN, 0 }, /* SUN Console */
1632 { "tek4014", TT_TEK40, 0 },
1633 #endif /* COMMENT */
1635 { "tty", TT_NONE, 0 },
1636 { "tvi910+", TT_TVI910, 0 },
1637 { "tvi925", TT_TVI925, 0 },
1638 { "tvi950", TT_TVI950, 0 },
1639 { "vc404", TT_VC4404, 0 },
1640 { "vc4404", TT_VC4404, CM_INV },
1641 { "vip7809", TT_VIP7809, 0 },
1642 { "vt100", TT_VT100, 0 },
1643 { "vt102", TT_VT102, 0 },
1644 { "vt220", TT_VT220, 0 },
1645 { "vt220pc", TT_VT220PC, 0 },
1646 { "vt320", TT_VT320, 0 },
1647 { "vt320pc", TT_VT320PC, 0 },
1648 { "vt52", TT_VT52, 0 },
1649 { "vtnt", TT_VTNT, CM_INV },
1650 { "wp", TT_KBM_WP, 0 }, /* Word Perfect mode */
1651 { "wy160", TT_WY160, 0 },
1652 { "wy30", TT_WY30, 0 },
1653 { "wy370", TT_WY370, 0 },
1654 { "wy50", TT_WY50, 0 },
1655 { "wy60", TT_WY60, 0 },
1656 { "wyse30", TT_WY30, CM_INV },
1657 { "wyse370", TT_WY370, CM_INV },
1658 { "wyse50", TT_WY50, CM_INV },
1659 { "wyse60", TT_WY60, CM_INV }
1661 int nttkey = (sizeof(ttkeytab) / sizeof(struct keytab));
1664 struct keytab kbmodtab[] = {
1665 { "emacs", KBM_EM, 0 },
1666 { "english", KBM_EN, CM_INV },
1667 { "hebrew", KBM_HE, 0 },
1668 { "normal", KBM_EN, 0 },
1669 { "none", KBM_EN, CM_INV },
1670 { "russian", KBM_RU, 0 },
1673 int nkbmodtab = (sizeof(kbmodtab) / sizeof(struct keytab));
1674 #endif /* NOSETKEY */
1675 #endif /* NOLOCAL */
1677 int tt_inpacing = 0; /* input-pacing (none) */
1679 struct keytab prtytab[] = { /* OS/2 Priority Levels */
1680 { "foreground-server", XYP_SRV, 0 },
1681 { "idle", XYP_IDLE, CM_INV },
1682 { "regular", XYP_REG, 0 },
1683 { "time-critical", XYP_RTP, 0 }
1685 int nprty = (sizeof(prtytab) / sizeof(struct keytab));
1689 struct keytab win95tab[] = { /* Win95 work-arounds */
1690 { "8.3-filenames", XYW8_3, 0 },
1691 { "alt-gr", XYWAGR, 0 },
1692 { "horizontal-scan-line-substitutions", XYWHSL, 0 },
1693 { "keyboard-translation", XYWKEY, 0 },
1694 { "lucida-substitutions", XYWLUC, 0 },
1695 { "overlapped-io", XYWOIO, 0 },
1696 { "popups", XYWPOPUP, 0 },
1697 { "select-bug", XYWSELECT, 0 }
1699 int nwin95 = (sizeof(win95tab) / sizeof(struct keytab));
1703 extern int wideresult;
1704 int tt_mouse = 1; /* Terminal mouse on/off */
1706 struct keytab mousetab[] = { /* Mouse items */
1707 { "activate", XYM_ON, 0 },
1708 { "button", XYM_BUTTON, 0 },
1709 { "clear", XYM_CLEAR, 0 },
1710 { "debug", XYM_DEBUG, 0 }
1712 int nmtab = (sizeof(mousetab)/sizeof(struct keytab));
1714 struct keytab mousebuttontab[] = { /* event button */
1718 { "one", XYM_B1, CM_INV },
1719 { "three", XYM_B3, CM_INV },
1720 { "two", XYM_B2, CM_INV }
1722 int nmbtab = (sizeof(mousebuttontab) / sizeof(struct keytab));
1724 struct keytab mousemodtab[] = { /* event button key modifier */
1725 { "alt", XYM_ALT, 0 },
1726 { "alt-shift", XYM_SHIFT|XYM_ALT, 0 },
1727 { "ctrl", XYM_CTRL, 0 },
1728 { "ctrl-alt", XYM_CTRL|XYM_ALT, 0 },
1729 { "ctrl-alt-shift", XYM_CTRL|XYM_SHIFT|XYM_ALT, 0 },
1730 { "ctrl-shift", XYM_CTRL|XYM_SHIFT, 0 },
1732 { "shift", XYM_SHIFT, 0 }
1734 int nmmtab = (sizeof(mousemodtab) / sizeof(struct keytab));
1736 struct keytab mclicktab[] = { /* event button click modifier */
1737 { "click", XYM_C1, 0 },
1738 { "drag", XYM_DRAG, 0 },
1739 { "double-click", XYM_C2, 0 }
1741 int nmctab = (sizeof(mclicktab) / sizeof(struct keytab));
1745 extern struct keytab kverbs[];
1746 #endif /* NOKVERBS */
1747 #endif /* OS2MOUSE */
1750 struct keytab fbtab[] = { /* Binary record types for VMS */
1751 { "fixed", XYFT_B, 0 }, /* Fixed is normal for binary */
1752 { "undefined", XYFT_U, 0 } /* Undefined if they ask for it */
1754 int nfbtyp = (sizeof(fbtab) / sizeof(struct keytab));
1758 struct keytab lbltab[] = { /* Labeled File info */
1759 { "acl", LBL_ACL, 0 },
1760 { "backup-date", LBL_BCK, 0 },
1761 { "name", LBL_NAM, 0 },
1762 { "owner", LBL_OWN, 0 },
1763 { "path", LBL_PTH, 0 }
1765 int nlblp = (sizeof(lbltab) / sizeof(struct keytab));
1768 struct keytab lbltab[] = { /* Labeled File info */
1769 { "archive", LBL_ARC, 0 },
1770 { "extended", LBL_EXT, 0 },
1771 { "hidden", LBL_HID, 0 },
1772 { "read-only", LBL_RO, 0 },
1773 { "system", LBL_SYS, 0 }
1775 int nlblp = (sizeof(lbltab) / sizeof(struct keytab));
1781 static struct keytab fdftab[] = { /* SET FILE DISPLAY FULL options */
1782 { "thermometer", 1, 0, },
1783 { "no-thermometer", 0, 0 }
1785 extern int thermometer;
1786 #endif /* CK_PCT_BAR */
1787 #endif /* CK_CURSES */
1789 static struct keytab fdtab[] = { /* SET FILE DISPLAY options */
1790 #ifdef MAC /* Macintosh */
1791 { "fullscreen", XYFD_R, 0 }, /* Full-screen but not curses */
1792 { "none", XYFD_N, 0 },
1793 { "off", XYFD_N, CM_INV },
1794 { "on", XYFD_R, CM_INV },
1795 { "quiet", XYFD_N, CM_INV },
1797 { "brief", XYFD_B, 0 }, /* Brief */
1798 { "crt", XYFD_S, 0 }, /* CRT display */
1801 { "curses", XYFD_C, CM_INV }, /* Full-screen, curses */
1802 #endif /* COMMENT */
1803 { "fullscreen", XYFD_C, 0 }, /* Full-screen, whatever the method */
1804 #endif /* CK_CURSES */
1806 { "gui", XYFD_G, 0 }, /* GUI */
1808 { "none", XYFD_N, 0 }, /* No display */
1809 { "off", XYFD_N, CM_INV }, /* Ditto */
1810 { "on", XYFD_R, CM_INV }, /* On = Serial */
1811 { "quiet", XYFD_N, CM_INV }, /* No display */
1812 { "serial", XYFD_R, 0 }, /* Serial */
1816 int nfdtab = (sizeof(fdtab) / sizeof(struct keytab)) - 1;
1818 struct keytab rsrtab[] = { /* For REMOTE SET RECEIVE */
1819 { "packet-length", XYLEN, 0 },
1820 { "timeout", XYTIMO, 0 }
1822 int nrsrtab = (sizeof(rsrtab) / sizeof(struct keytab));
1824 /* Send/Receive Parameters */
1826 struct keytab srtab[] = {
1827 { "backup", XYBUP, 0 },
1829 { "character-set-selection", XYCSET, 0 },
1830 #endif /* NOCSETS */
1831 { "control-prefix", XYQCTL, 0 },
1833 { "double-character", XYDBL, 0 },
1834 #endif /* CKXXCHAR */
1835 { "end-of-packet", XYEOL, 0 },
1837 { "filter", XYFLTR, 0 },
1838 #endif /* PIPESEND */
1840 { "ignore-character", XYIGN, 0 },
1841 #endif /* CKXXCHAR */
1842 { "i-packets", 993, 0 },
1843 { "move-to", XYMOVE, 0 },
1844 { "negotiation-string-max-length", XYINIL, CM_INV },
1845 { "packet-length", XYLEN, 0 },
1846 { "pad-character", XYPADC, 0 },
1847 { "padding", XYNPAD, 0 },
1848 { "pathnames", XYFPATH, 0 },
1849 { "pause", XYPAUS, 0 },
1851 { "permissions", 994, 0}, /* 206 */
1852 #endif /* CK_PERMS */
1853 { "quote", XYQCTL, CM_INV }, /* = CONTROL-PREFIX */
1854 { "rename-to", XYRENAME, 0 },
1855 { "start-of-packet", XYMARK, 0 },
1856 { "timeout", XYTIMO, 0 },
1858 { "version-numbers", 887, 0 }, /* VMS version numbers */
1862 int nsrtab = (sizeof(srtab) / sizeof(struct keytab)) - 1;
1867 static struct keytab ucstab[] = {
1868 { "bom", UCS_BOM, 0 },
1869 { "byte-order", UCS_BYT, 0 },
1872 int nucstab = (sizeof(ucstab) / sizeof(struct keytab)) - 1;
1874 static struct keytab botab[] = {
1875 { "big-endian", 0, 0 },
1876 { "little-endian", 1, 0 }
1878 static int nbotab = 2;
1879 #endif /* UNICODE */
1883 struct keytab rmstab[] = {
1884 { "attributes", XYATTR, 0 },
1885 { "block-check", XYCHKT, 0 },
1886 { "file", XYFILE, 0 },
1887 { "incomplete", XYIFD, CM_INV }, /* = REMOTE SET FILE INCOMPLETE */
1888 { "match", XYMATCH,0 },
1889 { "receive", XYRECV, 0 },
1890 { "retry", XYRETR, 0 },
1891 { "server", XYSERV, 0 },
1892 { "transfer", XYXFER, 0 },
1893 { "window", XYWIND, 0 },
1894 { "xfer", XYXFER, CM_INV }
1896 int nrms = (sizeof(rmstab) / sizeof(struct keytab));
1898 struct keytab attrtab[] = {
1900 { "account", AT_ACCT, 0 },
1901 #endif /* STRATUS */
1902 { "all", AT_XALL, 0 },
1904 { "blocksize", AT_BLKS, 0 }, /* (not used) */
1905 #endif /* COMMENT */
1907 { "character-set", AT_ENCO, 0 },
1908 #endif /* NOCSETS */
1910 { "creator", AT_CREA, 0 },
1911 #endif /* STRATUS */
1912 { "date", AT_DATE, 0 },
1913 { "disposition", AT_DISP, 0 },
1914 { "encoding", AT_ENCO, CM_INV },
1915 { "format", AT_RECF, CM_INV },
1916 { "length", AT_LENK, 0 },
1917 { "off", AT_ALLN, 0 },
1918 { "on", AT_ALLY, 0 },
1920 { "os-specific", AT_SYSP, 0 }, /* (not used by UNIX or VMS) */
1921 #endif /* COMMENT */
1923 { "protection", AT_LPRO, 0 },
1924 { "permissions", AT_LPRO, CM_INV },
1925 #endif /* CK_PERMS */
1926 { "record-format", AT_RECF, 0 },
1927 { "system-id", AT_SYSI, 0 },
1928 { "type", AT_FTYP, 0 }
1930 int natr = (sizeof(attrtab) / sizeof(struct keytab)); /* how many attributes */
1933 struct keytab idlacts[] = {
1934 { "exit", IDLE_EXIT, 0 },
1935 { "hangup", IDLE_HANG, 0 },
1936 { "output", IDLE_OUT, 0 },
1937 { "return", IDLE_RET, 0 },
1939 { "telnet-nop", IDLE_TNOP, 0 },
1940 { "telnet-ayt", IDLE_TAYT, 0 },
1944 int nidlacts = (sizeof(idlacts) / sizeof(struct keytab)) - 1;
1945 #endif /* CKTIDLE */
1948 extern int indef, inecho, insilence, inbufsize, inautodl, inintr;
1950 extern CKFLOAT inscale;
1951 #endif /* CKFLOAT */
1952 extern char * inpbuf, * inpbp;
1956 struct keytab inptab[] = { /* SET INPUT parameters */
1958 { "autodownload", IN_ADL, 0 },
1959 #endif /* CK_AUTODL */
1960 { "buffer-length", IN_BUF, 0 },
1961 { "cancellation", IN_CAN, 0 },
1962 { "case", IN_CAS, 0 },
1963 { "default-timeout", IN_DEF, CM_INV }, /* There is no default timeout */
1964 { "echo", IN_ECH, 0 },
1966 { "pacing", IN_PAC, CM_INV },
1968 { "scale-factor", IN_SCA, 0 },
1969 { "silence", IN_SIL, 0 },
1971 { "terminal", IN_TRM, 0 },
1973 { "timeout-action", IN_TIM, 0 }
1975 int ninp = (sizeof(inptab) / sizeof(struct keytab));
1977 struct keytab intimt[] = { /* SET INPUT TIMEOUT parameters */
1978 { "proceed", 0, 0 }, /* 0 = proceed */
1979 { "quit", 1, 0 } /* 1 = quit */
1982 struct keytab incast[] = { /* SET INPUT CASE parameters */
1983 { "ignore", 0, 0 }, /* 0 = ignore */
1984 { "observe", 1, 0 } /* 1 = observe */
1988 struct keytab nabltab[] = { /* For any command that needs */
1989 { "disabled", 0, 0 },
1990 { "enabled", 1, 0 },
1991 { "off", 0, CM_INV }, /* these keywords... */
1994 int nnabltab = sizeof(nabltab) / sizeof(struct keytab);
1997 struct keytab tvctab[] = { /* SET TERM VIDEO-CHANGE */
1998 { "disabled", TVC_DIS, 0 },
1999 { "enabled", TVC_ENA, 0 },
2001 { "win95-safe", TVC_W95, 0 },
2005 int ntvctab = (sizeof(tvctab) / sizeof(struct keytab)) - 1;
2007 struct keytab msktab[] = { /* SET MS-DOS KERMIT compatibilities */
2009 { "color", MSK_COLOR, 0 },
2010 #endif /* COMMENT */
2011 { "keycodes", MSK_KEYS, 0 }
2013 int nmsk = (sizeof(msktab) / sizeof(struct keytab));
2015 struct keytab scrnupd[] = { /* SET TERMINAL SCREEN-UPDATE */
2016 { "fast", TTU_FAST, 0 },
2017 { "smooth", TTU_SMOOTH, 0 }
2019 int nscrnupd = (sizeof(scrnupd) / sizeof(struct keytab));
2022 /* This definition of the term_font[] table is only for */
2023 /* the OS/2 Full Screen Session and is not used on Windows */
2024 struct keytab term_font[] = { /* SET TERMINAL FONT */
2026 { "cp111", TTF_111, 0 },
2027 { "cp112", TTF_112, 0 },
2028 { "cp113", TTF_113, 0 },
2029 #endif /* COMMENT */
2030 { "cp437", TTF_437, 0 },
2031 { "cp850", TTF_850, 0 },
2033 { "cp851", TTF_851, 0 },
2034 #endif /* COMMENT */
2035 { "cp852", TTF_852, 0 },
2037 { "cp853", TTF_853, 0 },
2038 { "cp860", TTF_860, 0 },
2039 { "cp861", TTF_861, 0 },
2040 #endif /* COMMENT */
2041 { "cp862", TTF_862, 0 },
2043 { "cp863", TTF_863, 0 },
2044 { "cp864", TTF_864, 0 },
2045 { "cp865", TTF_865, 0 },
2046 #endif /* COMMENT */
2047 { "cp866", TTF_866, 0 },
2049 { "cp880", TTF_880, 0 },
2050 { "cp881", TTF_881, 0 },
2051 { "cp882", TTF_882, 0 },
2052 { "cp883", TTF_883, 0 },
2053 { "cp884", TTF_884, 0 },
2054 { "cp885", TTF_885, 0 },
2055 #endif /* COMMENT */
2056 { "default",TTF_ROM,0 }
2058 int ntermfont = (sizeof(term_font) / sizeof(struct keytab));
2059 int tt_font = TTF_ROM; /* Terminal screen font */
2063 struct keytab * term_font = NULL;
2064 struct keytab * _term_font = NULL;
2065 char * tt_facename = NULL;
2068 int tt_font_size = 0;
2071 #endif /* PCFONTS */
2073 struct keytab anbktab[] = { /* For any command that needs */
2074 { "message", 2, 0 }, /* these keywords... */
2077 { "unsafe-messag0", 99, CM_INV },
2078 { "unsafe-message", 3, CM_INV }
2080 int nansbk = (sizeof(anbktab) / sizeof(struct keytab));
2082 int win95_popup = 1;
2085 int win95lucida = 0;
2088 int win95lucida = 1;
2092 int win95lucida = 0;
2097 extern int win95selectbug;
2098 extern int win95_8_3;
2101 extern CHAR (*xlr[MAXTCSETS+1][MAXFCSETS+1])(CHAR);
2102 extern struct keytab tcstab[];
2104 #endif /* COMMENT */
2105 extern int maxow, maxow_usr; owwait; /* Overlapped I/O variables */
2110 /* The following routines broken out of doprm() to give compilers a break. */
2112 /* S E T O N -- Parse on/off (default on), set parameter to result */
2115 seton(prm) int *prm; {
2117 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
2118 if ((x = cmcfm()) < 0) return(x);
2123 /* S E T O N A U T O -- Parse on/off/auto (default auto) & set result */
2125 struct keytab onoffaut[] = {
2126 { "auto", SET_AUTO, 0 }, /* 2 */
2127 { "off", SET_OFF, 0 }, /* 0 */
2128 { "on", SET_ON, 0 } /* 1 */
2132 setonaut(prm) int *prm; {
2134 if ((y = cmkey(onoffaut,3,"","auto",xxstring)) < 0) return(y);
2135 if ((x = cmcfm()) < 0) return(x);
2140 /* S E T N U M -- Set parameter to result of cmnum() parse. */
2142 Call with pointer to integer variable to be set,
2143 x = number from cnum parse, y = return code from cmnum,
2144 max = maximum value to accept, -1 if no maximum.
2145 Returns -9 on failure, after printing a message, or 1 on success.
2148 setnum(prm,x,y,max) int x, y, *prm, max; {
2149 debug(F101,"setnum","",y);
2151 printf("\n?Value required\n");
2155 printf("%s?Not a number: %s\n",cmflgs == 1 ? "" : "\n", atxbuf);
2158 if (y < 0) return(y);
2159 if (max > -1 && x > max) {
2160 printf("?Sorry, %d is the maximum\n",max);
2163 if ((y = cmcfm()) < 0) return(y);
2168 /* S E T C C -- Set parameter var to an ASCII control character value. */
2170 Parses a number, or a literal control character, or a caret (^) followed
2171 by an ASCII character whose value is 63-95 or 97-122, then gets confirmation,
2172 then sets the parameter to the code value of the character given. If there
2173 are any parse errors, they are returned, otherwise on success 1 is returned.
2176 setcc(dflt,var) char *dflt; int *var; {
2179 char *hlpmsg = "Control character,\n\
2180 numeric ASCII value,\n\
2181 or in ^X notation,\n\
2182 or preceded by a backslash and entered literally";
2184 /* This is a hack to turn off complaints from expression evaluator. */
2186 y = cmnum(hlpmsg, dflt, 10, &x, xxstring); /* Parse a number */
2187 x_ifnum = 0; /* Allow complaints again */
2188 if (y < 0) { /* Parse failed */
2189 if (y != -2) /* Reparse needed or somesuch */
2190 return(y); /* Pass failure back up the chain */
2192 /* Real control character or literal 8-bit character... */
2194 for (c = strlen(atmbuf) - 1; c > 0; c--) /* Trim */
2195 if (atmbuf[c] == SP) atmbuf[c] = NUL;
2197 if (y < 0) { /* It was not a number */
2198 if (((c = atmbuf[0])) && !atmbuf[1]) { /* Literal character? */
2200 if (((c > 31) && (c < 127)) || (c > 255)) {
2201 printf("\n?%d: Out of range - must be 0-31 or 127-255\n",c);
2204 if ((y = cmcfm()) < 0) /* Confirm */
2206 *var = c; /* Set the variable */
2209 } else if (atmbuf[0] == '^' && !atmbuf[2]) { /* Or ^X notation? */
2211 if (islower((char) c)) /* Uppercase lowercase letters */
2213 if (c > 62 && c < 96) { /* Check range */
2214 if ((y = cmcfm()) < 0)
2216 *var = ctl(c); /* OK */
2219 printf("?Not a control character - %s\n", atmbuf);
2222 } else { /* Something illegal was typed */
2223 printf("?Invalid - %s\n", atmbuf);
2227 if (((x > 31) && (x < 127)) || (x > 255)) { /* They typed a number */
2228 printf("\n?%d: Out of range - must be 0-31 or 127-255\n",x);
2231 if ((y = cmcfm()) < 0) /* In range, confirm */
2233 *var = x; /* Set variable */
2237 #ifndef NOSPL /* The SORT command... */
2239 static struct keytab srtswtab[] = { /* SORT command switches */
2240 { "/case", SRT_CAS, CM_ARG },
2241 { "/key", SRT_KEY, CM_ARG },
2242 { "/numeric", SRT_NUM, 0 },
2243 { "/range", SRT_RNG, CM_ARG },
2244 { "/reverse", SRT_REV, 0 }
2246 static int nsrtswtab = sizeof(srtswtab)/sizeof(struct keytab);
2248 extern char **a_ptr[]; /* Array pointers */
2249 extern int a_dim[]; /* Array dimensions */
2252 dosort() { /* Do the SORT command */
2253 char c, *p = NULL, ** ap, ** xp = NULL;
2254 struct FDB sw, fl, cm;
2256 int xn = 0, xr = -1, xk = -1, xc = -1, xs = 0;
2257 int getval = 0, range[2], confirmed = 0;
2259 cmfdbi(&sw, /* First FDB - command switches */
2261 "Array name or switch",
2263 "", /* addtl string data */
2264 nsrtswtab, /* addtl numeric data 1: tbl size */
2265 4, /* addtl numeric data 2: 4 = cmswi */
2266 NULL, /* Processing function */
2267 srtswtab, /* Keyword table */
2268 &fl /* Pointer to next FDB */
2270 cmfdbi(&fl, /* Anything that doesn't match */
2272 "Array name", /* hlpmsg */
2274 "", /* addtl string data */
2275 0, /* addtl numeric data 1 */
2276 0, /* addtl numeric data 2 */
2281 cmfdbi(&cm, /* Or premature confirmation */
2285 "", /* addtl string data */
2286 0, /* addtl numeric data 1 */
2287 0, /* addtl numeric data 2 */
2296 while (1) { /* Parse 0 or more switches */
2300 if (cmresult.fcode != _CMKEY) /* Break out if not a switch */
2303 getval = (c == ':' || c == '=');
2304 if (getval && !(cmresult.kflags & CM_ARG)) {
2305 printf("?This switch does not take arguments\n");
2308 switch (cmresult.nresult) {
2314 if ((y = cmnum("Column for comparison (1-based)",
2315 "1",10,&x,xxstring)) < 0)
2323 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0)
2329 case SRT_RNG: /* /RANGE */
2335 if ((y = cmfld("low:high element","1",&s,NULL)) < 0)
2338 ckstrncpy(buf,s,32);
2340 for (i = 0; *p && i < 2; i++) { /* Get low and high */
2341 q = p; /* Start of this piece */
2342 while (*p) { /* Find end of this piece */
2350 y = 15; /* Evaluate this piece */
2354 if (s) if (*s) ckstrncpy(buf2,s,16);
2355 if (!rdigits(buf2)) {
2356 printf("?Not numeric: %s\n",buf2);
2359 range[i] = atoi(buf2);
2363 case SRT_NUM: /* /NUMERIC */
2370 switch (cmresult.fcode) {
2375 ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Safe copy of name */
2379 printf("?Unexpected function code: %d\n",cmresult.fcode);
2383 printf("?Array name required\n");
2386 ckmakmsg(tmpbuf,TMPBUFSIZ,
2387 "Second array to sort according to ",s,NULL,NULL);
2388 if ((x = cmfld(tmpbuf,"",&p,NULL)) < 0)
2392 ckstrncpy(tmpbuf,p,TMPBUFSIZ);
2394 if ((x = cmcfm()) < 0) /* Get confirmation */
2397 x = arraybounds(s,&lo,&hi); /* Get array index & bounds */
2398 if (x < 0) { /* Check */
2399 printf("?Bad array name: %s\n",s);
2402 if (lo > -1) range[0] = lo; /* Set range */
2403 if (hi > -1) range[1] = hi;
2404 ap = a_ptr[x]; /* Get pointer to array element list */
2405 if (!ap) { /* Check */
2406 printf("?Array not declared: %s\n", s);
2409 if (range[0] < 0) /* Starting element */
2411 if (range[1] < 0) /* Final element */
2412 range[1] = a_dim[x];
2413 if (range[1] > a_dim[x]) {
2414 printf("?range %d:%d exceeds array dimension %d\n",
2415 range[0],range[1],a_dim[x]
2420 xs = range[1] - range[0] + 1; /* Number of elements to sort */
2421 if (xs < 1) { /* Check */
2422 printf("?Bad range: %d:%d\n",range[0],range[1]);
2425 if (xk < 0) xk = 0; /* Key position */
2426 if (xr < 0) xr = 0; /* Reverse flag */
2427 if (xn) /* Numeric flag */
2429 else if (xc < 0) /* Not numeric */
2430 xc = inpcas[cmdlvl]; /* so alpha case option */
2432 if (*p) { /* Parallel array given? */
2433 y = xarray(p); /* Yes, get its index. */
2435 printf("?Bad array name: %s\n", p);
2438 if (y != x) { /* If the 2 arrays are different */
2439 xp = a_ptr[y]; /* Pointer to 2nd array element list */
2441 printf("?Array not declared: %s\n", p);
2444 if (a_dim[y] < range[1]) {
2445 printf("?Array %s smaller than %s\n", p, s);
2448 xp += range[0]; /* Set base to same as 1st array */
2451 sh_sort(ap,xp,xs,xk,xr,xc); /* Sort the array(s) */
2452 return(success = 1); /* Always succeeds */
2456 static struct keytab purgtab[] = { /* PURGE command switches */
2457 { "/after", PU_AFT, CM_ARG },
2458 { "/ask", PU_ASK, 0 },
2459 { "/before", PU_BEF, CM_ARG },
2460 { "/delete", PU_DELE, CM_INV },
2462 { "/dotfiles", PU_DOT, 0 },
2463 #endif /* UNIXOROSK */
2464 { "/except", PU_EXC, CM_ARG },
2465 { "/heading", PU_HDG, 0 },
2466 { "/keep", PU_KEEP, CM_ARG },
2467 { "/larger-than", PU_LAR, CM_ARG },
2468 { "/list", PU_LIST, 0 },
2469 { "/log", PU_LIST, CM_INV },
2470 { "/noask", PU_NASK, 0 },
2471 { "/nodelete", PU_NODE, CM_INV },
2473 { "/nodotfiles", PU_NODOT,0 },
2474 #endif /* UNIXOROSK */
2475 { "/noheading", PU_NOH, 0 },
2476 { "/nol", PU_NOLI, CM_INV|CM_ABR },
2477 { "/nolist", PU_NOLI, 0 },
2478 { "/nolog", PU_NOLI, CM_INV },
2480 { "/nopage", PU_NOPA, 0 },
2481 #endif /* CK_TTGWSIZ */
2482 { "/not-after", PU_NAF, CM_ARG },
2483 { "/not-before", PU_NBF, CM_ARG },
2484 { "/not-since", PU_NAF, CM_INV|CM_ARG },
2486 { "/page", PU_PAGE, 0 },
2487 #endif /* CK_TTGWSIZ */
2488 { "/quiet", PU_QUIE, CM_INV },
2490 { "/recursive", PU_RECU, 0 },
2491 #endif /* RECURSIVE */
2492 { "/since", PU_AFT, CM_ARG|CM_INV },
2493 { "/simulate", PU_NODE, 0 },
2494 { "/smaller-than", PU_SMA, CM_ARG },
2495 { "/verbose", PU_VERB, CM_INV }
2497 static int npurgtab = sizeof(purgtab)/sizeof(struct keytab);
2504 bkupnum(s,i) char * s; int *i; {
2506 char * p = NULL, *q;
2511 if ((k = strlen(s)) < 5)
2518 while (q >= s && isdigit(*q)) {
2526 if (*q != '~' || *(q-1) != '.')
2530 debug(F111,"bkupnum",s+pos,pos);
2535 /* Presently only for UNIX because we need direct access to the file array. */
2536 /* Not needed for VMS anyway, because we don't make backup files there. */
2538 #define MAXKEEP 32 /* Biggest /KEEP: value */
2541 pu_keep = 0, pu_list = 0, pu_dot = 0, pu_ask = 0, pu_hdg = 0;
2544 static int pu_page = -1;
2546 static int pu_page = 0;
2547 #endif /* CK_TTGWSIZ */
2551 showpurgopts() { /* SHOW PURGE command options */
2553 extern int optlines;
2554 prtopt(&optlines,"PURGE");
2557 prtopt(&optlines, pu_ask ? "/ASK" : "/NOASK");
2562 prtopt(&optlines, pu_dot ? "/DOTFILES" : "/NODOTFILES");
2564 #endif /* UNIXOROSK */
2567 ckmakmsg(tmpbuf,TMPBUFSIZ,"/KEEP:",ckitoa(pu_keep),NULL,NULL);
2568 prtopt(&optlines,tmpbuf);
2572 prtopt(&optlines, pu_list ? "/LIST" : "/NOLIST");
2576 prtopt(&optlines, pu_hdg ? "/HEADING" : "/NOHEADING");
2581 prtopt(&optlines, pu_page ? "/PAGE" : "/NOPAGE");
2583 #endif /* CK_TTGWSIZ */
2584 if (!x) prtopt(&optlines,"(no options set)");
2585 prtopt(&optlines,"");
2590 setpurgopts() { /* Set PURGE command options */
2591 int c, z, getval = 0;
2593 x_keep = -1, x_list = -1, x_page = -1,
2594 x_hdg = -1, x_ask = -1, x_dot = -1;
2597 if ((y = cmswi(purgtab,npurgtab,"Switch","",xxstring)) < 0) {
2604 if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
2605 printf("?This switch does not take an argument\n");
2608 if (!getval && (cmgkwflgs() & CM_ARG)) {
2609 printf("?This switch requires an argument\n");
2615 if (c == ':' || c == '=')
2616 if ((y = cmnum("How many backup files to keep",
2617 "1",10,&z,xxstring)) < 0)
2619 if (z < 0 || z > MAXKEEP) {
2620 printf("?Please specify a number between 0 and %d\n",
2642 #endif /* CK_TTGWSIZ */
2662 #endif /* UNIXOROSK */
2664 printf("?This option can not be set\n");
2668 if ((x = cmcfm()) < 0) /* Get confirmation */
2670 if (x_keep > -1) /* Set PURGE defaults. */
2677 #endif /* CK_TTGWSIZ */
2684 return(success = 1);
2688 dopurge() { /* Do the PURGE command */
2689 extern char ** mtchs;
2690 extern int xaskmore, cmd_rows, recursive;
2691 int simulate = 0, asking = 0;
2692 int listing = 0, paging = -1, lines = 0, deleting = 1, errors = 0;
2693 struct FDB sw, sf, cm;
2694 int g, i, j, k, m = 0, n, x, y, z, done = 0, count = 0, flags = 0;
2695 int tokeep = 0, getval = 0, havename = 0, confirmed = 0;
2696 int xx[MAXKEEP+1]; /* Array of numbers to keep */
2698 int x_hdg = 0, fs = 0, rc = 0;
2699 long minsize = -1L, maxsize = -1L;
2700 char namebuf[CKMAXPATH+4];
2701 char basebuf[CKMAXPATH+4];
2708 char * pxlist[8]; /* Exception list */
2710 if (pu_keep > -1) /* Set PURGE defaults. */
2717 #endif /* CK_TTGWSIZ */
2719 for (i = 0; i <= MAXKEEP; i++) /* Clear this number buffer */
2721 for (i = 0; i < 8; i++) /* Initialize these... */
2724 g_matchdot = matchdot; /* Save these... */
2726 cmfdbi(&sw, /* 1st FDB - PURGE switches */
2728 "Filename or switch", /* hlpmsg */
2730 "", /* addtl string data */
2731 npurgtab, /* addtl numeric data 1: tbl size */
2732 4, /* addtl numeric data 2: 4 = cmswi */
2733 xxstring, /* Processing function */
2734 purgtab, /* Keyword table */
2735 &sf /* Pointer to next FDB */
2737 cmfdbi(&sf, /* 2nd FDB - filespec to purge */
2741 "", /* addtl string data */
2742 0, /* addtl numeric data 1 */
2743 0, /* addtl numeric data 2 */
2748 cmfdbi(&cm, /* Or premature confirmation */
2752 "", /* addtl string data */
2753 0, /* addtl numeric data 1 */
2754 0, /* addtl numeric data 2 */
2760 while (!havename && !confirmed) {
2761 x = cmfdb(&sw); /* Parse something */
2762 if (x < 0) { /* Error */
2765 } else if (cmresult.fcode == _CMKEY) {
2768 if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
2769 printf("?This switch does not take an argument\n");
2773 if (!getval && (cmgkwflgs() & CM_ARG)) {
2774 printf("?This switch requires an argument\n");
2778 switch (k = cmresult.nresult) {
2781 if (c == ':' || c == '=') {
2782 if ((y = cmnum("How many backup files to keep",
2783 "1",10,&z,xxstring)) < 0) {
2788 if (z < 0 || z > MAXKEEP) {
2789 printf("?Please specify a number between 0 and %d\n",
2810 #endif /* CK_TTGWSIZ */
2829 if ((x = cmdate("File-time","",&s,0,xxstring)) < 0) {
2831 printf("?Date-time required\n");
2839 case PU_AFT: makestr(&pu_aft,s); break;
2840 case PU_BEF: makestr(&pu_bef,s); break;
2841 case PU_NAF: makestr(&pu_naf,s); break;
2842 case PU_NBF: makestr(&pu_nbf,s); break;
2847 if ((x = cmnum("File size in bytes","0",10,&y,xxstring)) < 0) {
2852 switch (cmresult.nresult) {
2853 case PU_SMA: minsize = y; break;
2854 case PU_LAR: maxsize = y; break;
2864 if ((x = cmfld("Pattern","",&s,xxstring)) < 0) {
2866 printf("?Pattern required\n");
2879 case PU_RECU: /* /RECURSIVE */
2882 #endif /* RECURSIVE */
2884 printf("?Not implemented yet - \"%s\"\n",atmbuf);
2888 } else if (cmresult.fcode == _CMIFI) {
2890 } else if (cmresult.fcode == _CMCFM) {
2899 ckmakmsg(line,LINBUFSIZ,cmresult.sresult,".~[1-9]*~",NULL,NULL);
2901 ckmakmsg(line,LINBUFSIZ,cmresult.sresult,".~*~",NULL,NULL);
2902 #endif /* CKREGEX */
2905 ckstrncpy(line,"*.~[1-9]*~",LINBUFSIZ);
2907 ckstrncpy(line,"*.~*~",LINBUFSIZ);
2908 #endif /* CKREGEX */
2911 if ((x = cmcfm()) < 0) {
2916 /* Parse finished - now action */
2920 printf("?File deletion by guests not permitted.\n");
2924 #endif /* CK_LOGIN */
2927 if (paging < 0) /* /[NO]PAGE not given */
2928 paging = xaskmore; /* so use prevailing */
2929 #endif /* CK_TTGWSIZ */
2933 printf("Purging %s, keeping %d...%s\n",
2936 simulate ? " (SIMULATION)" : "");
2940 if (recursive) flags |= ZX_RECURSE;
2941 n = nzxpand(line,flags); /* Get list of backup files */
2942 if (tokeep < 1) { /* Deleting all of them... */
2943 for (i = 0; i < n; i++) {
2944 if (fs) if (fileselect(mtchs[i],
2945 pu_aft,pu_bef,pu_naf,pu_nbf,
2946 minsize,maxsize,0,8,pxlist) < 1) {
2948 printf(" %s (SKIPPED)\n",mtchs[i]);
2951 if (++lines > cmd_rows - 3) {
2952 if (!askmore()) goto xpurge; else lines = 0;
2954 #endif /* CK_TTGWSIZ */
2960 ckmakmsg(tmpbuf,TMPBUFSIZ," Delete ",mtchs[i],"?",NULL);
2961 x = getyesno(tmpbuf,1);
2965 case 2: goto xpurge;
2968 x = deleting ? zdelet(mtchs[i]) : 0;
2971 printf(" %s (%s)\n", mtchs[i],deleting ? "OK" : "SELECTED");
2976 printf(" %s (FAILED)\n", mtchs[i]);
2979 if (listing && paging)
2980 if (++lines > cmd_rows - 3) {
2981 if (!askmore()) goto xpurge; else lines = 0;
2983 #endif /* CK_TTGWSIZ */
2987 if (n < tokeep) { /* Not deleting any */
2990 printf(" Matches = %d: Not enough to purge.\n");
2994 /* General case - delete some but not others */
2996 sh_sort(mtchs,NULL,n,0,0,filecase); /* Alphabetize the list (ESSENTIAL) */
2998 g = 0; /* Start of current group */
2999 for (i = 0; i < n; i++) { /* Go thru sorted file list */
3000 x = znext(namebuf); /* Get next file */
3001 if (x < 1 || !namebuf[0] || i == n - 1) /* No more? */
3002 done = 1; /* NOTE: 'done' must be 0 or 1 only */
3003 if (fs) if (fileselect(namebuf,
3004 pu_aft,pu_bef,pu_naf,pu_nbf,
3005 minsize,maxsize,0,8,pxlist) < 1) {
3007 printf(" %s (SKIPPED)\n",namebuf);
3008 if (++lines > cmd_rows - 3)
3009 if (!askmore()) goto xpurge; else lines = 0;
3014 if ((m = bkupnum(namebuf,&z)) < 0) /* This file's backup number. */
3016 for (j = 0; j < tokeep; j++) { /* Insert in list. */
3018 for (k = tokeep - 1; k > j; k--)
3025 if (done || (i > 0 && ckstrcmp(namebuf,basebuf,z,1))) {
3026 if (i + done - g > tokeep) { /* Do we have enough to purge? */
3027 min = xx[tokeep-1]; /* Yes, lowest backup number to keep */
3028 debug(F111,"dopurge group",basebuf,min);
3029 for (j = g; j < i + done; j++) { /* Go through this group */
3030 x = bkupnum(mtchs[j],&z); /* Get file backup number */
3031 if (x > 0 && x < min) { /* Below minimum? */
3032 x = deleting ? zdelet(mtchs[j]) : 0;
3033 if (x < 0) errors++;
3035 printf(" %s (%s)\n",
3037 ((x < 0) ? "ERROR" :
3038 (deleting ? "DELETED" : "SELECTED"))
3041 } else if (listing) /* Not below minimum - keep this one */
3042 printf(" %s (KEPT)\n",mtchs[j]);
3044 if (listing && paging)
3045 if (++lines > cmd_rows - 3) {
3046 if (!askmore()) goto xpurge; else lines = 0;
3048 #endif /* CK_TTGWSIZ */
3050 } else if (listing && paging) { /* Not enough to purge */
3051 printf(" %s.~*~ (KEPT)\n",basebuf);
3053 if (++lines > cmd_rows - 3) {
3054 if (!askmore()) goto xpurge; else lines = 0;
3056 #endif /* CK_TTGWSIZ */
3058 for (j = 0; j < tokeep; j++) /* Clear the backup number list */
3060 g = i; /* Reset the group pointer */
3062 if (done) /* No more files, done. */
3064 strncpy(basebuf,namebuf,z); /* Set basename of this file */
3067 xpurge: /* Common exit point */
3068 if (g_matchdot > -1) {
3069 matchdot = g_matchdot; /* Restore these... */
3072 if (rc < 0) return(rc); /* Parse error */
3074 printf("Files purged: %d%s\n",
3076 deleting ? "" : " (not really)"
3078 return(success = count > 0 ? 1 : (errors > 0) ? 0 : 1);
3080 #endif /* CKPURGE */
3085 doxdis(which) int which; { /* 1 = Kermit, 2 = FTP */
3094 #endif /* COMMENT */
3096 if ((x = cmkey(fdtab,nfdtab,"file transfer display style","",
3100 if ((y = cmkey(fdftab,2,"","thermometer",xxstring)) < 0)
3102 #endif /* CK_PCT_BAR */
3103 if ((z = cmcfm()) < 0) return(z);
3105 if (x == XYFD_C) { /* FULLSCREEN */
3108 extern char * trmbuf; /* Real curses */
3110 #endif /* MYCURSES */
3111 #endif /* COMMENT */
3113 if (nolocal) /* Nothing to do in this case */
3114 return(success = 1);
3120 debug(F110,"doxdis TERM",s,0);
3123 if (*s && trmbuf) { /* Don't call tgetent */
3124 z = tgetent(trmbuf,s); /* if trmbuf not allocated */
3125 debug(F111,"doxdis tgetent",s,z);
3128 debug(F110,"doxdis tgetent skipped",s,0);
3131 printf("Sorry, terminal type unknown: \"%s\"\n",s);
3132 return(success = 0);
3135 #endif /* MYCURSES */
3138 #endif /* COMMENT */
3142 #endif /* CK_PCT_BAR */
3144 line[0] = '\0'; /* (What's this for?) */
3146 #endif /* CK_CURSES */
3147 if (which == 1) /* It's OK. */
3153 return(success = 1);
3155 #endif /* NOLOCAL */
3159 setfil(rmsflg) int rmsflg; {
3162 #endif /* COMMENT */
3165 if ((y = cmkey(rfiltab,nrfilp,"Remote file parameter","",
3168 printf("?Remote file parameter required\n");
3174 if ((y = cmkey(filtab,nfilp,"File parameter","",xxstring)) < 0)
3180 #ifdef COMMENT /* Not needed */
3181 case XYFILB: /* Blocksize */
3182 if ((y = cmnum("file block size",ckitoa(DBLKSIZ),10,&z,xxstring)) < 0)
3184 if ((x = cmcfm()) < 0) return(x);
3186 sstate = setgen('S', "311", ckitoa(z), "");
3187 return((int) sstate);
3190 return(success = 1);
3192 #endif /* COMMENT */
3195 case XYFILS: /* Byte size */
3196 if ((y = cmnum("file byte size (7 or 8)","8",10,&z,xxstring)) < 0)
3198 if (z != 7 && z != 8) {
3199 printf("\n?The choices are 7 and 8\n");
3202 if ((y = cmcfm()) < 0) return(y);
3203 if (z == 7) fmask = 0177;
3204 else if (z == 8) fmask = 0377;
3205 return(success = 1);
3208 case XYFILC: { /* Character set */
3209 char * csetname = NULL;
3211 r_cset, s_cset, afcset[]; /* SEND CHARACTER-SET AUTO or MANUAL */
3214 cmfdbi(&kw, /* First FDB - command switches */
3216 rmsflg ? "server character-set name" : "", /* help */
3218 "", /* addtl string data */
3219 nfilc, /* addtl numeric data 1: tbl size */
3220 0, /* addtl numeric data 2: 0 = keyword */
3221 xxstring, /* Processing function */
3222 fcstab, /* Keyword table */
3223 rmsflg ? &fl : NULL /* Pointer to next FDB */
3225 cmfdbi(&fl, /* Anything that doesn't match */
3229 "", /* addtl string data */
3230 0, /* addtl numeric data 1 */
3231 0, /* addtl numeric data 2 */
3236 if ((x = cmfdb(&kw)) < 0)
3238 if (cmresult.fcode == _CMKEY) {
3239 x = cmresult.nresult;
3240 csetname = fcsinfo[x].keyword;
3242 ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
3245 if ((z = cmcfm()) < 0) return(z);
3247 sstate = setgen('S', "320", csetname, "");
3248 return((int) sstate);
3251 if (s_cset == XMODE_A) /* If SEND CHARACTER-SET is AUTO */
3252 if (x > -1 && x <= MAXFCSETS)
3253 if (afcset[x] > -1 && afcset[x] <= MAXTCSETS)
3254 tcharset = afcset[x]; /* Pick corresponding xfer charset */
3255 setxlatype(tcharset,fcharset); /* Translation type */
3256 /* If I say SET FILE CHARACTER-SET blah, I want to be blah! */
3257 r_cset = XMODE_M; /* Don't switch incoming set! */
3258 x = fcsinfo[fcharset].size; /* Also set default x-bit charset */
3259 if (x == 128) /* 7-bit... */
3261 else if (x == 256) /* 8-bit... */
3263 return(success = 1);
3265 #endif /* NOCSETS */
3268 case XYFILD: /* Display */
3269 return(doxdis(1)); /* 1 == kermit */
3270 #endif /* NOLOCAL */
3273 case XYFILA: /* End-of-line */
3278 else if (NLCHAR == 012)
3280 if ((x = cmkey(eoltab, neoltab,
3281 "local text-file line terminator",s,xxstring)) < 0)
3284 if ((x = cmkey(eoltab, neoltab,
3285 "local text-file line terminator","crlf",xxstring)) < 0)
3288 if ((z = cmcfm()) < 0) return(z);
3290 return(success = 1);
3293 case XYFILN: /* Names */
3294 if ((x = cmkey(fntab,nfntab,"how to handle filenames","converted",
3297 if ((z = cmcfm()) < 0) return(z);
3299 sstate = setgen('S', "301", ckitoa(1 - x), "");
3300 return((int) sstate);
3302 ptab[protocol].fncn = x; /* Set structure */
3303 fncnv = x; /* Set variable */
3304 f_save = x; /* And set "permanent" variable */
3305 return(success = 1);
3308 case XYFILR: /* Record length */
3309 if ((y = cmnum("file record length",
3310 ckitoa(DLRECL),10,&z,xxstring)) < 0)
3312 if ((x = cmcfm()) < 0) return(x);
3314 sstate = setgen('S', "312", ckitoa(z), "");
3315 return((int) sstate);
3318 return(success = 1);
3322 case XYFILO: /* Organization */
3323 if ((x = cmkey(forgtab,nforg,"file organization","sequential",
3326 if ((y = cmcfm()) < 0) return(y);
3328 sstate = setgen('S', "314", ckitoa(x), "");
3329 return((int) sstate);
3332 return(success = 1);
3334 #endif /* COMMENT */
3336 #ifdef COMMENT /* Not needed */
3337 case XYFILF: /* Format */
3338 if ((x = cmkey(frectab,nfrec,"file record format","stream",
3341 if ((y = cmcfm()) < 0) return(y);
3343 sstate = setgen('S', "313", ckitoa(x), "");
3344 return((int) sstate);
3347 return(success = 1);
3349 #endif /* COMMENT */
3352 case XYFILP: /* Printer carriage control */
3353 if ((x = cmkey(fcctab,nfcc,"file carriage control","newline",
3356 if ((y = cmcfm()) < 0) return(y);
3358 sstate = setgen('S', "315", ckitoa(x), "");
3359 return((int) sstate);
3362 return(success = 1);
3364 #endif /* COMMENT */
3367 case XYFILT: /* Type */
3368 if ((x = cmkey(rmsflg ? rfttab : fttab,
3369 rmsflg ? nrfttyp : nfttyp,
3370 "type of file transfer","text",xxstring)) < 0)
3374 /* Allow VMS users to choose record format for binary files */
3375 if ((x == XYFT_B) && (rmsflg == 0)) {
3376 if ((x = cmkey(fbtab,nfbtyp,"VMS record format","fixed",
3381 if ((y = cmcfm()) < 0) return(y);
3385 (void) mac_setfildflg(binary);
3389 /* Allow for LABELED in VMS & OS/2 */
3390 sstate = setgen('S', "300", ckitoa(x), "");
3391 return((int) sstate);
3394 return(success = 1);
3400 case XYFILX: /* Collision Action */
3401 if ((x = cmkey(colxtab,ncolx,"Filename collision action","backup",
3404 if ((y = cmcfm()) < 0) return(y);
3407 /* Don't let guests change existing files */
3408 printf("?This command not valid for guests\n");
3411 #endif /* CK_LOGIN */
3413 /* Not appropriate - DISABLE DELETE only refers to server */
3414 if ((x == XYFX_X || x == XYFX_B || x == XYFX_U || x == XYFX_A) &&
3415 (!ENABLED(en_del))) {
3416 printf("?Sorry, file deletion is disabled.\n");
3419 #endif /* COMMENT */
3421 ptab[protocol].fnca = x;
3423 sstate = setgen('S', "302", ckitoa(fncact), "");
3424 return((int) sstate);
3426 if (fncact == XYFX_R) ckwarn = 1; /* FILE WARNING implications */
3427 if (fncact == XYFX_X) ckwarn = 0; /* ... */
3428 return(success = 1);
3431 case XYFILW: /* Warning/Write-Protect */
3432 if ((x = seton(&ckwarn)) < 0) return(x);
3437 return(success = 1);
3440 case XYFILL: /* LABELED FILE parameters */
3441 if ((x = cmkey(lbltab,nlblp,"Labeled file feature","",
3444 if ((success = seton(&y)) < 0)
3446 if (y) /* Set or reset the selected bit */
3447 lf_opts |= x; /* in the options bitmask. */
3451 #endif /* CK_LABELED */
3453 case XYFILI: { /* INCOMPLETE */
3454 extern struct keytab ifdatab[];
3456 if ((y = cmkey(ifdatab,3,"","auto",xxstring)) < 0) return(y);
3457 if ((x = cmcfm()) < 0) return(x);
3459 sstate = setgen('S',
3461 y == 0 ? "0" : (y == 1 ? "1" : "2"),
3464 return((int) sstate);
3467 return(success = 1);
3472 case XYFILG: { /* Download directory */
3483 if ((x = cmdir("Name of local directory, or carriage return",
3491 if ((x = cmdir("Name of PC disk and/or directory,\n\
3492 or press the Enter key to use current directory",
3493 "",&s,xxstring)) < 0 ) {
3499 x = ckstrncpy(temp,zhome(),32);
3500 if (x > 0) if (temp[x-1] != ':') { temp[x] = ':'; temp[x+1] = NUL; }
3501 if ((x = cmtxt("Name of Macintosh volume and/or folder,\n\
3502 or press the Return key for the desktop on the boot disk",
3503 temp,&s, xxstring)) < 0 )
3506 if ((x = cmdir("Name of local directory, or carriage return",
3507 "", &s, xxstring)) < 0 ) {
3514 debug(F110,"download dir",s,0);
3518 printf("?Wildcards not allowed in directory name\n");
3524 if ((fnp = zfnqfp(s,TMPBUFSIZ - 1,tmpbuf))) {
3526 if ((int) strlen(fnp->fpath) > 0)
3529 debug(F110,"download zfnqfp",s,0);
3532 ckstrncpy(line,s,LINBUFSIZ); /* Make a safe copy */
3534 if ((x = cmcfm()) < 0) /* Get confirmation */
3540 /* Don't let guests change existing files */
3541 printf("?This command not valid for guests\n");
3544 #endif /* CK_LOGIN */
3548 #ifdef datageneral /* AOS/VS */
3549 if (s[x-1] == ':') /* homdir ends in colon, */
3550 s[x-1] = NUL; /* and "dir" doesn't like that... */
3552 #ifdef OS2ORUNIX /* Unix or K-95... */
3553 if ((x < (LINBUFSIZ - 2)) && /* Add trailing dirsep */
3554 (s[x-1] != '/')) { /* if none present. */
3555 s[x] = '/'; /* Note that Windows path has */
3556 s[x+1] = NUL; /* been canonicalized to forward */
3557 } /* slashes at this point. */
3558 #endif /* OS2ORUNIX */
3559 #endif /* datageneral */
3562 makestr(&dldir,NULL); /* dldir is NULL when not assigned */
3564 return(success = 1);
3566 #endif /* CK_TMPDIR */
3572 case XYFILV: { /* EOF */
3573 extern int eofmethod;
3574 if ((x = cmkey(eoftab,3,"end-of-file detection method","",
3577 if ((y = cmcfm()) < 0)
3580 return(success = 1);
3582 #endif /* CK_CTRLZ */
3586 case XYFILH: { /* OUTPUT */
3587 extern int zofbuffer, zobufsize, zofblock;
3589 extern char * zoutbuffer;
3590 #endif /* DYNAMIC */
3592 if ((x = cmkey(zoftab,nzoftab,"output file writing method","",
3595 if (x == ZOF_BUF || x == ZOF_NBUF) {
3596 if ((y = cmnum("output buffer size","32768",10,&z,xxstring)) < 0)
3599 printf("?Bad size - %d\n", z);
3603 if ((y = cmcfm()) < 0) return(y);
3607 zofbuffer = (x == ZOF_BUF);
3612 zofblock = (x == ZOF_BLK);
3616 if (zoutbuffer) free(zoutbuffer);
3617 if (!(zoutbuffer = (char *)malloc(z))) {
3618 printf("MEMORY ALLOCATION ERROR - FATAL\n");
3619 doexit(BAD_EXIT,-1);
3623 if (z <= OBUFSIZE) {
3626 printf("?Sorry, %d is too big - %d is the maximum\n",z,OBUFSIZE);
3629 #endif /* DYNAMIC */
3630 return(success = 1);
3635 case XYFIBP: /* BINARY-PATTERN */
3636 case XYFITP: { /* TEXT-PATTERN */
3637 char * tmp[FTPATTERNS];
3639 while (n < FTPATTERNS) {
3641 if ((x = cmfld("Pattern","",&s,xxstring)) < 0)
3643 ckstrncpy(line,s,LINBUFSIZ);
3645 makestr(&(tmp[n++]),s);
3647 if (x == -3) x = cmcfm();
3648 for (i = 0; i <= n; i++) {
3651 makestr(&(binpatterns[i]),tmp[i]);
3653 makestr(&(txtpatterns[i]),tmp[i]);
3657 if (y == XYFIBP) /* Null-terminate the list */
3658 makestr(&(binpatterns[i]),NULL);
3660 makestr(&(txtpatterns[i]),NULL);
3664 case XYFIPA: /* PATTERNS */
3665 if ((x = setonaut(&patterns)) < 0)
3667 return(success = 1);
3668 #endif /* PATTERNS */
3672 case XYFILU: { /* UCS */
3673 extern int ucsorder, ucsbom, byteorder;
3674 if ((x = cmkey(ucstab,nucstab,"","",xxstring)) < 0)
3678 if ((y = cmkey(botab,nbotab,
3680 byteorder ? "little-endian" : "big-endian",
3685 if ((x = cmcfm()) < 0)
3688 return(success = 1);
3690 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0)
3692 if ((x = cmcfm()) < 0)
3695 return(success = 1);
3700 #endif /* UNICODE */
3703 case XYF_INSP: { /* SCAN (INSPECTION) */
3704 extern int filepeek, nscanfile;
3705 if ((x = cmkey(onoff,2,"","on",xxstring)) < 0)
3708 if ((y = cmnum("How much to scan",ckitoa(SCANFILEBUF),
3709 10,&z,xxstring)) < 0)
3712 if ((y = cmcfm()) < 0)
3717 return(success = 0);
3721 return(success = 1);
3724 #endif /* datageneral */
3729 if ((y = cmkey(fdfltab,nfdflt,"","",xxstring)) < 0)
3731 if (y == 7 || y == 8) {
3733 s = fcsinfo[dcset7].keyword;
3735 s = fcsinfo[dcset8].keyword;
3736 if ((x = cmkey(fcstab,nfilc,"character-set",s,xxstring)) < 0)
3739 ckstrncpy(line,fcsinfo[x].keyword,LINBUFSIZ);
3741 #endif /* NOCSETS */
3742 if ((z = cmcfm()) < 0)
3747 if (fcsinfo[x].size != 128) {
3748 printf("%s - Not a 7-bit set\n",s);
3754 if (fcsinfo[x].size != 256) {
3755 printf("%s - Not an 8-bit set\n",s);
3760 #endif /* NOCSETS */
3764 return(success = 1);
3767 case 9997: /* FASTLOOKUPS */
3768 return(success = seton(&stathack));
3773 case XYF_LSIZ: { /* LISTSIZE */
3775 y = cmnum("Maximum number of filenames","",10,&x,xxstring);
3776 if ((x = setnum(&zz,x,y,-1)) < 0)
3778 if (zsetfil(zz,3) < 0) {
3779 printf("?Memory allocation failure\n");
3782 return(success = 1);
3784 case XYF_SSPA: { /* STRINGSPACE */
3786 y = cmnum("Number of characters for filename list",
3788 if ((x = setnum(&zz,x,y,-1)) < 0)
3790 if (zsetfil(zz,1) < 0) {
3791 printf("?Memory allocation failure\n");
3794 return(success = 1);
3797 #endif /* DYNAMIC */
3801 printf("?unexpected file parameter\n");
3808 /* MS-DOS KERMIT compatibility modes */
3811 if ((y = cmkey(msktab,nmsk,"MS-DOS Kermit compatibility mode",
3812 "keycodes",xxstring)) < 0) return(y);
3817 return(seton(&mskcolors));
3818 #endif /* COMMENT */
3820 return(seton(&mskkeys));
3821 default: /* Shouldn't get here. */
3831 extern int ttnum; /* Last Telnet Terminal Type sent */
3832 extern int ttnumend; /* Has end of list been found */
3834 if ((x = cmkey(ttyptab,nttyp,"","vt320",xxstring)) < 0)
3836 if ((y = cmcfm()) < 0)
3840 /* So we send the correct terminal name to the host if it asks for it */
3841 ttnum = -1; /* Last Telnet Terminal Type sent */
3842 ttnumend = 0; /* end of list not found */
3844 return(success = 1);
3847 "\n Sorry, this version of C-Kermit does not support the SET TERMINAL TYPE\n");
3849 " command. Type \"help set terminal\" for further information.\n");
3851 return(success = 0);
3855 static char iactbuf[132];
3859 switch (tt_idleact) {
3860 case IDLE_RET: return("return");
3861 case IDLE_EXIT: return("exit");
3862 case IDLE_HANG: return("hangup");
3864 case IDLE_TNOP: return("Telnet NOP");
3865 case IDLE_TAYT: return("Telnet AYT");
3871 k = ckstrncpy(iactbuf,"output ",132);
3876 if (!*p) return("output (nothing)");
3877 while ((c = *p++) && n < 131) {
3885 } else if ((c > 31 && c < 127) || c > 159) {
3892 sprintf(q,"\\{%d}",c);
3913 default: return("unknown");
3916 #endif /* CKTIDLE */
3920 setlclcharset(x) int x; {
3922 tcsl = y; /* Local character set */
3924 for (i = 0; i < 4; i++) {
3926 x = G[i].designation;
3927 G[i].c1 = (x != tcsl) && cs_is_std(x);
3928 x = G[i].def_designation;
3929 G[i].def_c1 = (x != tcsl) && cs_is_std(x);
3935 setremcharset(x, z) int x, z; {
3939 KuiSetProperty( KUI_TERM_REMCHARSET, (long) x, (long) z ) ;
3945 #endif /* UNICODE */
3946 { /* TRANSPARENT? */
3948 tcsr = tcsl; /* Make both sets the same */
3951 tt_utf8 = 0; /* Turn off UTF8 flag */
3952 tcsr = tcsl = dec_kbd = TX_TRANSP; /* No translation */
3955 if (!cs_is_nrc(tcsl)) {
3956 G[0].def_designation = G[0].designation = TX_ASCII;
3958 G[0].def_c1 = G[0].c1 = FALSE;
3960 G[0].national = FALSE;
3962 for (i = cs_is_nrc(tcsl) ? 0 : 1; i < 4; i++) {
3963 G[i].def_designation = G[i].designation = tcsl;
3965 G[i].def_c1 = G[i].c1 = FALSE;
3966 switch (cs_size(G[i].designation)) { /* 94, 96, or 128 */
3969 G[i].size = G[i].def_size = cs96;
3972 G[i].size = G[i].def_size = cs94;
3975 G[i].size = G[i].def_size = csmb;
3978 G[i].national = cs_is_nrc(x);
3981 tcsr = tcsl; /* Make both sets the same */
3982 for (i = 0; i < 4; i++) {
3983 G[i].def_designation = G[i].designation = FC_TRANSP;
3985 G[i].size = G[i].def_size = cs96;
3986 G[i].c1 = G[i].def_c1 = FALSE;
3991 G[i].national = FALSE;
3999 else if (x == TX_UTF8) {
4001 tt_utf8 = 1; /* Turn it on if we are UTF8 */
4007 tcsr = x; /* Remote character set */
4009 tt_utf8 = 0; /* Turn off UTF8 flag */
4012 if (z == TT_GR_ALL) {
4016 #endif /* UNICODE */
4017 for (i = 0; i < 4; i++) {
4019 if ( i == 0 && !cs_is_nrc(x) ) {
4020 G[0].designation = G[0].def_designation = FC_USASCII;
4021 G[0].size = G[0].def_size = cs94;
4024 G[i].def_designation = G[i].designation = x;
4025 switch (cs_size(x)) { /* 94, 96, or 128 */
4028 G[i].size = G[i].def_size = cs96;
4031 G[i].size = G[i].def_size = cs94;
4034 G[i].size = G[i].def_size = csmb;
4037 G[i].national = cs_is_nrc(x);
4039 G[i].c1 = G[i].def_c1 = x != tcsl && cs_is_std(x);
4042 } else if (z == TT_GR_KBD) { /* Keyboard only */
4044 #endif /* UNICODE */
4045 } else { /* Specific Gn */
4046 G[z].def_designation = G[z].designation = x;
4048 switch (cs_size(x)) { /* 94, 96, or 128 */
4051 G[z].size = G[z].def_size = cs96;
4054 G[z].size = G[z].def_size = cs94;
4057 G[z].size = G[z].def_size = csmb;
4060 G[z].c1 = G[z].def_c1 = x != tcsl && cs_is_std(x);
4061 G[z].national = cs_is_nrc(x);
4065 tcsr = x; /* Remote character set */
4068 #endif /* NOCSETS */
4071 setcmask(x) int x; {
4074 } else if (x == 8) {
4079 KuiSetProperty(KUI_TERM_CMASK,x,0);
4085 setautodl(x,y) int x,y; {
4089 KuiSetProperty(KUI_TERM_AUTODOWNLOAD,x?(y?2:1):0,0);
4092 #endif /* CK_AUTODL */
4099 KuiSetProperty(KUI_TERM_URL_HIGHLIGHT,x,0);
4108 KuiSetProperty(KUI_TERM_PRINTERCOPY,x,0);
4117 extern int colorreset, user_erasemode;
4119 if ((y = cmkey(trmtab,ntrm,"", "",xxstring)) < 0) return(y);
4121 printf("\n?Sorry, not implemented yet. Please use the Settings menu.\n");
4126 if ((y = cmcfm()) < 0) return(y);
4127 printf("?Sorry, command disabled.\r\n");
4128 return(success = 0);
4133 case XYTBYT: /* SET TERMINAL BYTESIZE */
4134 if ((y = cmnum("bytesize for terminal connection","8",10,&x,
4137 if (x != 7 && x != 8) {
4138 printf("\n?The choices are 7 and 8\n");
4139 return(success = 0);
4141 if ((y = cmcfm()) < 0) return(y);
4144 if (IS97801(tt_type_mode))
4147 return(success = 1);
4149 case XYTSO: /* SET TERMINAL LOCKING-SHIFT */
4150 return(seton(&sosi));
4152 case XYTNL: /* SET TERMINAL NEWLINE-MODE */
4153 return(seton(&tnlm));
4157 if ((x = cmkey(ttycoltab,ncolors,"","terminal",xxstring)) < 0)
4159 else if (x == TTCOLRES) {
4160 if ((y = cmkey(ttcolmodetab,ncolmode,
4161 "","default-color",xxstring)) < 0)
4163 if ((z = cmcfm()) < 0)
4166 return(success = 1);
4167 } else if (x == TTCOLERA) {
4168 if ((y = cmkey(ttcolmodetab,ncolmode,"",
4169 "current-color",xxstring)) < 0)
4171 if ((z = cmcfm()) < 0)
4175 } else { /* No parse error */
4177 fg = cmkey(ttyclrtab, nclrs,
4179 "color for screen border" :
4180 "foreground color and then background color"),
4184 if (x != TTCOLBOR) {
4185 if ((bg = cmkey(ttyclrtab,nclrs,
4186 "background color","blue",xxstring)) < 0)
4189 if ((y = cmcfm()) < 0)
4193 colornormal = fg | bg << 4;
4198 colorreverse = fg | bg << 4;
4201 coloritalic = fg | bg << 4;
4204 colorunderline = fg | bg << 4;
4207 colorgraphic = fg | bg << 4;
4210 colordebug = fg | bg << 4;
4213 colorstatus = fg | bg << 4;
4216 colorhelp = fg | bg << 4;
4222 colorselect = fg | bg << 4;
4225 printf("%s - invalid\n",cmdbuf);
4229 scrninitialized[VTERM] = 0;
4232 return(success = 1);
4234 case XYTCUR: { /* SET TERMINAL CURSOR */
4235 extern int cursorena[];
4236 extern int cursoron[] ; /* Cursor state on/off */
4237 if ((x = cmkey(ttycurtab,ncursors,"","underline",xxstring)) < 0)
4239 if ((z = cmkey(curontab,ncuron,"","on",xxstring)) < 0)
4241 if ((y = cmcfm()) < 0) return(y);
4242 tt_cursor = tt_cursor_usr = x;
4244 cursorena[VTERM] = tt_cursorena_usr = 1;
4245 tt_cursor_blink = 0;
4247 cursorena[VTERM] = tt_cursorena_usr = z;/* turn cursor on/off */
4248 tt_cursor_blink = 1;
4250 cursoron[VTERM] = FALSE; /* Force newcursor to restore the cursor */
4251 return(success = 1);
4255 case XYTTYP: /* SET TERMINAL TYPE */
4256 return(settrmtyp());
4259 case XYTARR: /* SET TERMINAL ARROW-KEYS */
4260 if ((x = cmkey(akmtab,2,"","",xxstring)) < 0) return(x);
4261 if ((y = cmcfm()) < 0) return(y);
4262 tt_arrow = x; /* TTK_NORM / TTK_APPL; see ckuusr.h */
4263 return(success = 1);
4265 case XYTKPD: /* SET TERMINAL KEYPAD-MODE */
4266 if ((x = cmkey(kpmtab,2,"","",xxstring)) < 0) return(x);
4267 if ((y = cmcfm()) < 0) return(y);
4268 tt_keypad = x; /* TTK_NORM / TTK_APPL; see ckuusr.h */
4269 return(success = 1);
4271 case XYTUNX: { /* SET TERM UNIX-MODE (DG) */
4272 extern int dgunix,dgunix_usr;
4274 dgunix_usr = dgunix;
4277 case XYTKBMOD: { /* SET TERM KEYBOARD MODE */
4278 extern int tt_kb_mode;
4279 if ((x = cmkey(kbmodtab,
4282 "special keyboard mode for terminal emulation",
4286 if ((y = cmcfm()) < 0) return(y);
4288 return(success = 1);
4291 case XYTWRP: /* SET TERMINAL WRAP */
4292 return(seton(&tt_wrap));
4295 if ((y = cmnum("CONNECT scrollback buffer size, lines","2000",10,&x,
4298 /* The max number of lines is the RAM */
4299 /* we can actually dedicate to a */
4300 /* scrollback buffer given the maximum */
4301 /* process memory space of 512MB */
4302 if (x < 256 || x > 2000000L) {
4303 printf("\n?The size must be between 256 and 2,000,000.\n");
4304 return(success = 0);
4306 if ((y = cmcfm()) < 0) return(y);
4307 tt_scrsize[VTERM] = x;
4309 return(success = 1);
4313 case XYTCS: { /* SET TERMINAL CHARACTER-SET */
4315 /* set terminal character-set <remote> <local> */
4322 "remote terminal character-set","",xxstring)) < 0)
4331 if ((y = cmcfm()) < 0) /* Confirm the command */
4334 if ( isunicode() && x == TX_TRANSP ) {
4335 /* If we are in unicode display mode then transparent
4336 * only affects the output direction. We need to know
4337 * the actual remote character set in order to perform
4338 * the tcsr -> ucs2 translation for display.
4346 if (x == FC_TRANSP) {
4347 if ((y = cmcfm()) < 0) /* Confirm the command */
4351 #endif /* UNICODE */
4353 /* Not transparent or UTF8, so get local set to translate it into */
4356 y = os2getcp(); /* Default is current code page */
4358 case 437: s = "cp437"; break;
4359 case 850: s = "cp850"; break;
4360 case 852: s = "cp852"; break;
4361 case 857: s = "cp857"; break;
4362 case 858: s = "cp858"; break;
4363 case 862: s = "cp862"; break;
4364 case 866: s = "cp866"; break;
4365 case 869: s = "cp869"; break;
4366 case 1250: s = "cp1250"; break;
4367 case 1251: s = "cp1251"; break;
4368 case 1252: s = "cp1252"; break;
4369 case 1253: s = "cp1253"; break;
4370 case 1254: s = "cp1254"; break;
4371 case 1255: s = "cp1255"; break;
4372 case 1256: s = "cp1256"; break;
4373 case 1257: s = "cp1257"; break;
4374 case 1258: s = "cp1258"; break;
4378 If the user has loaded a font with SET TERMINAL FONT then we want
4379 to change the default code page to the font that was loaded.
4381 if (tt_font != TTF_ROM) {
4382 for (y = 0; y < ntermfont; y++ ) {
4383 if (term_font[y].kwval == tt_font) {
4384 s = term_font[y].kwd;
4389 #endif /* PCFONTS */
4390 #else /* Not K95... */
4391 s = fcsinfo[fcharset].keyword;
4400 "local character-set",s,xxstring)) < 0)
4405 printf("?UTF8 may not be used as a local character set.\r\n");
4408 #endif /* UNICODE */
4410 if ((z = cmkey(graphsettab,ngraphset,
4411 "DEC VT intermediate graphic set","all",xxstring)) < 0)
4414 if ((eol = cmcfm()) < 0)
4415 return(eol); /* Confirm the command */
4417 /* End of command parsing - actions begin */
4420 return(success = 1);
4422 #endif /* NOCSETS */
4425 case XYTLCS: /* SET TERMINAL LOCAL-CHARACTER-SET */
4426 /* set terminal character-set <local> */
4427 s = getdcset(); /* Get display character-set name */
4434 "local character-set",s,xxstring)) < 0)
4439 printf("?UTF8 may not be used as a local character set.\r\n");
4442 #endif /* UNICODE */
4443 if ((z = cmcfm()) < 0) return(z); /* Confirm the command */
4445 /* End of command parsing - action begins */
4448 return(success = 1);
4449 #endif /* NOCSETS */
4453 case XYTUNI: /* SET TERMINAL UNICODE */
4454 return(seton(&tt_unicode));
4455 #endif /* UNICODE */
4457 case XYTRCS: /* SET TERMINAL REMOTE-CHARACTER-SET */
4458 /* set terminal character-set <remote> <Graphic-set> */
4465 "remote terminal character-set","",xxstring)) < 0)
4474 if ((y = cmcfm()) < 0) /* Confirm the command */
4477 if ( isunicode() && x == TX_TRANSP ) {
4478 /* If we are in unicode display mode then transparent
4479 * only affects the output direction. We need to know
4480 * the actual remote character set in order to perform
4481 * the tcsr -> ucs2 translation for display.
4488 if (x == FC_TRANSP) {
4489 if ((y = cmcfm()) < 0) /* Confirm the command */
4492 #endif /* UNICODE */
4495 if ((z = cmkey(graphsettab,ngraphset,
4496 "DEC VT intermediate graphic set","all",xxstring)) < 0)
4499 if ((y = cmcfm()) < 0) /* Confirm the command */
4502 /* Command parsing ends here */
4505 return(success = 1);
4506 #endif /* NOCSETS */
4508 case XYTEC: /* SET TERMINAL ECHO */
4509 if ((x = cmkey(rltab,nrlt,"which side echos during CONNECT",
4510 "remote", xxstring)) < 0) return(x);
4511 if ((y = cmcfm()) < 0) return(y);
4514 #endif /* NETCONN */
4516 return(success = 1);
4518 case XYTESC: /* SET TERM ESC */
4519 if ((x = cmkey(nabltab,nnabltab,"","enabled",xxstring)) < 0)
4521 if ((y = cmcfm()) < 0) return(y);
4525 case XYTCRD: /* SET TERMINAL CR-DISPLAY */
4526 if ((x = cmkey(crdtab,2,"", "normal", xxstring)) < 0) return(x);
4527 if ((y = cmcfm()) < 0) return(y);
4529 return(success = 1);
4532 case XYTANS: { /* SET TERMINAL ANSWERBACK */
4534 NOTE: We let them enable and disable the answerback sequence, but we
4535 do NOT let them change it, and we definitely do not let the host set it.
4536 This is a security feature.
4538 As of 1.1.8 we allow the SET TERM ANSWERBACK MESSAGE <string> to be
4539 used just as MS-DOS Kermit does. C0 and C1 controls as well as DEL
4540 are not allowed to be used as characters. They are translated to
4541 underscore. This may not be set by APC.
4543 if ((x = cmkey(anbktab,nansbk,"", "off", xxstring)) < 0)
4546 if ((y = cmcfm()) < 0)
4549 return(success = 1);
4550 } else if ( x == 2 || x == 3) {
4552 extern int safeanswerbk;
4553 extern char useranswerbk[];
4554 if ((y = cmtxt("Answerback extension","",&s,xxstring)) < 0)
4556 if (apcactive == APC_LOCAL ||
4557 (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH)))
4558 return(success = 0);
4561 /* Safe Answerback's don't have C0/C1 chars */
4562 for (z = 0; z < len; z++) {
4563 if ((s[z] & 0x7F) <= SP || (s[z] & 0x7F) == DEL)
4564 useranswerbk[z] = '_';
4566 useranswerbk[z] = s[z];
4568 useranswerbk[z] = '\0';
4569 safeanswerbk = 1 ; /* TRUE */
4571 ckstrncpy(useranswerbk,s,60); /* (see ckocon.c) */
4572 safeanswerbk = 0; /* FALSE */
4575 return(success = 1);
4577 return(success = 0);
4583 if ((y = cmkey(apctab,napctab,
4584 "application program command execution","",
4587 if ((x = cmcfm()) < 0)
4589 if (apcactive == APC_LOCAL ||
4590 (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH)))
4591 return(success = 0);
4593 return(success = 1);
4596 case XYTAUTODL: /* AUTODOWNLOAD */
4597 if ((y = cmkey(adltab,nadltab,"Auto-download options","",
4603 if ((x = cmcfm()) < 0)
4608 if ((x = cmcfm()) < 0)
4610 setautodl(TAD_ON,1);
4613 if ((y = cmkey(adlerrtab,nadlerrtab,"","", xxstring)) < 0)
4615 if ((x = cmcfm()) < 0)
4621 if ((y = cmkey(adlxtab,nadlxtab,"","", xxstring)) < 0)
4625 if ((y = cmkey(adlc0tab,nadlc0tab,"",
4626 "processed-by-emulator",xxstring)) < 0)
4628 if ((x = cmcfm()) < 0)
4633 if ((y = cmkey(adldtab,nadldtab,"","packet",xxstring)) < 0)
4635 if ((x = cmcfm()) < 0)
4640 if ((y = cmtxt("Kermit start string","KERMIT READY TO SEND...",
4644 adl_kstr = strdup(s);
4650 if ((y = cmkey(adlxtab,nadlxtab,"","",xxstring)) < 0)
4654 if ((y = cmkey(adlc0tab,nadlc0tab,"",
4655 "processed-by-emulator",xxstring)) < 0)
4657 if ((x = cmcfm()) < 0)
4662 if ((y = cmkey(adldtab,nadldtab,"","packet",xxstring)) < 0)
4664 if ((x = cmcfm()) < 0)
4669 if ((y = cmtxt("","rz\\{13}",&s,xxstring)) < 0)
4672 adl_zstr = strdup(s);
4678 return(success = 1);
4680 #endif /* CK_AUTODL */
4685 return(success = setbell());
4687 case XYTMBEL: /* MARGIN-BELL */
4688 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
4690 if ((z = cmnum("Column at which to set margin bell",
4691 "72",10,&x,xxstring)) < 0)
4694 if ((z = cmcfm()) < 0) return(z);
4697 return(success = 1);
4701 case XYTIDLE: /* IDLE-SEND */
4702 case XYTITMO: /* IDLE-TIMEOUT */
4703 if ((z = cmnum("seconds of idle time to wait, or 0 to disable",
4704 "0",10,&x,xxstring)) < 0)
4707 if ((y = cmtxt("string to send, may contain kverbs and variables",
4708 "\\v(newline)",&s,xxstring)) < 0)
4710 tt_idlesnd_tmo = x; /* (old) */
4711 tt_idlelimit = x; /* (new) */
4712 makestr(&tt_idlestr,brstrip(s)); /* (new) */
4713 tt_idlesnd_str = tt_idlestr; /* (old) */
4714 tt_idleact = IDLE_OUT; /* (new) */
4716 if ((y = cmcfm()) < 0)
4723 return(success = 1);
4725 case XYTIACT: { /* SET TERM IDLE-ACTION */
4726 if ((y = cmkey(idlacts,nidlacts,"","",xxstring)) < 0)
4728 if (y == IDLE_OUT) {
4729 if ((x = cmtxt("string to send, may contain kverbs and variables"
4730 , "\\v(newline)",&s,xxstring)) < 0)
4732 makestr(&tt_idlestr,brstrip(s)); /* (new) */
4733 tt_idlesnd_str = tt_idlestr; /* (old) */
4735 if ((x = cmcfm()) < 0)
4739 return(success = 1);
4741 #endif /* CKTIDLE */
4743 case XYTDEB: /* TERMINAL DEBUG */
4744 y = seton(&x); /* Go parse ON or OFF */
4745 if (y > 0) /* Command succeeded? */
4750 case XYTASCRL: /* SET TERMINAL AUTOSCROLL */
4751 y = seton(&autoscroll);
4754 case XYTAPAGE: /* SET TERMINAL AUTOPAGE */
4755 y = seton(&wy_autopage);
4758 case XYTROL: /* SET TERMINAL ROLL */
4759 if ((y = cmkey(rolltab,nroll,"scrollback mode","insert",xxstring))<0)
4761 if (y == TTR_KEYS) {
4762 if ((x = cmkey(rollkeytab,nrollkey,"","send",xxstring))<0)
4764 if ((z = cmcfm()) < 0) return(z);
4765 tt_rkeys[VTERM] = x;
4767 if ((x = cmcfm()) < 0) return(x);
4770 return(success = 1);
4772 case XYTCTS: /* SET TERMINAL TRANSMIT-TIMEOUT */
4773 y = cmnum("Maximum seconds to allow CTS off during CONNECT",
4774 "5",10,&x,xxstring);
4775 return(setnum(&tt_ctstmo,x,y,10000));
4777 case XYTCPG: { /* SET TERMINAL CODE-PAGE */
4780 y = cmnum("PC code page to use during terminal emulation",
4781 ckitoa(os2getcp()),10,&x,xxstring);
4782 if ((x = setnum(&cp,x,y,11000)) < 0) return(x);
4783 if (os2setcp(cp) != 1) {
4787 "Sorry, Windows 95 does not support code page switching\n");
4791 "Sorry, %d is not a valid code page for this system.\n",cp);
4794 /* Force the terminal character-sets conversions to be updated */
4795 for ( i = 0; i < 4; i++ )
4800 case XYTPAC: /* SET TERMINAL OUTPUT-PACING */
4802 "Pause between sending each character during CONNECT, milliseconds",
4803 "-1",10,&x,xxstring);
4804 return(setnum(&tt_pacing,x,y,10000));
4807 case XYTMOU: { /* SET TERMINAL MOUSE */
4808 int old_mou = tt_mouse;
4809 if ((x = seton(&tt_mouse)) < 0)
4811 if (tt_mouse != old_mou)
4818 #endif /* OS2MOUSE */
4824 "number of columns in display window during CONNECT",
4826 "number of columns on your screen",
4828 "80",10,&x,xxstring)) < 0)
4830 if ((y = cmcfm()) < 0) return(y);
4832 return(success = os2_settermwidth(x));
4833 #else /* Not OS/2 */
4835 return(success = 1);
4842 "number of rows in display window during CONNECT, not including status line",
4843 tt_status[VTERM]?"24":"25",
4845 "24","number of rows on your screen",
4847 10,&x,xxstring)) < 0)
4849 if ((y = cmcfm()) < 0) return(y);
4852 return (success = os2_settermheight(x));
4853 #else /* Not OS/2 */
4855 return(success = 1);
4859 case XYTPRN: { /* Print Mode */
4860 extern bool xprint, aprint, cprint, uprint;
4861 if ((y = cmkey(prnmtab,nprnmtab,"","off", xxstring)) < 0) return(y);
4862 if ((x = cmcfm()) < 0) return(x);
4865 if (cprint || uprint || aprint || xprint)
4867 cprint = xprint = uprint = 0;
4871 if (!(cprint || uprint || aprint || xprint))
4874 cprint = xprint = uprint = 0;
4877 if (!(cprint || uprint || aprint || xprint))
4881 xprint = uprint = 0;
4884 if (!(cprint || uprint || aprint || xprint))
4888 xprint = cprint = 0;
4896 extern int tt_print;
4897 if ((x = seton(&tt_print)) < 0)
4899 return(success = 1);
4906 extern int decscnm, decscnm_usr;
4907 if ((y = cmkey(normrev,4,"",
4908 decscnm_usr?"reverse":"normal",
4912 if ((x = cmcfm()) < 0) return(x);
4914 if (decscnm != decscnm_usr)
4919 if ((y = cmkey(onoff,2,"",tt_diff_upd?"on":"off",
4920 xxstring)) < 0) return(y);
4921 if ((x = cmcfm()) < 0) return(x);
4926 if ((mode = cmkey(scrnupd,nscrnupd,"","fast",xxstring)) < 0) {
4930 "Pause between FAST screen updates in CONNECT mode, milliseconds",
4931 "100",10,&x,xxstring
4933 if (x < 0 || x > 1000 ) {
4935 "\n?The update rate must be between 0 and 1000 milliseconds.\n"
4937 return(success = 0);
4939 if ((y = cmcfm()) < 0) return(y);
4941 updmode = tt_updmode = mode;
4942 return(setnum(&tt_update,x,y,10000));
4946 if ((x = cmkey(termctrl,ntermctrl,"","7",xxstring)) < 0) {
4949 if ((y = cmcfm()) < 0)
4953 send_c1 = send_c1_usr = TRUE;
4957 send_c1 = send_c1_usr = FALSE;
4961 return(success = TRUE);
4966 if ( !IsOS2FullScreen() ) {
4968 "\n?SET TERMINAL FONT is only supported in Full Screen sessions.\n");
4969 return(success = FALSE);
4972 if ((x = cmkey(term_font,ntermfont,"","default",xxstring)) < 0) {
4975 if ((y = cmcfm()) < 0) return(y);
4976 if ( !os2LoadPCFonts() ) {
4978 return(success = TRUE);
4981 "\n?PCFONTS.DLL is not available in CKERMIT executable directory.\n");
4982 return(success = FALSE);
4990 return(setguifont()); /* ckuus3.c */
4993 #endif /* PCFONTS */
4996 extern int pheight, marginbot, cmd_rows, cmd_cols;
4997 if ((x = cmkey(tvctab,ntvctab,"",isWin95()?"win95-safe":"enabled",
5000 if ((y = cmcfm()) < 0) return(y);
5002 if (x != tt_modechg) {
5005 /* When disabled the heights of all of the virtual screens */
5006 /* must be equal to the physical height of the console */
5007 /* window and may not be changed. */
5008 /* The width of the window may not be altered. */
5009 tt_modechg = TVC_ENA; /* Temporary */
5010 if (marginbot > pheight-(tt_status[VTERM]?1:0))
5011 marginbot = pheight-(tt_status[VTERM]?1:0);
5012 tt_szchng[VCMD] = 1 ;
5013 tt_rows[VCMD] = pheight;
5018 tt_szchng[VTERM] = 2 ;
5019 tt_rows[VTERM] = pheight - (tt_status[VTERM]?1:0);
5025 /* When enabled the physical height of the console windows */
5026 /* should be adjusted to the height of the virtual screen */
5027 /* The width may be set to anything. */
5032 /* Win95-safe mode allows the physical height to change */
5033 /* but restricts it to a width of 80 and a height equal to */
5034 /* 25, 43, or 50. Must be adjusted now. */
5035 /* The virtual heights must be equal to the above. */
5036 if (pheight != 25 && pheight != 43 && pheight != 50) {
5039 else if (pheight < 43)
5046 tt_modechg = TVC_ENA; /* Temporary */
5048 tt_szchng[VCMD] = 1;
5056 marginbot = y-(tt_status[VTERM]?1:0);
5057 tt_szchng[VTERM] = 2;
5058 tt_rows[VTERM] = y - (tt_status[VTERM]?1:0);
5059 tt_cols[VTERM] = 80;
5065 return(success = 1);
5067 return(success = 0);
5071 extern int marginbot;
5072 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5073 if ((x = cmcfm()) < 0) return(x);
5074 if (y != tt_status[VTERM] || y != tt_status_usr[VTERM]) {
5075 /* Might need to fixup the margins */
5076 if ( marginbot == VscrnGetHeight(VTERM)-(tt_status[VTERM]?1:0) )
5082 tt_status_usr[VTERM] = tt_status[VTERM] = y;
5084 tt_szchng[VTERM] = 2;
5086 VscrnInit(VTERM); /* Height set here */
5088 if (TELOPT_ME(TELOPT_NAWS))
5092 if (TELOPT_ME(TELOPT_NAWS))
5094 #endif /* RLOGCODE */
5096 if (TELOPT_ME(TELOPT_NAWS))
5098 #endif /* SSHBUILTIN */
5100 tt_szchng[VTERM] = 1;
5102 VscrnInit(VTERM); /* Height set here */
5104 if (TELOPT_ME(TELOPT_NAWS))
5108 if (TELOPT_ME(TELOPT_NAWS))
5110 #endif /* RLOGCODE */
5112 if (TELOPT_ME(TELOPT_NAWS))
5114 #endif /* SSHBUILTIN */
5123 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5124 if ((x = cmcfm()) < 0) return(x);
5131 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5132 if ((x = cmcfm()) < 0) return(x);
5137 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5138 if ((x = cmcfm()) < 0) return(x);
5143 if ((y = cmkey(ttyseobtab,2,"","us_cr",xxstring)) < 0) return(y);
5144 if ((x = cmcfm()) < 0) return(x);
5149 int done = 0, attr = VT_CHAR_ATTR_NORMAL;
5151 if ((x = cmkey(onoff,2,"","on",xxstring)) < 0)
5156 if ((y = cmkey(ttyprotab,nprotect,"",
5157 z?"done":"reverse",xxstring)) < 0)
5164 attr |= VT_CHAR_ATTR_BLINK;
5167 attr |= VT_CHAR_ATTR_REVERSE;
5170 attr |= VT_CHAR_ATTR_ITALIC;
5173 attr |= VT_CHAR_ATTR_UNDERLINE;
5176 attr |= VT_CHAR_ATTR_BOLD;
5179 attr |= VT_CHAR_ATTR_DIM;
5182 attr |= VT_CHAR_ATTR_INVISIBLE;
5187 z = 1; /* One attribute has been chosen */
5190 if ((z = cmcfm()) < 0) return(z);
5193 tt_url_hilite_attr = attr;
5197 if ((x = cmkey(ttyattrtab,nattrib,"","underline",xxstring)) < 0)
5201 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5202 if ((x = cmcfm()) < 0) return(x);
5205 if ( !trueblink && trueunderline ) {
5207 printf("Warning: Underline being simulated by color.\n");
5214 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5215 if ((x = cmcfm()) < 0) return(x);
5220 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5221 if ((x = cmcfm()) < 0) return(x);
5226 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5227 if ((x = cmcfm()) < 0) return(x);
5230 if (!trueblink && trueunderline) {
5232 printf("Warning: True blink mode is active.\n");
5238 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5239 if ((x = cmcfm()) < 0) return(x);
5243 case TTATTPRO: { /* Set default Protected Character attribute */
5244 extern vtattrib WPattrib; /* current WP Mode Attrib */
5245 extern vtattrib defWPattrib; /* default WP Mode Attrib */
5246 vtattrib wpa = {0,0,0,0,0,1,0,0,0,0,0}; /* Protected */
5251 if ((y = cmkey(ttyprotab,nprotect,"",
5252 x?"done":"dim",xxstring)) < 0)
5257 case TTATTBLI: /* Blinking doesn't work */
5258 wpa.blinking = TRUE;
5261 wpa.reversed = TRUE;
5267 wpa.underlined = TRUE;
5276 wpa.invisible = TRUE ;
5282 x = 1; /* One attribute has been chosen */
5284 if ((x = cmcfm()) < 0) return(x);
5285 WPattrib = defWPattrib = wpa;
5291 case XYTKEY: { /* SET TERMINAL KEY */
5293 int clear = 0, deflt = 0;
5296 int kc = -1; /* Key code */
5297 int litstr = 0; /* Literal String? */
5298 char *s = NULL; /* Key binding */
5300 char *p = NULL; /* Worker */
5301 #endif /* NOKVERBS */
5306 struct FDB kw,sw,nu,cm;
5308 defevt.type = error;
5310 if ((t = cmkey(ttkeytab,nttkey,"","",xxstring)) < 0)
5312 cmfdbi(&nu, /* First FDB - command switches */
5314 "/literal, keycode, or action",
5316 "", /* addtl string data */
5317 10, /* addtl numeric data 1: radix */
5318 0, /* addtl numeric data 2: 0 */
5319 xxstring, /* Processing function */
5320 NULL, /* Keyword table */
5321 &sw /* Pointer to next FDB */
5323 cmfdbi(&sw, /* Second FDB - switches */
5327 "", /* addtl string data */
5328 nstrmswitab, /* addtl numeric data 1: tbl size */
5329 4, /* addtl numeric data 2: 4 = cmswi */
5330 xxstring, /* Processing function */
5331 strmswitab, /* Keyword table */
5332 &kw /* Pointer to next FDB */
5334 cmfdbi(&kw, /* Third FDB - command switches */
5336 "/literal, keycode, or action",
5338 "", /* addtl string data */
5339 nstrmkeytab, /* addtl numeric data 1: tbl size */
5340 0, /* addtl numeric data 2 */
5341 xxstring, /* Processing function */
5342 strmkeytab, /* Keyword table */
5343 &cm /* Pointer to next FDB */
5345 cmfdbi(&cm, /* Final FDB - Confirmation */
5349 "", /* addtl string data */
5350 0, /* addtl numeric data 1: tbl size */
5351 0, /* addtl numeric data 2: 4 = cmswi */
5352 xxstring, /* Processing function */
5353 NULL, /* Keyword table */
5354 NULL /* Pointer to next FDB */
5357 x = cmfdb(&nu); /* Parse something */
5361 switch (cmresult.fcode) {
5363 printf(" Press key to be defined: ");
5364 conbin((char)escape); /* Put terminal in binary mode */
5365 os2gks = 0; /* Turn off Kverb preprocessing */
5366 kc = congks(0); /* Get character or scan code */
5367 os2gks = 1; /* Turn on Kverb preprocessing */
5368 concb((char)escape); /* Restore terminal to cbreak mode */
5369 if (kc < 0) { /* Check for error */
5370 printf("?Error reading key\n");
5373 shokeycode(kc,t); /* Show current definition */
5374 flag = 1; /* Remember it's a multiline command */
5377 kc = cmresult.nresult;
5380 if (cmresult.fdbaddr == &sw) { /* Switch */
5381 if (cmresult.nresult == 0)
5383 } else if (cmresult.fdbaddr == &kw) { /* Keyword */
5384 if (cmresult.nresult == 0)
5388 if ((x = cmcfm()) < 0)
5400 /* Normal SET TERMINAL KEY <terminal> <scancode> <value> command... */
5405 if (kc < 0 || kc >= KMSIZE) {
5406 printf("?key code must be between 0 and %d\n", KMSIZE - 1);
5410 printf("Sorry, %d is the CONNECT-mode escape character\n",kc);
5415 cmsavp(psave,PROMPTL);
5416 cmsetp(" Enter new definition: ");
5420 if (flag) prompt(NULL);
5421 if ((y = cmtxt("key definition,\n\
5422 or Ctrl-C to cancel this command,\n\
5423 or Enter to restore default definition",
5425 if (flag) /* Handle parse errors */
5432 p = s; /* Save this place */
5433 #endif /* NOKVERBS */
5435 If the definition included any \Kverbs, quote the backslash so the \Kverb
5436 will still be in the definition when the key is pressed. We don't do this
5437 in zzstring(), because \Kverbs are valid only in this context and nowhere
5440 We use this code active for all versions that support SET KEY, even if they
5441 don't support \Kverbs, because otherwise \K would behave differently for
5444 for (x = 0, y = 0; s[x]; x++, y++) { /* Convert \K to \\K */
5446 (s[x] == 'K' || s[x] == 'k')
5449 if ((x == 1 && s[x-1] == CMDQ) ||
5450 (x > 1 && s[x-1] == CMDQ && s[x-2] != CMDQ)) {
5451 line[y++] = CMDQ; /* Make it \\K */
5453 if (x > 1 && s[x-1] == '{' && s[x-2] == CMDQ) {
5454 line[y-1] = CMDQ; /* Have \{K */
5455 line[y++] = '{'; /* Make it \\{K */
5460 line[y++] = NUL; /* Terminate */
5461 s = line + y + 1; /* Point to after it */
5462 x = LINBUFSIZ - (int) strlen(line) - 1; /* Get remaining space */
5463 if ((x < (LINBUFSIZ / 2)) ||
5464 (zzstring(line, &s, &x) < 0)) { /* Expand variables, etc. */
5465 printf("?Key definition too long\n");
5466 if (flag) cmsetp(psave);
5469 s = line + y + 1; /* Point to result. */
5473 Special case: see if the definition starts with a \Kverb.
5474 If it does, point to it with p, otherwise set p to NULL.
5479 p = (*p == 'k' || *p == 'K') ? p + 1 : NULL;
5481 #endif /* NOKVERBS */
5483 switch (strlen(s)) { /* Action depends on length */
5484 case 0: /* Clear individual key def */
5489 defevt.type = key; /* Single character */
5490 defevt.key.scancode = *s;
5493 default: /* Character string */
5496 y = xlookup(kverbs,p,nkverbs,&x); /* Look it up */
5497 /* Need exact match */
5498 debug(F101,"set key kverb lookup",0,y);
5500 defevt.type = kverb;
5501 defevt.kverb.id = y;
5505 #endif /* NOKVERBS */
5507 defevt.type = literal;
5508 defevt.literal.string = (char *) malloc(strlen(s)+1);
5509 if (defevt.literal.string)
5510 strcpy(defevt.literal.string, s); /* safe */
5512 defevt.type = macro;
5513 defevt.macro.string = (char *) malloc(strlen(s)+1);
5514 if (defevt.macro.string)
5515 strcpy(defevt.macro.string, s); /* safe */
5519 insertkeymap(t, kc, defevt);
5522 initvik = 1; /* Update VIK table */
5527 case XYTPCTERM: /* PCTERM Keyboard Mode */
5528 if ((x = seton(&tt_pcterm)) < 0) return(x);
5529 return(success = 1);
5535 if ((y = cmtxt("String to trigger automatic return to command mode",
5536 "",&s,xxstring)) < 0)
5538 makelist(s,tt_trigger,TRIGGERS);
5540 #endif /* CK_TRIGGER */
5544 if ((y = cmnum("ASCII value to use for spacing attributes",
5545 "32",10,&x,xxstring)) < 0)
5547 if ((y = cmcfm()) < 0) return(y);
5549 return(success = 1);
5551 case XYTKBDGL: { /* SET TERM KBD-FOLLOWS-GL/GR */
5552 extern int tt_kb_glgr; /* from ckoco3.c */
5553 if ((x = seton(&tt_kb_glgr)) < 0)
5555 return(success = 1);
5558 case XYTVTLNG: /* SET TERM DEC-LANGUAGE */
5559 if ((y = cmkey(vtlangtab,nvtlangtab,"VT language",
5560 IS97801(tt_type_mode)?"german":"north-american",
5563 if ((x = cmcfm()) < 0) return(x);
5565 /* A real VT terminal would use the language to set the */
5566 /* default keyboard language for both 8-bit multinational */
5567 /* and 7-bit national modes. For 8-bit mode it would */
5568 /* set the terminal character-set to the ISO set if it */
5569 /* is not already set. */
5570 /* Latin-1 can be replaced by DEC Multinational */
5572 case VTL_NORTH_AM: /* North American */
5573 /* Multinational: Latin-1 */
5574 /* National: US_ASCII */
5577 dec_kbd = TX_8859_1;
5580 /* Multinational: Latin-1 */
5581 /* National: UK_ASCII */
5583 dec_nrc = TX_BRITISH;
5584 dec_kbd = TX_8859_1;
5589 /* Multinational: Latin-1 */
5590 /* National: FR_ASCII */
5592 dec_nrc = TX_FRENCH;
5593 dec_kbd = TX_8859_1;
5596 /* Multinational: Latin-1 */
5597 /* National: FC_ASCII */
5599 dec_nrc = TX_CN_FRENCH;
5600 dec_kbd = TX_8859_1;
5604 /* Multinational: Latin-1 */
5605 /* National: NO_ASCII */
5607 dec_nrc = TX_NORWEGIAN;
5608 dec_kbd = TX_8859_1;
5611 /* Multinational: Latin-1 */
5612 /* National: FI_ASCII */
5614 dec_nrc = TX_FINNISH;
5615 dec_kbd = TX_8859_1;
5618 /* Multinational: Latin-1 */
5619 /* National: GR_ASCII */
5621 dec_nrc = TX_GERMAN;
5622 dec_kbd = TX_8859_1;
5625 /* Multinational: Latin-1 */
5626 /* National: DU_ASCII */
5629 dec_kbd = TX_8859_1;
5632 /* Multinational: Latin-1 */
5633 /* National: IT_ASCII */
5635 dec_nrc = TX_ITALIAN;
5636 dec_kbd = TX_8859_1;
5640 /* Multinational: Latin-1 */
5641 /* National: CH_ASCII */
5644 dec_kbd = TX_8859_1;
5647 /* Multinational: Latin-1 */
5648 /* National: SW_ASCII */
5650 dec_nrc = TX_SWEDISH;
5651 dec_kbd = TX_8859_1;
5654 /* Multinational: Latin-1 */
5655 /* National: SP_ASCII */
5657 dec_nrc = TX_SPANISH;
5658 dec_kbd = TX_8859_1;
5661 /* Multinational: Latin-1 */
5662 /* National: Portugese ASCII */
5664 dec_nrc = TX_PORTUGUESE;
5665 dec_kbd = TX_8859_1;
5668 /* Multinational: Latin-Hebrew / DEC-Hebrew */
5669 /* National: DEC 7-bit Hebrew */
5672 dec_kbd = TX_8859_8;
5675 /* Multinational: Latin-Greek / DEC-Greek */
5676 /* National: DEC Greek NRC */
5677 /* is ELOT927 equivalent to DEC Greek???? */
5679 dec_nrc = TX_ELOT927;
5680 dec_kbd = TX_8859_7;
5685 /* Multinational: Latin-Turkish / DEC-Turkish */
5686 /* National: DEC 7-bit Turkish */
5688 #endif /* COMMENT */
5690 /* Multinational: Latin-2 */
5691 /* National: no national mode */
5693 dec_nrc = TX_HUNGARIAN;
5694 dec_kbd = TX_8859_2;
5700 /* Multinational: Latin-2 */
5701 /* National: no national mode */
5704 dec_kbd = TX_8859_2;
5707 /* Multinational: Latin-Cyrillic / KOI-8 */
5708 /* National: DEC Russian NRC */
5711 dec_kbd = TX_8859_5;
5714 /* Multinational: not listed in table */
5715 /* National: not listed in table */
5718 dec_kbd = TX_8859_1;
5722 /* Multinational: Latin-2 */
5723 /* National: SCS NRC */
5725 #endif /* COMMENT */
5727 return(success = 0);
5729 if (IS97801(tt_type_mode)) {
5730 SNI_bitmode(cmask == 0377 ? 8 : 7);
5732 return(success = 1);
5733 #endif /* NOCSETS */
5735 case XYTVTNRC: { /* SET TERM DEC-NRC-MODE */
5736 extern int decnrcm_usr, decnrcm; /* from ckoco3.c */
5737 if ((x = seton(&decnrcm_usr)) < 0)
5739 decnrcm = decnrcm_usr;
5740 return(success = 1);
5742 case XYTSNIPM: { /* SET TERM SNI-PAGEMODE */
5743 extern int sni_pagemode, sni_pagemode_usr;
5744 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5745 if ((x = cmcfm()) < 0) return(x);
5746 sni_pagemode_usr = sni_pagemode = y;
5747 return(success = 1);
5749 case XYTSNISM: { /* SET TERM SNI-SCROLLMODE */
5750 extern int sni_scroll_mode, sni_scroll_mode_usr;
5751 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5752 if ((x = cmcfm()) < 0) return(x);
5753 sni_scroll_mode_usr = sni_scroll_mode = y;
5754 return(success = 1);
5756 case XYTSNICC: { /* SET TERM SNI-CH.CODE */
5757 extern int sni_chcode_usr;
5758 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5759 if ((x = cmcfm()) < 0) return(x);
5762 return(success = 1);
5764 case XYTSNIFV: { /* SET TERM SNI-FIRMWARE-VERSIONS */
5765 extern CHAR sni_kbd_firmware[], sni_term_firmware[];
5766 CHAR kbd[7],term[7];
5768 if ((x = cmfld("Keyboard Firmware Version",sni_kbd_firmware,
5771 if ((int)strlen(s) != 6) {
5772 printf("?Sorry - the firmware version must be 6 digits long\n");
5775 for (i = 0; i < 6; i++) {
5776 if (!isdigit(s[i])) {
5777 printf("?Sorry - the firmware version can only contain digits [0-9]\n");
5783 if ((x = cmfld("Terminal Firmware Version",sni_term_firmware,
5786 if ((int)strlen(s) != 6) {
5787 printf("?Sorry - the firmware version must be 6 digits long\n");
5790 for (i = 0; i < 6; i++) {
5791 if (!isdigit(s[i])) {
5792 printf("?Sorry - the firmware version can only contain digits [0-9]\n");
5796 ckstrncpy(term,s,7);
5797 if ((x = cmcfm()) < 0) return(x);
5799 ckstrncpy(sni_kbd_firmware,kbd,7);
5800 ckstrncpy(sni_term_firmware,term,7);
5801 return(success = 1);
5804 case XYTLSP: { /* SET TERM LINE-SPACING */
5805 if ((x = cmfld("Line Spacing","1",&s, xxstring)) < 0)
5807 if (isfloat(s,0) < 1) { /* (sets floatval) */
5808 printf("?Integer or floating-point number required\n");
5811 if (floatval < 1.0 || floatval > 3.0) {
5812 printf("?Value must within the range 1.0 and 3.0 (inclusive)\n");
5815 if ((x = cmcfm()) < 0) return(x);
5817 tt_linespacing[VCMD] = tt_linespacing[VTERM] = floatval;
5818 return(success = 1);
5820 printf("?Sorry, Line-spacing is only supported in K95G.EXE.\n");
5821 return(success = 0);
5826 default: /* Shouldn't get here. */
5832 This was supposed to shut up picky compilers but instead it makes
5833 most compilers complain about "statement not reached".
5836 #endif /* COMMENT */
5845 extern char usertitle[];
5846 if ((y = cmtxt("title text","",&s,xxstring)) < 0)
5850 printf("?Sorry, command disabled.\r\n");
5851 return(success = 0);
5855 ckstrncpy(usertitle,s,64);
5860 static struct keytab dialertab[] = { /* K95 Dialer types */
5864 static int ndialer = 2;
5869 int clear = 0, deflt = 0;
5870 int kc; /* Key code */
5871 char *s = NULL; /* Key binding */
5873 char *p = NULL; /* Worker */
5874 #endif /* NOKVERBS */
5880 defevt.type = error;
5882 if (( x = cmkey(dialertab, ndialer,
5883 "Kermit-95 dialer work-arounds",
5884 "", xxstring)) < 0 )
5887 case 0: /* Backspace */
5894 printf("Illegal value in setdialer()\n");
5897 if ((y = cmtxt("Key definition","",&s,xxstring)) < 0)
5902 printf("?Sorry, command disabled.\r\n");
5903 return(success = 0);
5908 p = s; /* Save this place */
5909 #endif /* NOKVERBS */
5911 If the definition included any \Kverbs, quote the backslash so the \Kverb
5912 will still be in the definition when the key is pressed. We don't do this
5913 in zzstring(), because \Kverbs are valid only in this context and nowhere
5916 We use this code active for all versions that support SET KEY, even if they
5917 don't support \Kverbs, because otherwise \K would behave differently for
5920 for (x = 0, y = 0; s[x]; x++, y++) { /* Convert \K to \\K */
5922 (s[x] == 'K' || s[x] == 'k')
5925 if ((x == 1 && s[x-1] == CMDQ) ||
5926 (x > 1 && s[x-1] == CMDQ && s[x-2] != CMDQ)) {
5927 line[y++] = CMDQ; /* Make it \\K */
5929 if (x > 1 && s[x-1] == '{' && s[x-2] == CMDQ) {
5930 line[y-1] = CMDQ; /* Have \{K */
5931 line[y++] = '{'; /* Make it \\{K */
5936 line[y++] = NUL; /* Terminate */
5937 s = line + y + 1; /* Point to after it */
5938 x = LINBUFSIZ - (int) strlen(line) - 1; /* Calculate remaining space */
5939 if ((x < (LINBUFSIZ / 2)) ||
5940 (zzstring(line, &s, &x) < 0)) { /* Expand variables, etc. */
5941 printf("?Key definition too long\n");
5944 s = line + y + 1; /* Point to result. */
5948 Special case: see if the definition starts with a \Kverb.
5949 If it does, point to it with p, otherwise set p to NULL.
5954 p = (*p == 'k' || *p == 'K') ? p + 1 : NULL;
5956 #endif /* NOKVERBS */
5958 /* Clear the definition for SET KEY */
5959 if (macrotab[kc]) { /* Possibly free old macro from key. */
5960 free((char *)macrotab[kc]);
5961 macrotab[kc] = NULL;
5963 keymap[kc] = (KEY) kc;
5965 /* Now reprogram the default value for all terminal types */
5966 /* remember to treat Wyse and Televideo terminals special */
5967 /* because of their use of Kverbs for Backspace and Enter */
5968 for (t = 0; t <= TT_MAX; t++) {
5969 if ( ISDG200(t) && kc == 264) {
5970 extern char * udkfkeys[] ;
5971 if (kc == 264) { /* \Kdgbs */
5974 udkfkeys[83] = strdup(s);
5976 } else if (ISWYSE(t) || ISTVI(t)) {
5977 extern char * udkfkeys[] ;
5978 if (kc == 264) { /* \Kwybs or \Ktvibs */
5981 udkfkeys[32] = strdup(s);
5983 if (kc == 269) { /* \Kwyenter and \Kwyreturn */
5984 if (udkfkeys[39]) /* \Ktvienter and \Ktvireturn */
5986 udkfkeys[39] = strdup(s);
5989 udkfkeys[49] = strdup(s);
5992 switch (strlen(s)) { /* Action depends on length */
5993 case 0: /* Clear individual key def */
5997 defevt.type = key; /* Single character */
5998 defevt.key.scancode = *s;
6000 default: /* Character string */
6003 y = xlookup(kverbs,p,nkverbs,&x); /* Look it up */
6004 /* Exact match req'd */
6005 debug(F101,"set key kverb lookup",0,y);
6007 defevt.type = kverb;
6008 defevt.kverb.id = y;
6012 #endif /* NOKVERBS */
6013 defevt.type = macro;
6014 defevt.macro.string = (char *) malloc(strlen(s)+1);
6015 if (defevt.macro.string)
6016 strcpy(defevt.macro.string, s); /* safe */
6019 insertkeymap( t, kc, defevt ) ;
6020 initvik = 1; /* Update VIK table */
6032 if (( y = cmkey(win95tab, nwin95,
6033 "Windows 95 specific work-arounds",
6034 "keyboard-translation",
6039 if ((y = cmkey(onoff,2,"popups are used to prompt the user for data",
6040 "on",xxstring)) < 0)
6042 if ((x = cmcfm()) < 0) return(x);
6047 if ((y = cmkey(onoff,2,"8.3 FAT file names","off",xxstring)) < 0)
6049 if ((x = cmcfm()) < 0) return(x);
6054 if ((y = cmkey(onoff,2,"\"select()\" fails on write","off",
6057 if ((x = cmcfm()) < 0) return(x);
6062 if ((y = cmkey(onoff,2,"Right-Alt is Alt-Gr","off",xxstring)) < 0)
6064 if ((x = cmcfm()) < 0) return(x);
6069 if ((y = cmkey(onoff,2,"Use Overlapped I/O","on",xxstring)) < 0)
6072 if ((x = cmnum("Maximum number of outstanding I/O requests",
6073 "10",10,&z,xxstring)) < 0)
6075 if (z < 1 || z > 7) {
6077 "?Maximum outstanding I/O requests must be between 1 and 7.\n");
6082 if ((x = cmcfm()) < 0) return(x);
6084 maxow = maxow_usr = z;
6089 printf("\n?\"Keyboard-Translation\" is no longer required.\n");
6092 if (( z = cmkey(tcstab, ntcs,
6093 "Keyboard Character Set",
6097 if ((x = cmcfm()) < 0)
6101 win95kl2 = (win95kcsi == TC_2LATIN);
6103 if (win95kcsi == TC_TRANSP) {
6107 win95kcs = xlr[win95kcsi][tx2fc(tcsl)];
6109 win95kcs = xlr[win95kcsi][tcsl];
6110 #endif /* UNICODE */
6113 #endif /* COMMENT */
6116 if ((y = cmkey(onoff,2,"Unicode-to-Lucida-Console substitutions",
6117 "on",xxstring)) < 0)
6119 if ((x = cmcfm()) < 0) return(x);
6124 if ((y = cmkey(onoff,2,"Horizontal Scan Line substitutions",
6125 "on",xxstring)) < 0)
6127 if ((x = cmcfm()) < 0) return(x);
6132 printf("Illegal value in setwin95()\n");
6143 #endif /* CK_ANSIC */
6147 if (( y = cmkey(prtytab, nprty,
6148 "priority level of terminal and communication threads",
6149 "foreground-server",
6153 if ((x = cmcfm()) < 0)
6161 #endif /* IKSDCONF */
6163 if ((y = cmcfm()) < 0) return(y);
6164 printf("?Sorry, command disabled.\r\n");
6165 return(success = 0);
6180 if ((y = cmkey(beltab,nbeltab,
6182 "how console and terminal bells should\nbe generated", "audible",
6184 "Whether Kermit should ring the terminal bell (beep)", "on",
6191 if ((y = cmcfm()) < 0) return(y);
6192 printf("?Sorry, command disabled.\r\n");
6193 return(success = 0);
6197 switch (y) { /* SET BELL */
6202 if ((x = cmcfm()) < 0)
6213 if ((x = cmkey(audibletab, naudibletab,
6214 "how audible console and terminal\nbells should be generated",
6215 "beep",xxstring))<0)
6217 if ((z = cmcfm()) < 0)
6221 /* This lets C-Kermit accept but ignore trailing K95 keywords */
6222 if ((x = cmtxt("Confirm with carriage return","",&s,xxstring)) < 0)
6236 #endif /* CK_ANSIC */
6239 int button = 0, event = 0;
6242 if ((y = cmkey(mousetab,nmtab,"","",xxstring)) < 0)
6247 if ((y = cmcfm()) < 0) return(y);
6248 printf("?Sorry, command disabled.\r\n");
6249 return(success = 0);
6253 if (y == XYM_ON) { /* MOUSE ACTIVATION */
6254 int old_mou = tt_mouse;
6255 if ((x = seton(&tt_mouse)) < 0)
6257 if (tt_mouse != old_mou)
6265 if (y == XYM_DEBUG) { /* MOUSE DEBUG */
6266 extern int MouseDebug;
6267 if ((x = seton(&MouseDebug)) < 0)
6272 if (y == XYM_CLEAR) { /* Reset Mouse Defaults */
6273 if ((x = cmcfm()) < 0) return(x);
6274 mousemapinit(-1,-1);
6275 initvik = 1; /* Update VIK Table */
6278 if (y != XYM_BUTTON) { /* Shouldn't happen. */
6279 printf("Internal parsing error\n");
6283 /* MOUSE EVENT ... */
6285 if ((button = cmkey(mousebuttontab,nmbtab,
6286 "Button number","1",
6290 if ((y = cmkey(mousemodtab,nmmtab,
6291 "Keyboard modifier","none",
6295 event |= y; /* OR in the bits */
6297 if ((y = cmkey(mclicktab,nmctab,"","click",xxstring)) < 0)
6300 /* Two bits are assigned, if neither are set then it is button one */
6302 event |= y; /* OR in the bit */
6306 if ((y = cmtxt("definition,\n\
6307 or Ctrl-C to cancel this command,\n\
6308 or Enter to restore default definition",
6313 p = s; /* Save this place */
6315 If the definition included any \Kverbs, quote the backslash so the \Kverb
6316 will still be in the definition when the key is pressed. We don't do this
6317 in zzstring(), because \Kverbs are valid only in this context and nowhere
6318 else. This code copied from SET KEY, q.v. for addt'l commentary.
6320 for (x = 0, y = 0; s[x]; x++, y++) { /* Convert \K to \\K */
6322 (s[x] == 'K' || s[x] == 'k')
6325 if ((x == 1 && s[x-1] == CMDQ) ||
6326 (x > 1 && s[x-1] == CMDQ && s[x-2] != CMDQ)) {
6327 line[y++] = CMDQ; /* Make it \\K */
6329 if (x > 1 && s[x-1] == '{' && s[x-2] == CMDQ) {
6330 line[y-1] = CMDQ; /* Have \{K */
6331 line[y++] = '{'; /* Make it \\{K */
6336 line[y++] = NUL; /* Terminate */
6337 s = line + y + 1; /* Point to after it */
6338 x = LINBUFSIZ - (int) strlen(line) - 1; /* Calculate remaining space */
6339 if ((x < (LINBUFSIZ / 2)) ||
6340 (zzstring(line, &s, &x) < 0)) { /* Expand variables, etc. */
6341 printf("?Key definition too long\n");
6344 s = line + y + 1; /* Point to result. */
6348 Special case: see if the definition starts with a \Kverb.
6349 If it does, point to it with p, otherwise set p to NULL.
6354 p = (*p == 'k' || *p == 'K') ? p + 1 : NULL;
6358 #endif /* NOKVERBS */
6360 /* free the old definition if necessary */
6361 if (mousemap[button][event].type == macro) {
6362 free( mousemap[button][event].macro.string);
6363 mousemap[button][event].macro.string = NULL;
6365 switch (strlen(s)) { /* Action depends on length */
6366 case 0: /* Reset to default binding */
6367 mousemapinit( button, event );
6369 case 1: /* Single character */
6370 mousemap[button][event].type = key;
6371 mousemap[button][event].key.scancode = *s;
6373 default: /* Character string */
6376 y = xlookup(kverbs,p,nkverbs,&x); /* Look it up */
6377 debug(F101,"set mouse kverb lookup",0,y); /* need exact match */
6379 /* Assign the kverb to the event */
6380 mousemap[button][event].type = kverb;
6381 mousemap[button][event].kverb.id = F_KVERB | y;
6385 #endif /* NOKVERBS */
6387 /* Otherwise, it's a macro, so assign the macro to the event */
6388 mousemap[button][event].type = macro;
6389 mousemap[button][event].macro.string = (MACRO) malloc(strlen(s)+1);
6390 if (mousemap[button][event].macro.string)
6391 strcpy((char *) mousemap[button][event].macro.string, s); /* safe */
6394 initvik = 1; /* Update VIK Table */
6395 if ( (button == XYM_B3) && (mousebuttoncount() < 3) && !quiet )
6397 printf("?Warning: this machine does not have a three button mouse.\n");
6402 #endif /* OS2MOUSE */
6403 #endif /* NOLOCAL */
6406 int /* SET SEND/RECEIVE */
6407 setsr(xx, rmsflg) int xx; int rmsflg; {
6409 ckstrncpy(line,"Parameter for inbound packets",LINBUFSIZ);
6411 ckstrncpy(line,"Parameter for outbound packets",LINBUFSIZ);
6414 if ((y = cmkey(rsrtab,nrsrtab,line,"",xxstring)) < 0) {
6416 printf("?Remote receive parameter required\n");
6421 if ((y = cmkey(srtab,nsrtab,line,"",xxstring)) < 0) return(y);
6424 case XYQCTL: /* CONTROL-PREFIX */
6425 if ((x = cmnum("ASCII value of control prefix","",10,&y,xxstring)) < 0)
6427 if ((x = cmcfm()) < 0) return(x);
6428 if ((y > 32 && y < 63) || (y > 95 && y < 127)) {
6430 ctlq = (CHAR) y; /* RECEIVE prefix, use with caution! */
6432 myctlq = (CHAR) y; /* SEND prefix, OK to change */
6433 return(success = 1);
6435 printf("?Illegal value for prefix character\n");
6440 if ((y = setcc("13",&z)) < 0)
6443 printf("Sorry, the legal values are 0-31\n");
6450 return(success = y);
6453 y = cmnum("Maximum number of characters in a packet","90",10,&x,
6455 if (xx == XYRECV) { /* Receive... */
6456 if ((y = setnum(&z,x,y,maxrps)) < 0)
6458 if (protocol != PROTO_K) {
6459 printf("?Sorry, this command does not apply to %s protocol.\n",
6460 ptab[protocol].p_name
6462 printf("Use SET SEND PACKET-LENGTH for XYZMODEM\n");
6466 printf("Sorry, 10 is the minimum\n");
6470 sstate = setgen('S', "401", ckitoa(z), "");
6471 return((int) sstate);
6473 if (protocol == PROTO_K) {
6474 if (z > MAXRP) z = MAXRP;
6475 y = adjpkl(z,wslotr,bigrbsiz);
6480 " Adjusting receive packet-length to %d for %d window slots\n",
6484 ptab[protocol].rpktlen = urpsiz;
6485 rpsiz = (y > 94) ? 94 : y;
6488 if ((protocol == PROTO_X || protocol == PROTO_XC) &&
6489 z != 128 && z != 1024) {
6490 printf("Sorry, bad packet length for XMODEM.\n");
6491 printf("Please use 128 or 1024.\n");
6498 } else { /* Send... */
6499 if ((y = setnum(&z,x,y,maxsps)) < 0)
6502 printf("Sorry, 10 is the minimum\n");
6505 if (protocol == PROTO_K) {
6506 if (z > MAXSP) z = MAXSP;
6507 spsiz = z; /* Set it */
6508 y = adjpkl(spsiz,wslotr,bigsbsiz);
6509 if (y != spsiz && !xcmdsrc)
6511 printf("Adjusting packet size to %d for %d window slots\n",
6516 if ((protocol == PROTO_X || protocol == PROTO_XC) &&
6517 z != 128 && z != 1024) {
6518 printf("Sorry, bad packet length for XMODEM.\n");
6519 printf("Please use 128 or 1024.\n");
6523 spsiz = spmax = spsizr = y; /* Set it and flag that it was set */
6524 spsizf = 1; /* to allow overriding Send-Init. */
6525 ptab[protocol].spktflg = spsizf;
6526 ptab[protocol].spktlen = spsiz;
6528 if (pflag && protocol == PROTO_K && !xcmdsrc) {
6529 if (z > 94 && !reliable && msgflg) {
6530 /* printf("Extended-length packets requested.\n"); */
6531 if (bctr < 2 && z > 200) printf("\
6532 Remember to SET BLOCK 2 or 3 for long packets.\n");
6534 if (speed <= 0L) speed = ttgspd();
6537 Kermit does this now itself.
6539 if (speed <= 0L && z > 200 && msgflg) {
6541 Make sure your timeout interval is long enough for %d-byte packets.\n",z);
6543 #endif /* COMMENT */
6545 return(success = y);
6550 Printable start-of-packet works for UNIX and VMS only!
6553 y = cmnum("Code for packet-start character","1",10,&x,xxstring);
6555 if ((y = setnum(&z,x,y,126)) < 0) return(y);
6557 if ((y = setcc("1",&z)) < 0)
6559 #endif /* DOOMSDAY */
6565 /* If IKS negotiation in use */
6566 if (TELOPT_U(TELOPT_KERMIT) || TELOPT_ME(TELOPT_KERMIT))
6567 tn_siks(KERMIT_SOP); /* Report change to other side */
6568 #endif /* IKS_OPTION */
6570 return(success = y);
6572 case XYNPAD: /* PADDING */
6573 y = cmnum("How many padding characters for inbound packets","0",10,&x,
6575 if ((y = setnum(&z,x,y,94)) < 0) return(y);
6580 return(success = y);
6582 case XYPADC: /* PAD-CHARACTER */
6583 if ((y = setcc("0",&z)) < 0) return(y);
6584 if (xx == XYRECV) mypadc = z; else padch = z;
6585 return(success = y);
6587 case XYTIMO: /* TIMEOUT */
6589 y = cmnum("Packet timeout interval",ckitoa(URTIME),10,&x,xxstring);
6590 if ((y = setnum(&z,x,y,94)) < 0) return(y);
6592 if (rmsflg) { /* REMOTE SET RECEIVE TIMEOUT */
6593 sstate = setgen('S', "402", ckitoa(z), "");
6594 return((int) sstate);
6595 } else { /* SET RECEIVE TIMEOUT */
6596 pkttim = z; /* Value to put in my negotiation */
6597 } /* packet for other Kermit to use */
6599 } else { /* SET SEND TIMEOUT */
6601 extern int rttflg, mintime, maxtime;
6602 int tmin = 0, tmax = 0;
6603 #endif /* CK_TIMERS */
6604 y = cmnum("Packet timeout interval",ckitoa(DMYTIM),10,&x,xxstring);
6605 if (y == -3) { /* They cancelled a previous */
6606 x = DMYTIM; /* SET SEND command, so restore */
6607 timef = 0; /* and turn off the override flag */
6611 if (y < 0) return(y);
6613 printf("?Out of range - %d\n",x);
6616 if ((z = cmkey(timotab,2,"","dynamic",xxstring)) < 0) return(z);
6618 if ((y = cmnum("Minimum timeout to allow",
6619 "1",10,&tmin,xxstring)) < 0)
6622 printf("?Out of range - %d\n",tmin);
6625 if ((y = cmnum("Maximum timeout to allow",
6626 "0",10,&tmax,xxstring)) < 0)
6628 /* 0 means let Kermit choose, < 0 means no maximum */
6630 if ((y = cmcfm()) < 0)
6632 rttflg = z; /* Round-trip timer flag */
6635 if ((y = setnum(&z,x,y,94)) < 0)
6637 #endif /* CK_TIMERS */
6638 timef = 1; /* Turn on the override flag */
6639 timint = rtimo = z; /* Override value for me to use */
6641 if (rttflg) { /* Lower and upper bounds */
6645 #endif /* CK_TIMERS */
6647 return(success = 1);
6649 case XYFPATH: /* PATHNAMES */
6651 y = cmkey(rpathtab,nrpathtab,"","auto",xxstring);
6653 y = cmkey(pathtab,npathtab,"","off",xxstring);
6655 if (y < 0) return(y);
6657 if ((x = cmcfm()) < 0) return(x);
6658 if (xx == XYRECV) { /* SET RECEIVE PATHNAMES */
6660 ptab[protocol].fnrp = fnrpath;
6661 } else { /* SET SEND PATHNAMES */
6663 ptab[protocol].fnsp = fnspath;
6665 return(success = 1); /* Note: 0 = ON, 1 = OFF */
6666 /* In other words, ON = leave pathnames ON, OFF = take them off. */
6668 case XYPAUS: /* SET SEND/RECEIVE PAUSE */
6669 y = cmnum("Milliseconds to pause between packets","0",10,&x,xxstring);
6670 if ((y = setnum(&z,x,y,15000)) < 0)
6673 return(success = 1);
6675 #ifdef CKXXCHAR /* SET SEND/RECEIVE IGNORE/DOUBLE */
6680 extern short dblt[];
6681 extern int dblflag, ignflag;
6683 /* Make space for a temporary copy of the ignore/double table */
6687 if (zz == XYIGN && xx == XYSEND) {
6690 if (zz == XYDBL && xx == XYRECV) {
6693 #endif /* COMMENT */
6694 p = (short *)malloc(256 * sizeof(short));
6696 printf("?Internal error - malloc failure\n");
6699 for (i = 0; i < 256; i++) p[i] = dblt[i]; /* Copy current table */
6701 while (1) { /* Collect a list of numbers */
6703 x_ifnum = 1; /* Turn off complaints from eval() */
6705 if ((x = cmnum(zz == XYDBL ?
6706 "Character to double" :
6707 "Character to ignore",
6713 if (x == -3) /* Done */
6716 if (p) { free(p); p = NULL; }
6717 debug(F110,"SET S/R DOUBLE/IGNORE atmbuf",atmbuf,0);
6718 if (!ckstrcmp(atmbuf,"none",4,0) ||
6719 !ckstrcmp(atmbuf,"non",3,0) ||
6720 !ckstrcmp(atmbuf,"no",2,0) ||
6721 !ckstrcmp(atmbuf,"n",1,0)) {
6722 if ((x = cmcfm()) < 0) /* Get confirmation */
6724 for (y = 0; y < 256; y++)
6725 dblt[y] &= (zz == XYDBL) ? 1 : 2;
6726 if (zz == XYDBL) dblflag = 0;
6727 if (zz == XYIGN) ignflag = 0;
6728 return(success = 1);
6731 "?Please specify a number or the word NONE\n");
6743 if (y < 0 || y > 255) {
6744 printf("?Please enter a character code in range 0-255\n");
6749 p[y] |= (zz == XYDBL) ? 2 : 1;
6750 if (zz == XYDBL) dblflag = 1;
6751 if (zz == XYIGN) ignflag = 1;
6752 } /* End of while loop */
6754 if ((x = cmcfm()) < 0) return(x);
6756 Get here only if they have made no mistakes. Copy temporary table back to
6757 permanent one, then free temporary table and return successfully.
6760 for (i = 0; i < 256; i++) dblt[i] = p[i];
6764 return(success = 1);
6766 #endif /* CKXXCHAR */
6769 case XYFLTR: { /* SET { SEND, RECEIVE } FILTER */
6770 if ((y = cmtxt((xx == XYSEND) ?
6771 "Filter program for sending files -\n\
6772 use \\v(filename) to substitute filename" :
6773 "Filter program for receiving files -\n\
6774 use \\v(filename) to substitute filename",
6777 if (!*s) { /* Removing a filter... */
6778 if (xx == XYSEND && sndfilter) {
6779 makestr(&g_sfilter,NULL);
6780 makestr(&sndfilter,NULL);
6781 } else if (rcvfilter) {
6782 makestr(&g_rfilter,NULL);
6783 makestr(&rcvfilter,NULL);
6785 return(success = 1);
6786 } /* Adding a filter... */
6787 s = brstrip(s); /* Strip any braces */
6789 if (xx == XYSEND) { /* For SEND filter... */
6790 for (x = 0; x < y; x++) { /* make sure they included "\v(...)" */
6791 if (s[x] != '\\') continue;
6792 if (s[x+1] == 'v') break;
6796 "?Filter must contain a replacement variable for filename.\n"
6802 makestr(&sndfilter,s);
6803 makestr(&g_sfilter,s);
6805 makestr(&rcvfilter,s);
6806 makestr(&g_rfilter,s);
6808 return(success = 1);
6810 #endif /* PIPESEND */
6813 y = cmnum("Max length for protocol init string","-1",10,&x,xxstring);
6814 if ((y = setnum(&z,x,y,-1)) < 0)
6820 return(success = 1);
6823 extern int sendipkts;
6825 if ((x = seton(&sendipkts)) < 0)
6834 if ((x = seton(&atlpro)) < 0) return(x);
6838 if ((x = seton(&atlpri)) < 0) return(x);
6844 #endif /* CK_PERMS */
6847 case XYCSET: { /* CHARACTER-SET-SELECTION */
6848 extern struct keytab xfrmtab[];
6849 extern int r_cset, s_cset;
6850 if ((y = cmkey(xfrmtab,2,"","automatic",xxstring)) < 0)
6852 if ((x = cmcfm()) < 0)
6858 return(success = 1);
6860 #endif /* NOCSETS */
6863 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0)
6865 if ((x = cmcfm()) < 0) return(x);
6868 skipbup = (y == 0) ? 1 : 0;
6869 return(success = 1);
6872 "?Please use SET FILE COLLISION to choose the desired action\n");
6878 y = cmdir("Directory to move file(s) to after successful transfer",
6881 y = cmtxt("Directory to move file(s) to after successful transfer",
6883 #endif /* COMMENT */
6885 if (y < 0 && y != -3)
6887 ckstrncpy(line,s,LINBUFSIZ);
6891 /* Only needed for cmdir() */
6892 if ((x = cmcfm()) < 0)
6894 #endif /* COMMENT */
6896 /* Check directory existence if absolute */
6897 /* THIS MEANS IT CAN'T INCLUDE ANY DEFERRED VARIABLES! */
6899 if (isabsolute(s) && !isdir(s)) {
6900 printf("?Directory does not exist - %s\n",s);
6907 /* Allow it to be relative */
6908 zfnqfp(s,LINBUFSIZ,line);
6909 #endif /* COMMENT */
6910 makestr(&snd_move,line);
6911 makestr(&g_snd_move,line);
6913 makestr(&snd_move,NULL);
6914 makestr(&g_snd_move,NULL);
6919 /* Allow it to be relative */
6920 zfnqfp(s,LINBUFSIZ,line);
6921 #endif /* COMMENT */
6922 makestr(&rcv_move,line);
6923 makestr(&g_rcv_move,line);
6925 makestr(&rcv_move,NULL);
6926 makestr(&g_rcv_move,NULL);
6929 return(success = 1);
6932 y = cmtxt("Template to rename file(s) to after successful transfer",
6933 "",&s,NULL); /* NOTE: no xxstring */
6934 if (y < 0 && y != -3) /* Evaluation is deferred */
6936 ckstrncpy(line,s,LINBUFSIZ);
6938 if ((x = cmcfm()) < 0)
6942 makestr(&snd_rename,s);
6943 makestr(&g_snd_rename,s);
6945 makestr(&snd_rename,NULL);
6946 makestr(&g_snd_rename,NULL);
6950 makestr(&rcv_rename,s);
6951 makestr(&g_rcv_rename,s);
6953 makestr(&rcv_rename,NULL);
6954 makestr(&g_rcv_rename,NULL);
6957 return(success = 1);
6960 case 887: /* VERSION-NUMBERS */
6962 extern int vmssversions;
6963 return(seton(&vmssversions));
6965 extern int vmsrversions;
6966 return(seton(&vmsrversions));
6972 } /* End of SET SEND/RECEIVE... */
6979 if ((y = cmkey(xmitab,nxmit,"","",xxstring)) < 0) return(y);
6981 case XMITE: /* EOF */
6982 y = cmtxt("Characters to send at end of file,\n\
6983 Use backslash codes for control characters","",&s,xxstring);
6984 if (y < 0) return(y);
6985 if ((int)strlen(s) > XMBUFL) {
6986 printf("?Too many characters, %d maximum\n",XMBUFL);
6989 ckstrncpy(xmitbuf,s,XMBUFL);
6990 return(success = 1);
6992 case XMITF: /* Fill */
6993 y = cmnum("Numeric code for blank-line fill character","0",10,&x,
6995 if ((y = setnum(&z,x,y,127)) < 0) return(y);
6997 return(success = 1);
6998 case XMITL: /* Linefeed */
6999 return(seton(&xmitl));
7000 case XMITS: /* Locking-Shift */
7001 return(seton(&xmits));
7002 case XMITP: /* Prompt */
7003 y = cmnum("Numeric code for host's prompt character, 0 for none",
7004 "10",10,&x,xxstring);
7005 if ((y = setnum(&z,x,y,127)) < 0) return(y);
7007 return(success = 1);
7008 case XMITX: /* Echo */
7009 return(seton(&xmitx));
7010 case XMITW: /* Pause */
7011 y = cmnum("Number of milliseconds to pause between binary characters\n\
7012 or text lines during transmission","0",10,&x,xxstring);
7013 if ((y = setnum(&z,x,y,1000)) < 0) return(y);
7015 return(success = 1);
7016 case XMITT: /* Timeout */
7017 y = cmnum("Seconds to wait for each character to echo",
7018 "1",10,&x,xxstring);
7019 if ((y = setnum(&z,x,y,1000)) < 0) return(y);
7021 return(success = 1);
7029 /* D O R M T -- Do a remote command */
7033 if (pflag && !quiet && fdispla != XYFD_N)
7036 " Type your escape character, %s, followed by X or E to cancel.\n",
7039 " Press the X or E key to cancel.\n"
7040 #endif /* CK_NEED_SIG */
7044 static int xzcmd = 0; /* Global copy of REMOTE cmd index */
7046 /* R E M C F M -- Confirm a REMOTE command */
7048 Like cmcfm(), but allows for a redirection indicator on the end,
7049 like "> filename" or "| command". Returns what cmcfm() would have
7050 returned: -1 if reparse needed, etc etc blah blah. On success,
7053 char * remdest containing the name of the file or command.
7054 int remfile set to 1 if there is to be any redirection.
7055 int remappd set to 1 if output file is to be appended to.
7056 int rempipe set to 1 if remdest is a command, 0 if it is a file.
7069 "> filename, | command,\n\
7070 or type carriage return to confirm the command",
7071 "",&s,xxstring)) < 0)
7077 debug(F101,"remcfm local","",local);
7078 debug(F110,"remcfm s",s,0);
7079 debug(F101,"remcfm cmd","",xzcmd);
7081 if (!*s) { /* No redirection indicator */
7083 (xzcmd == XZDIR || xzcmd == XZTYP ||
7084 xzcmd == XZXIT || xzcmd == XZSPA ||
7085 xzcmd == XZHLP || xzcmd == XZPWD ||
7086 xzcmd == XZLGI || xzcmd == XZLGO ||
7087 xzcmd == XZWHO || xzcmd == XZHOS)) {
7088 printf("?\"%s\" has no effect in remote mode\n",cmdbuf);
7093 c = *s; /* We have something */
7094 if (c != '>' && c != '|') { /* Is it > or | ? */
7095 printf("?Not confirmed\n"); /* No */
7098 s++; /* See what follows */
7099 if (c == '>' && *s == '>') { /* Allow for ">>" too */
7101 remappd = 1; /* Append to output file */
7103 while (*s == SP || *s == HT) s++; /* Strip intervening whitespace */
7105 printf("?%s missing\n", c == '>' ? "Filename" : "Command");
7108 if (c == '>' && zchko(s) < 0) { /* Check accessibility */
7109 printf("?Access denied - %s\n", s);
7112 remfile = 1; /* Set global results */
7113 rempipe = (c == '|');
7119 printf("?Sorry, access to external commands is disabled.\n");
7122 makestr(&remdest,s);
7125 debug(F101,"remcfm remfile","",remfile);
7126 debug(F101,"remcfm remappd","",remappd);
7127 debug(F101,"remcfm rempipe","",rempipe);
7128 debug(F110,"remcfm remdest",remdest, 0);
7130 #endif /* NODEBUG */
7134 /* R E M T X T -- Like remcfm()... */
7136 ... but for REMOTE commands that end with cmtxt().
7137 Here we must decipher braces to discover whether the trailing
7138 redirection indicator is intended for local use, or to be sent out
7139 to the server, as in:
7141 remote host blah blah > file This end
7142 remote host { blah blah } > file This end
7143 remote host { blah blah > file } That end
7144 remote host { blah blah > file } > file Both ends
7148 remote host blah blah | cmd This end
7149 remote host { blah blah } | cmd This end
7150 remote host { blah blah | cmd } That end
7151 remote host { blah blah | cmd } | cmd Both ends
7155 remote host blah blah | cmd > file This end, etc etc...
7157 Note: this really only makes sense for REMOTE HOST, but why be picky?
7158 Call after calling cmtxt(), with pointer to string that cmtxt() parsed,
7159 as in "remtxt(&s);".
7162 1 on success with braces & redirection things removed & pointer updated,
7163 -9 on failure (bad indirection), after printing error message.
7166 remtxt(p) char ** p; {
7167 int i, x, bpos, ppos;
7170 remfile = 0; /* Initialize global results */
7178 if (!s) /* No redirection indicator */
7180 if (!*s) { /* Ditto */
7182 (xzcmd == XZDIR || xzcmd == XZTYP ||
7183 xzcmd == XZXIT || xzcmd == XZSPA ||
7184 xzcmd == XZHLP || xzcmd == XZPWD ||
7185 xzcmd == XZLGI || xzcmd == XZLGO ||
7186 xzcmd == XZWHO || xzcmd == XZHOS)) {
7187 printf("?\"%s\" has no effect in remote mode\n",cmdbuf);
7189 printf("Hint: Try again with an output redirector.\n");
7195 bpos = -1; /* Position of > (bracket) */
7196 ppos = -1; /* Position of | (pipe) */
7197 x = strlen(s); /* Length of cmtxt() string */
7199 for (i = x-1; i >= 0; i--) { /* Search right to left. */
7201 if (c == '}') /* Break on first right brace */
7202 break; /* Don't look at contents of braces */
7203 else if (c == '>') /* Record position of > */
7205 else if (c == '|') /* and of | */
7208 if (bpos < 0 && ppos < 0) { /* No redirectors. */
7210 (xzcmd == XZDIR || xzcmd == XZTYP ||
7211 xzcmd == XZXIT || xzcmd == XZSPA ||
7212 xzcmd == XZHLP || xzcmd == XZPWD ||
7213 xzcmd == XZLGI || xzcmd == XZLGO ||
7214 xzcmd == XZWHO || xzcmd == XZHOS)) {
7215 printf("?\"%s\" has no effect in remote mode\n",cmdbuf);
7217 printf("Hint: Try again with an output redirector.\n");
7221 s = brstrip(s); /* Remove outer braces if any. */
7222 *p = s; /* Point to result */
7223 return(1); /* and return. */
7225 remfile = 1; /* It's | or > */
7226 i = -1; /* Get leftmost symbol */
7227 if (bpos > -1) /* Bracket */
7229 if (ppos > -1 && (ppos < bpos || bpos < 0)) { /* or pipe */
7238 printf("?Sorry, access to external commands is disabled.\n");
7241 c = s[i]; /* Copy of symbol */
7243 if (c == '>' && s[i+1] == '>') /* ">>" for append? */
7244 remappd = 1; /* It's not just a flag it's a number */
7246 q = s + i + 1 + remappd; /* Point past symbol in string */
7247 while (*q == SP || *q == HT) q++; /* and any intervening whitespace */
7249 printf("?%s missing\n", c == '>' ? "Filename" : "Command");
7252 if (c == '>' && zchko(q) < 0) { /* (Doesn't work for | cmd > file) */
7253 printf("?Access denied - %s\n", q);
7256 makestr(&remdest,q); /* Create the destination string */
7257 q = s + i - 1; /* Point before symbol */
7258 while (q > s && (*q == SP || *q == HT)) /* Strip trailing whitespace */
7260 *(q+1) = NUL; /* Terminate the string. */
7261 s = brstrip(s); /* Remove any braces */
7262 *p = s; /* Set return value */
7266 debug(F101,"remtxt remfile","",remfile);
7267 debug(F101,"remtxt remappd","",remappd);
7268 debug(F101,"remtxt rempipe","",rempipe);
7269 debug(F110,"remtxt remdest",remdest, 0);
7270 debug(F110,"remtxt command",s,0);
7272 #endif /* NODEBUG */
7278 plogin(xx) int xx; {
7279 char *p1 = NULL, *p2 = NULL, *p3 = NULL;
7280 int psaved = 0, rc = 0;
7282 extern int on_recall; /* around Password prompting */
7283 #endif /* CK_RECALL */
7284 debug(F101,"plogin local","",local);
7286 if (!local || (network && ttchk() < 0)) {
7287 printf("?No connection\n");
7290 if ((x = cmfld("User ID","",&s,xxstring)) < 0) { /* Get User ID */
7291 if (x != -3) return(x);
7295 if ((p1 = malloc(y + 1)) == NULL) {
7296 printf("?Internal error: malloc\n");
7300 strcpy(p1,s); /* safe */
7301 if ((rc = cmfld("Password","",&s,xxstring)) < 0)
7302 if (rc != -3) goto XZXLGI;
7305 if ((p2 = malloc(y + 1)) == NULL) {
7306 printf("?Internal error: malloc\n");
7310 strcpy(p2,s); /* safe */
7311 if ((rc = cmfld("Account","",&s,xxstring)) < 0)
7312 if (rc != -3) goto XZXLGI;
7315 if ((p3 = malloc(y + 1)) == NULL) {
7316 printf("?Internal error: malloc\n");
7320 strcpy(p3,s); /* safe */
7324 if ((rc = remtxt(&s)) < 0) /* Confirm & handle redirectors */
7327 if (!p1) { /* No Userid specified... */
7328 debok = 0; /* Don't log this */
7329 /* Prompt for username, password, and account */
7332 #endif /* CK_RECALL */
7333 cmsavp(psave,PROMPTL); /* Save old prompt */
7335 debug(F110,"REMOTE LOGIN saved",psave,0);
7337 cmsetp("Username: "); /* Make new prompt */
7338 concb((char)escape); /* Put console in cbreak mode */
7342 for (x = -1; x < 0; ) { /* Prompt till they answer */
7343 cmres(); /* Reset the parser */
7344 x = cmtxt("","",&s,NULL); /* Get a literal line of text */
7348 printf("?Canceled\n");
7351 if ((p1 = malloc(y + 1)) == NULL) {
7352 printf("?Internal error: malloc\n");
7355 strcpy(p1,s); /* safe */
7357 cmsetp("Password: "); /* Make new prompt */
7358 concb((char)escape); /* Put console in cbreak mode */
7359 cmini(0); /* No echo */
7362 for (x = -1; x < 0 && x != -3; ) { /* Get answer */
7363 cmres(); /* Reset the parser */
7364 x = cmtxt("","",&s,NULL); /* Get literal line of text */
7366 if ((p2 = malloc((int)strlen(s) + 1)) == NULL) {
7367 printf("?Internal error: malloc\n");
7370 strcpy(p2,s); /* safe */
7372 if ((rc = cmcfm()) < 0)
7375 sstate = setgen('I',p1,p2,p3); /* Get here with at least user ID */
7378 XZXLGI: /* Common exit point */
7380 cmsetp(psave); /* Restore original prompt */
7381 if (p3) { free(p3); p3 = NULL; } /* Free malloc'd storage */
7382 if (p2) { free(p2); p2 = NULL; }
7383 if (p1) { free(p1); p1 = NULL; }
7385 if (local && rc > -1) /* If local, flush tty input buffer */
7397 int term_io_sav = term_io;
7399 extern int ftpget, ftpisopen();
7400 if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
7401 return(doftprmt(xx,0));
7405 term_io = term_io_sav;
7415 #endif /* NOLOCAL */
7420 { /* REMOTE commands */
7422 char *s, sbuf[50], *s2;
7425 extern int ftpget, ftpisopen();
7426 if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
7427 return(doftprmt(xx,0));
7430 remfile = 0; /* Clear these */
7434 if (xx < 0) return(xx); /* REMOTE what? */
7436 xzcmd = xx; /* Make global copy of arg */
7438 if (xx == XZSET) { /* REMOTE SET */
7439 if ((y = cmkey(rmstab,nrms,"","",xxstring)) < 0) {
7441 printf("?Parameter name required\n");
7448 switch (xx) { /* Others... */
7451 if ((x = cmcfm()) < 0) return(x);
7452 printf("?Sorry, REMOTE CDUP not supported yet\n");
7455 case XZCWD: /* CWD (CD) */
7456 if ((x = cmtxt("Remote directory name","",&s,xxstring)) < 0)
7458 if ((x = remtxt(&s)) < 0)
7460 debug(F111,"XZCWD: ",s,x);
7464 The following is commented out because since the disappearance of the
7465 DECSYSTEM-20 from the planet, no known computer requires a password for
7469 if (*s != NUL) { /* If directory name given, */
7470 /* get password on separate line. */
7471 if (tlevel > -1) { /* From take file... */
7473 if (fgets(sbuf,50,tfile[tlevel]) == NULL)
7474 fatal("take file ends prematurely in 'remote cwd'");
7475 debug(F110," pswd from take file",s2,0);
7476 for (x = (int)strlen(sbuf);
7477 x > 0 && (sbuf[x-1] == NL || sbuf[x-1] == CR);
7481 } else { /* From terminal... */
7483 printf(" Password: "); /* get a password */
7485 if (!local && inserver) {
7490 x = is_a_tty(0) ? coninc(0) : /* with no echo ... */
7495 while ((x != NL) && (x != CR)) {
7496 if ((x &= 0177) == '?') {
7497 printf("? Password of remote directory\n Password: ");
7500 } else if (x == ESC) /* Mini command line editor... */
7502 else if (x == BS || x == 0177)
7504 else if (x == 025) { /* Ctrl-U */
7510 /* Get the next character */
7512 if (!local && inserver) {
7517 x = is_a_tty(0) ? coninc(0) : /* with no echo ... */
7528 #endif /* DIRPWDPR */
7530 debug(F110," password",s2,0);
7532 sstate = setgen('C',s,s2,"");
7536 case XZDEL: /* Delete */
7537 if ((x = cmtxt("Name of remote file(s) to delete",
7538 "",&s,xxstring)) < 0) {
7540 printf("?Name of remote file(s) required\n");
7544 if ((x = remtxt(&s)) < 0)
7546 if (local) ttflui(); /* If local, flush tty input buffer */
7547 retcode = sstate = rfilop(s,'E');
7550 case XZDIR: /* Directory */
7551 if ((x = cmtxt("Remote directory or file specification","",&s,
7554 if ((x = remtxt(&s)) < 0)
7556 if (local) ttflui(); /* If local, flush tty input buffer */
7558 retcode = sstate = setgen('D',s,"","");
7561 case XZHLP: /* Help */
7562 if ((x = remcfm()) < 0) return(x);
7563 sstate = setgen('H',"","","");
7567 case XZHOS: /* Host */
7568 if ((x = cmtxt("Command for remote system","",&s,xxstring)) < 0)
7570 if ((x = remtxt(&s)) < 0)
7572 if ((y = (int)strlen(s)) < 1)
7574 ckstrncpy(line,s,LINBUFSIZ);
7577 retcode = sstate = 'c';
7582 if ((x = cmtxt("Command for remote Kermit","",&s,xxstring)) < 0)
7584 if ((x = remtxt(&s)) < 0)
7586 if ((int)strlen(s) < 1) {
7588 printf("?Remote Kermit command required\n");
7592 ckstrncpy(line,s,LINBUFSIZ);
7594 retcode = sstate = 'k';
7598 case XZLGI: /* Login */
7599 rcdactive = 1; /* Suppress "Logged in" msg if quiet */
7600 return(plogin(XXREM));
7602 case XZLGO: { /* Logout */
7603 extern int bye_active;
7604 if ((x = remcfm()) < 0) return(x);
7605 sstate = setgen('I',"","","");
7607 bye_active = 1; /* Close connection when done */
7611 case XZPRI: /* Print */
7612 if (!atdiso || !atcapr) { /* Disposition attribute off? */
7613 printf("?Disposition Attribute is Off\n");
7618 if ((x = cmifi("Local file(s) to print on remote printer","",&s,&y,
7621 printf("?Name of local file(s) required\n");
7626 ckstrncpy(line,s,LINBUFSIZ); /* Make a safe copy of filename */
7627 *optbuf = NUL; /* Wipe out any old options */
7628 if ((x = cmtxt("Options for remote print command","",&s,xxstring)) < 0)
7630 if ((x = remtxt(&s)) < 0)
7632 if ((int)strlen(optbuf) > 94) { /* Make sure this is legal */
7633 printf("?Option string too long\n");
7636 ckstrncpy(optbuf,s,OPTBUFLEN); /* Make a safe copy of options */
7637 nfils = -1; /* Expand file list internally */
7638 cmarg = line; /* Point to file list. */
7639 rprintf = 1; /* REMOTE PRINT modifier for SEND */
7640 sstate = 's'; /* Set start state to SEND */
7641 if (local) displa = 1;
7644 #endif /* NOFRILLS */
7646 case XZSPA: /* Space */
7647 if ((x = cmtxt("Confirm, or remote directory name",
7648 "",&s,xxstring)) < 0)
7650 if ((x = remtxt(&s)) < 0)
7652 retcode = sstate = setgen('U',s,"","");
7656 case XZTYP: /* Type */
7657 if ((x = cmtxt("Remote file specification","",&s,xxstring)) < 0)
7659 if ((int)strlen(s) < 1) {
7660 printf("?Remote filename required\n");
7663 if ((x = remtxt(&s)) < 0)
7666 retcode = sstate = rfilop(s,'T');
7668 #endif /* NOFRILLS */
7672 if ((x = cmtxt("Remote user name, or carriage return",
7673 "",&s,xxstring)) < 0)
7675 if ((x = remtxt(&s)) < 0)
7677 retcode = sstate = setgen('W',s,"","");
7679 #endif /* NOFRILLS */
7681 case XZPWD: /* PWD */
7682 if ((x = remcfm()) < 0) return(x);
7683 sstate = setgen('A',"","","");
7688 case XZQUE: { /* Query */
7690 extern char querybuf[], * qbufp;
7692 if ((y = cmkey(vartyp,nvartyp,"","",xxstring)) < 0)
7694 if ((x = cmtxt(y == 'F' ? "Remote function invocation" :
7695 ('K' ? "Remote variable name or function":
7696 "Remote variable name"),
7699 (y == 'K') ? xxstring : NULL
7700 )) < 0) /* Don't evaluate */
7702 if ((x = remtxt(&s)) < 0)
7704 query = 1; /* QUERY is active */
7705 qbufp = querybuf; /* Initialize query response buffer */
7708 buf[0] = (char) (y & 127);
7710 retcode = sstate = setgen('V',"Q",(char *)buf,s);
7714 case XZASG: { /* Assign */
7716 if ((y = cmfld("Remote variable name","",&s,NULL)) < 0) /* No eval */
7718 if ((int)strlen(s) >= VNAML) {
7719 printf("?Too long\n");
7722 ckstrncpy(buf,s,VNAML);
7723 if ((x = cmtxt("Assignment for remote variable",
7724 "",&s,xxstring)) < 0) /* Evaluate this one */
7726 if ((x = remtxt(&s)) < 0)
7730 Server commands can't be long packets. In principle there's no reason
7731 why they shouldn't be, except that we don't know at this point if the
7732 server is capable of accepting long packets because we haven't started
7733 the protocol yet. In practice, allowing a long packet here breaks a lot
7734 of assumptions, causes buffer overruns and crashes, etc. To be fixed
7735 later. (But since this is commented out, evidently I fixed it later...)
7737 if ((int)strlen(s) > 85) { /* Allow for encoding expansion */
7738 printf("?Sorry, value is too long - 85 characters max\n");
7741 #endif /* COMMENT */
7742 retcode = sstate = setgen('V',"S",(char *)buf,s);
7747 case XZCPY: { /* COPY */
7748 char buf[TMPBUFSIZ];
7749 buf[TMPBUFSIZ-1] = '\0';
7750 if ((x = cmfld("Name of remote file to copy","",&s,xxstring)) < 0) {
7752 printf("?Name of remote file required\n");
7758 ckstrncpy(buf,s,TMPBUFSIZ);
7759 if ((x = cmfld("Name of remote destination file or directory",
7760 "",&s, xxstring)) < 0) {
7762 printf("?Name of remote file or directory required\n");
7766 ckstrncpy(tmpbuf,s,TMPBUFSIZ);
7767 if ((x = remcfm()) < 0)
7769 if (local) ttflui(); /* If local, flush tty input buffer */
7770 retcode = sstate = setgen('K',buf,tmpbuf,"");
7773 case XZREN: { /* Rename */
7774 char buf[TMPBUFSIZ];
7775 buf[TMPBUFSIZ-1] = '\0';
7776 if ((x = cmfld("Name of remote file to rename",
7777 "",&s,xxstring)) < 0) {
7779 printf("?Name of remote file required\n");
7783 ckstrncpy(buf,s,TMPBUFSIZ);
7784 if ((x = cmfld("New name of remote file","",&s, xxstring)) < 0) {
7786 printf("?Name of remote file required\n");
7790 ckstrncpy(tmpbuf,s,TMPBUFSIZ);
7791 if ((x = remcfm()) < 0)
7793 if (local) ttflui(); /* If local, flush device buffer */
7794 retcode = sstate = setgen('R',buf,tmpbuf,"");
7797 case XZMKD: /* mkdir */
7798 case XZRMD: /* rmdir */
7799 if ((x = cmtxt((xx == XZMKD) ?
7800 "Name of remote directory to create" :
7801 "Name of remote directory to delete",
7807 printf("?Name required\n");
7811 if ((x = remtxt(&s)) < 0)
7813 if (local) ttflui(); /* If local, flush tty input buffer */
7814 retcode = sstate = rfilop(s, (char)(xx == XZMKD ? 'm' : 'd'));
7817 case XZXIT: /* Exit */
7818 if ((x = remcfm()) < 0) return(x);
7819 sstate = setgen('X',"","","");
7824 if ((x = remcfm()) < 0) return(x);
7825 printf("?Not implemented - %s\n",cmdbuf);
7828 if (local && retcode > -1) /* If local, flush tty input buffer */
7834 /* R F I L O P -- Remote File Operation */
7838 rfilop(char * s, char t)
7840 rfilop(s,t) char *s, t;
7841 #endif /* CK_ANSIC */
7844 printf("?File specification required\n");
7847 debug(F111,"rfilop",s,t);
7848 return(setgen(t,s,"",""));
7855 if ((y = cmkey(x25tab,nx25,"X.25 call options","",xxstring)) < 0)
7859 if ((z = cmkey(onoff,2,"X.25 call user data","",xxstring))
7862 if ((z = cmcfm()) < 0) return(z);
7863 cudata = 0; /* disable call user data */
7864 return (success = 1);
7866 if ((x = cmtxt("X.25 call user data string","",&s,xxstring)) < 0)
7868 if ((int)strlen(s) == 0) {
7870 } else if ((int)strlen(s) > MAXCUDATA) {
7871 printf("?The length must be > 0 and <= %d\n",MAXCUDATA);
7874 if ((y = cmcfm()) < 0) return(y);
7875 ckstrncpy(udata,s,MAXCUDATA);
7876 cudata = 1; /* X.25 call user data specified */
7877 return (success = 1);
7879 if ((z = cmkey(onoff,2,"X.25 closed user group call","",xxstring))
7882 if ((z = cmcfm()) < 0) return(z);
7883 closgr = -1; /* disable closed user group */
7884 return (success = 1);
7886 if ((y = cmnum("0 <= cug index >= 99","",10,&x,xxstring)) < 0)
7888 if (x < 0 || x > 99) {
7889 printf("?The choices are 0 <= cug index >= 99\n");
7892 if ((y = cmcfm()) < 0) return(y);
7893 closgr = x; /* closed user group selected */
7894 return (success = 1);
7897 if((z = cmkey(onoff,2,"X.25 reverse charge call","",xxstring)) < 0)
7899 if ((x = cmcfm()) < 0) return(x);
7901 return (success = 1);
7908 if ((y = cmkey(padx3tab,npadx3,"PAD X.3 parameter name","",xxstring)) < 0)
7912 case PAD_BREAK_CHARACTER:
7913 if ((y = cmnum("PAD break character value","",10,&z,xxstring)) < 0)
7915 if ((y = cmcfm()) < 0) return(y);
7918 if ((y = cmnum("PAD escape","",10,&z,xxstring)) < 0) return(y);
7919 if (z != 0 && z != 1) {
7920 printf("?The choices are 0 or 1\n");
7923 if ((y = cmcfm()) < 0) return(y);
7926 if ((y = cmnum("PAD echo","",10,&z,xxstring)) < 0) return(y);
7927 if (z != 0 && z != 1) {
7928 printf("?The choices are 0 or 1\n");
7931 if ((y = cmcfm()) < 0) return(y);
7933 case PAD_DATA_FORWARD_CHAR:
7934 if ((y = cmnum("PAD data forward char","",10,&z,xxstring)) < 0)
7936 if (z != 0 && z != 2) {
7937 printf("?The choices are 0 or 2\n");
7940 if ((y = cmcfm()) < 0) return(y);
7942 case PAD_DATA_FORWARD_TIMEOUT:
7943 if ((y = cmnum("PAD data forward timeout","",10,&z,xxstring)) < 0)
7945 if (z < 0 || z > 255) {
7946 printf("?The choices are 0 or 1 <= timeout <= 255\n");
7949 if ((y = cmcfm()) < 0) return(y);
7951 case PAD_FLOW_CONTROL_BY_PAD:
7952 if ((y = cmnum("PAD pad flow control","",10,&z,xxstring)) < 0)
7954 if (z != 0 && z != 1) {
7955 printf("?The choices are 0 or 1\n");
7958 if ((y = cmcfm()) < 0) return(y);
7960 case PAD_SUPPRESSION_OF_SIGNALS:
7961 if ((y = cmnum("PAD service","",10,&z,xxstring)) < 0) return(y);
7962 if (z != 0 && z != 1) {
7963 printf("?The choices are 0 or 1\n");
7966 if ((y = cmcfm()) < 0) return(y);
7969 case PAD_BREAK_ACTION:
7970 if ((y = cmnum("PAD break action","",10,&z,xxstring)) < 0) return(y);
7971 if (z != 0 && z != 1 && z != 2 && z != 5 && z != 8 && z != 21) {
7972 printf("?The choices are 0, 1, 2, 5, 8 or 21\n");
7975 if ((y = cmcfm()) < 0) return(y);
7978 case PAD_SUPPRESSION_OF_DATA:
7979 if ((y = cmnum("PAD data delivery","",10,&z,xxstring)) < 0) return(y);
7980 if (z != 0 && z != 1) {
7981 printf("?The choices are 0 or 1\n");
7984 if ((y = cmcfm()) < 0) return(y);
7987 case PAD_PADDING_AFTER_CR:
7988 if ((y = cmnum("PAD crpad","",10,&z,xxstring)) < 0) return(y);
7989 if (z < 0 || z > 7) {
7990 printf("?The choices are 0 or 1 <= crpad <= 7\n");
7993 if ((y = cmcfm()) < 0) return(y);
7996 case PAD_LINE_FOLDING:
7997 if ((y = cmnum("PAD linefold","",10,&z,xxstring)) < 0) return(y);
7998 if (z < 0 || z > 255) {
7999 printf("?The choices are 0 or 1 <= linefold <= 255\n");
8002 if ((y = cmcfm()) < 0) return(y);
8005 case PAD_LINE_SPEED:
8006 if ((y = cmnum("PAD baudrate","",10,&z,xxstring)) < 0) return(y);
8007 if (z < 0 || z > 18) {
8008 printf("?The choices are 0 <= baudrate <= 18\n");
8011 if ((y = cmcfm()) < 0) return(y);
8014 case PAD_FLOW_CONTROL_BY_USER:
8015 if ((y = cmnum("PAD terminal flow control","",10,&z,xxstring)) < 0)
8017 if (z != 0 && z != 1) {
8018 printf("?The choices are 0 or 1\n");
8021 if ((y = cmcfm()) < 0) return(y);
8024 case PAD_LF_AFTER_CR:
8025 if ((y = cmnum("PAD crpad","",10,&z,xxstring)) < 0) return(y);
8026 if (z < 0 || z == 3 || z > 7) {
8027 printf("?The choices are 0, 1, 2, 4, 5, 6 or 7\n");
8030 if ((y = cmcfm()) < 0) return(y);
8033 case PAD_PADDING_AFTER_LF:
8034 if ((y = cmnum("PAD lfpad","",10,&z,xxstring)) < 0) return(y);
8035 if (z < 0 || z > 7) {
8036 printf("?The choices are 0 or 1 <= lfpad <= 7\n");
8039 if ((y = cmcfm()) < 0) return(y);
8043 if ((y = cmnum("PAD edit control","",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 case PAD_CHAR_DELETE_CHAR:
8052 if ((y = cmnum("PAD char delete char","",10,&z,xxstring)) < 0)
8054 if (z < 0 || z > 127) {
8055 printf("?The choices are 0 or 1 <= chardelete <= 127\n");
8058 if ((y = cmcfm()) < 0) return(y);
8061 case PAD_BUFFER_DELETE_CHAR:
8062 if ((y = cmnum("PAD buffer delete char","",10,&z,xxstring)) < 0)
8064 if (z < 0 || z > 127) {
8065 printf("?The choices are 0 or 1 <= bufferdelete <= 127\n");
8068 if ((y = cmcfm()) < 0) return(y);
8071 case PAD_BUFFER_DISPLAY_CHAR:
8072 if ((y = cmnum("PAD display line char","",10,&z,xxstring)) < 0)
8074 if (z < 0 || z > 127) {
8075 printf("?The choices are 0 or 1 <= displayline <= 127\n");
8078 if ((y = cmcfm()) < 0) return(y);
8082 return(success = 1);
8089 setat(rmsflg) int rmsflg; {
8091 if ((y = cmkey(attrtab,natr,"File Attribute packets","",xxstring)) < 0)
8093 if (y == AT_XALL) { /* ATTRIBUTES ALL ON or ALL OFF */
8094 if ((z = seton(&xx)) < 0) return(z);
8096 printf("Sorry, command not available\n");
8099 atenci = xx; /* Encoding in */
8100 atenco = xx; /* Encoding out */
8101 atdati = xx; /* Date in */
8102 atdato = xx; /* Date out */
8103 atdisi = xx; /* Disposition in/out */
8105 atleni = xx; /* Length in/out (both kinds) */
8107 atblki = xx; /* Blocksize in/out */
8109 attypi = xx; /* File type in/out */
8111 atsidi = xx; /* System ID in/out */
8113 atsysi = xx; /* System-dependent params in/out */
8115 #ifdef CK_PERMS /* Protection */
8116 atlpri = xx; /* Local in */
8117 atlpro = xx; /* Local out */
8118 atgpri = xx; /* Generic in */
8119 atgpro = xx; /* Generic out */
8120 #endif /* CK_PERMS */
8122 atfrmi = xx; /* Format in/out */
8124 atcrei = xx; /* Creator id in/out */
8126 atacti = xx; /* Account in/out */
8128 #endif /* STRATUS */
8131 } else if (y == AT_ALLY || y == AT_ALLN) { /* ATTRIBUTES ON or OFF */
8132 if ((x = cmcfm()) < 0) return(x);
8133 atcapr = (y == AT_ALLY) ? 1 : 0;
8135 sstate = setgen('S', "132", atcapr ? "1" : "0", "");
8136 return((int) sstate);
8137 } else return(success = 1);
8139 /* Otherwise, it's an individual attribute that wants turning off/on */
8141 if ((z = cmkey(onoff,2,"","",xxstring)) < 0) return(z);
8142 if ((x = cmcfm()) < 0) return(x);
8144 /* There are better ways to do this... */
8145 /* The real problem is that we're not separating the in and out cases */
8146 /* and so we have to arbitrarily pick the "in" case, i.e tell the remote */
8147 /* server to ignore incoming attributes of the specified type, rather */
8148 /* than telling it not to send them. The protocol does not (yet) define */
8149 /* codes for "in-and-out-at-the-same-time". */
8153 /* We're lumping local and generic protection together for now... */
8157 sstate = setgen('S', "143", z ? "1" : "0", "");
8158 return((int) sstate);
8160 atlpri = atlpro = atgpri = atgpro = z; break;
8161 #endif /* CK_PERMS */
8164 sstate = setgen('S', "142", z ? "1" : "0", "");
8165 return((int) sstate);
8167 atdisi = atdiso = z; break;
8170 sstate = setgen('S', "141", z ? "1" : "0", "");
8171 return((int) sstate);
8173 atenci = atenco = z; break;
8176 sstate = setgen('S', "135", z ? "1" : "0", "");
8177 return((int) sstate);
8179 atdati = atdato = z; break;
8183 sstate = setgen('S', "133", z ? "1" : "0", "");
8184 return((int) sstate);
8186 atleni = atleno = z; break;
8189 sstate = setgen('S', "139", z ? "1" : "0", "");
8190 return((int) sstate);
8192 atblki = atblko = z; break;
8195 sstate = setgen('S', "134", z ? "1" : "0", "");
8196 return((int) sstate);
8198 attypi = attypo = z; break;
8202 sstate = setgen('S', "136", z ? "1" : "0", "");
8203 return((int) sstate);
8205 atcrei = atcreo = z; break;
8208 sstate = setgen('S', "137", z ? "1" : "0", "");
8209 return((int) sstate);
8211 atacti = atacto = z; break;
8212 #endif /* STRATUS */
8215 sstate = setgen('S', "145", z ? "1" : "0", "");
8216 return((int) sstate);
8218 atsidi = atsido = z; break;
8221 sstate = setgen('S', "146", z ? "1" : "0", "");
8222 return((int) sstate);
8224 atfrmi = atfrmo = z; break;
8227 sstate = setgen('S', "147", z ? "1" : "0", "");
8228 return((int) sstate);
8230 atsysi = atsyso = z; break;
8232 printf("?Not available\n");
8242 if ((y = cmkey(inptab,ninp,"","",xxstring)) < 0) return(y);
8245 case IN_PAC: /* SET INPUT PACING */
8246 z = cmnum("milliseconds","0",10,&x,xxstring);
8247 return(setnum(&tt_inpacing,x,z,1000));
8248 case IN_TRM: /* SET INPUT TERMINAL */
8249 return(seton(&interm));
8251 case IN_DEF: /* SET INPUT DEFAULT-TIMEOUT */
8252 z = cmnum("Positive number","",10,&x,xxstring);
8253 return(setnum(&indef,x,z,94));
8255 case IN_SCA: /* SET INPUT SCALE-FACTOR */
8256 if ((x = cmfld("Number such as 2 or 0.5","1.0",&s, xxstring)) < 0)
8258 if (isfloat(s,0)) { /* A floating-point number? */
8259 extern char * inpscale;
8260 inscale = floatval; /* Yes, get its value */
8261 makestr(&inpscale,s); /* Save it as \v(inscale) */
8262 return(success = 1);
8266 #endif /* CKFLOAT */
8267 case IN_TIM: /* SET INPUT TIMEOUT-ACTION */
8268 if ((z = cmkey(intimt,2,"","",xxstring)) < 0) return(z);
8269 if ((x = cmcfm()) < 0) return(x);
8271 return(success = 1);
8272 case IN_CAS: /* SET INPUT CASE */
8273 if ((z = cmkey(incast,2,"","",xxstring)) < 0) return(z);
8274 if ((x = cmcfm()) < 0) return(x);
8276 return(success = 1);
8277 case IN_ECH: /* SET INPUT ECHO */
8278 return(seton(&inecho));
8279 case IN_SIL: /* SET INPUT SILENCE */
8280 z = cmnum("Seconds of inactivity before INPUT fails","",10,&x,
8282 return(setnum(&insilence,x,z,-1));
8284 case IN_BUF: /* SET INPUT BUFFER-SIZE */
8285 if ((z = cmnum("Number of bytes in INPUT buffer",
8286 ckitoa(INPBUFSIZ),10,&x, xxstring)) < 0)
8288 if ((y = cmcfm()) < 0) return(y);
8295 if (!(s = (char *)malloc(x + 1)))
8300 for (x = 0; x <= inbufsize; x++)
8302 return(success = 1);
8305 case IN_ADL: /* AUTODOWNLOAD */
8306 return(seton(&inautodl));
8307 #endif /* CK_AUTODL */
8309 case IN_CAN: /* SET INPUT INTERRUPTS */
8310 return(seton(&inintr));
8319 #ifndef NODIAL /* This depends on DIAL... */
8321 if (!ndinited) /* Don't free garbage... */
8323 for (i = 0; i < nhcount; i++) { /* Clean out previous list */
8330 for (j = 0; j < 4; j++) {
8340 ndinit() { /* Net directory pointers */
8341 #ifndef NODIAL /* This depends on DIAL... */
8343 if (ndinited++) /* Don't do this more than once. */
8345 for (i = 0; i < MAXDDIR; i++) { /* Init all pointers to NULL */
8348 for (i = 0; i < MAXDNUMS; i++) {
8351 for (j = 0; j < 4; j++)
8359 VOID /* Get net defaults from environment */
8363 makestr(&p,getenv("K_NET_DIRECTORY")); /* Dialing directories */
8366 xwords(p,MAXDDIR,netdir,0);
8367 for (i = 0; i < MAXDDIR; i++) { /* Fill in any gaps... */
8371 netdir[i] = netdir[i+1];
8372 debug(F111,"netdir[i]",netdir[i],i);
8377 #endif /* NETCONN */
8382 lunet(char *s) /* s = name to look up */
8385 #endif /* CK_ANSIC */
8387 #ifndef NODIAL /* This depends on DIAL... */
8388 int n, n1, t, dd = 0;
8393 int netdpy = dialdpy;
8396 nhcount = 0; /* Set this before returning */
8398 if (!s || nnetdir < 1) /* Validate arguments */
8401 if (isdigit(*s) || *s == '*' || *s == '.')
8404 if ((n1 = (int) strlen(s)) < 1) /* Length of string to look up */
8407 if (!(line = malloc(1024))) /* Allocate input buffer */
8411 f = NULL; /* Network directory file descriptor */
8412 t = nhcount = 0; /* Match count */
8413 dd = 0; /* Directory counter */
8416 while (1) { /* We make one pass */
8417 if (!f) { /* Directory not open */
8418 if (dd >= nnetdir) /* No directories left? */
8420 if ((f = fopen(netdir[dd],"r")) == NULL) { /* Open it */
8421 perror(netdir[dd]); /* Can't, print message saying why */
8423 continue; /* But go on to next one. */
8426 printf("Opening %s...\n",netdir[dd]);
8430 if (getnct(line,1023,f,1) < 0) { /* Read a line */
8431 if (f) { /* f can be clobbered! */
8432 fclose(f); /* Close the file */
8433 f = NULL; /* Indicate next one needs opening */
8437 if (!line[0]) /* Empty line */
8440 xwords(line,7,info,0); /* Parse it */
8442 if (!info[1] || !info[2] || !info[3]) /* Required fields */
8444 if (*info[1] == ';') /* Full-line comment */
8446 if ((n = (int) strlen(info[1])) < 1) /* Length of name-tag */
8448 if (n < n1) /* Search name is longer */
8449 continue; /* Can't possibly match */
8450 if (ambiguous && n != n1)
8452 if (ckstrcmp(s,info[1],n1,0)) /* Compare using length of */
8453 continue; /* search string s. */
8457 makestr(&(nh_p[nhcount]), info[3]); /* address */
8458 makestr(&(nh_p2[nhcount]),info[2]); /* net type */
8459 makestr(&(nh_px[0][nhcount]),info[4]); /* net-specific stuff... */
8460 makestr(&(nh_px[1][nhcount]),info[5]);
8461 makestr(&(nh_px[2][nhcount]),info[6]);
8462 makestr(&(nh_px[3][nhcount]),info[7]);
8464 nhcount++; /* Count this match */
8465 if (nhcount > MAXDNUMS) { /* Watch out for too many */
8466 printf("Warning: %d matches found, %d max\n",
8473 if (nhcount == 1) { /* First one - save entry name */
8474 if (n_name) { /* Free the one from before if any */
8478 if (!(n_name = (char *)malloc(n + 1))) { /* Allocate new storage */
8479 printf("?memory allocation error - lunet:3\n");
8487 t = n; /* Remember its length */
8488 strcpy(n_name,info[1]); /* safe */
8489 } else { /* Second or subsequent one */
8490 if ((int) strlen(info[1]) == t) /* Lengths compare */
8491 if (!ckstrcmp(n_name,info[1],t,0)) /* Caseless compare OK */
8494 /* Name given by user matches entries with different names */
8496 if (ambiguous) /* Been here before */
8499 ambiguous = 1; /* Now an exact match is required */
8500 ndreset(); /* Clear out previous list */
8501 goto lu_again; /* Do it all over again. */
8508 if (nhcount == 0 && ambiguous)
8509 printf("?\"%s\" - ambiguous in network directory\n",s);
8515 #endif /* NETCONN */
8518 /* C L S C O N N X -- Close connection */
8521 clsconnx(ask) int ask; {
8524 extern int ftpget, ftpisopen(), ftpbye();
8525 if ((ftpget == 1) || ((ftpget == 2) && !local && ftpisopen()))
8526 return(success = ftpbye());
8528 debug(F101,"clsconnx local","",local);
8530 x = ask ? hupok(1) : 1; /* Make sure it's OK to close */
8533 debug(F101,"clsconnx hupok says no","",rc);
8536 ttflui(); /* Clear away buffered up junk */
8539 /* Don't hangup a line that is shared with the SLIP or PPP driver */
8540 if (!ttslip && !ttppp)
8541 #endif /* OS2ONLY */
8544 if (network && msgflg)
8545 printf(" Closing connection\n");
8546 ttclos(0); /* Close old connection, if any */
8549 extern int wasclosed, whyclosed;
8551 whyclosed = WC_CLOS;
8553 if (nmac) { /* Any macros defined? */
8555 /* printf("ON_CLOSE CLSCONNX\n"); */
8557 k = mlook(mactab,"on_close",nmac); /* Look this up */
8558 if (k >= 0) { /* If found, */
8559 if (dodo(k,ckitoa(whyclosed),0) > -1) /* set it up, */
8560 parser(1); /* and execute it */
8564 whyclosed = WC_REMO;
8569 #ifdef VMS /* Or maybe #ifndef UNIX? */
8570 else { /* Need to do this in VMS to */
8571 ttclos(0); /* free the tty channel number */
8572 rc = 1; /* obtained in ttopen() or else */
8573 } /* subsequent ttopen's won't work */
8577 if (mdmtyp < 0) { /* Switching from net to async? */
8578 if (mdmsav > -1) /* Restore modem type from last */
8579 mdmtyp = mdmsav; /* SET MODEM command, if any. */
8587 if (oldplex > -1) { /* Restore previous duplex setting. */
8591 #endif /* NETCONN */
8593 ckstrncpy(ttname,dftty,TTNAMLEN); /* Restore default communication */
8595 local = dfloc; /* device and local/remote status */
8597 cxtype = CXT_DIRECT; /* Something reasonable */
8598 speed = ttgspd(); /* Get the current speed */
8600 cxtype = CXT_REMOTE;
8604 if (xreliable > -1 && !setreliable) {
8605 reliable = xreliable;
8606 debug(F101,"clsconnx reliable A","",reliable);
8607 } else if (!setreliable) {
8608 reliable = SET_AUTO;
8609 debug(F101,"clsconnx reliable B","",reliable);
8612 setflow(); /* Revert flow control */
8617 clskconnx(x) int x; { /* Close Kermit connection only */
8618 int t, rc; /* (not FTP) */
8631 /* May 2002: setlin() decomposition starts here ... */
8634 #define SRVBUFSIZ PIPENAML
8636 #define SRVBUFSIZ 63
8638 #define HOSTNAMLEN 15*65
8641 static char * tmpstring = NULL;
8642 static char * tmpusrid = NULL;
8645 char * sshcmd = NULL;
8646 char * defsshcmd = "ssh -e none";
8649 char * sshrcmd = NULL;
8650 char * sshtmpcmd = NULL;
8651 #endif /* SSHBUILTIN */
8654 /* c x _ f a i l -- Common error exit routine for cx_net, cx_line */
8657 cx_fail(msg, text) int msg; char * text; {
8658 makestr(&slmsg,text); /* For the record (or GUI) */
8659 if (msg) /* Not GUI, not quiet, etc */
8660 printf("?%s\n",text); /* Print error message */
8661 slrestor(); /* Restore LINE/HOST to known state */
8662 return(msg ? -9 : (success = 0)); /* Return appropriate code */
8666 /* c x _ n e t -- Make a network connection */
8671 protocol = protocol type
8672 host = string pointer to host name.
8673 svc = string pointer to service or port on host.
8674 username = username for connection
8675 password = password for connection
8676 command = command to execute
8677 param1 = Telnet: Authentication type
8679 param2 = Telnet: Encryption type
8680 SSH: Command as Subsystem
8681 param3 = Telnet: 1 to wait for negotiations, 0 otherwise
8683 cx = 1 to automatically enter Connect mode, 0 otherwise.
8684 sx = 1 to automatically enter Server mode, 0 otherwise.
8685 flag = if no host name given, 1 = close current connection, 0 = resume
8686 gui = 1 if called from GUI dialog, 0 otherwise.
8689 0 on failure and no message printed, slmsg set to failure message.
8690 -9 on failure and message printed, ditto.
8694 cx_net( int net, int protocol, char * xhost, char * svc,
8695 char * username, char * password, char * command,
8696 int param1, int param2, int param3, int cx, int sx, int flag, int gui)
8697 #else /* CK_ANSIC */
8698 cx_net(net, protocol, xhost, svc,
8699 username, password, command,
8700 param1, param2, param3, cx, sx, flag, gui)
8701 char * xhost, * svc, * username, *password, *command;
8702 int net, protocol, cx, sx, flag, param1, param2, param3, gui;
8703 #endif /* CK_ANSIC */
8709 extern char pwbuf[], * g_pswd;
8710 extern int pwflg, pwcrypt, g_pflg, g_pcpt, nolocal;
8712 char srvbuf[SRVBUFSIZ+1]; /* Service */
8713 char hostbuf[HOSTNAMLEN]; /* Host buffer to manipulate */
8714 char hostname[HOSTNAMLEN]; /* Copy of host parameter */
8715 char * host = hostbuf; /* Pointer to copy of host param */
8717 if (!xhost) xhost = ""; /* Watch out for null pointers */
8719 ckstrncpy(host,xhost,HOSTNAMLEN); /* Avoid buffer confusion */
8721 debug(F110,"cx_net host",host,0);
8722 debug(F111,"cx_net service",svc,SRVBUFSIZ);
8723 debug(F101,"cx_net network type","",net);
8725 msg = (gui == 0) && msgflg; /* Whether to print messages */
8728 debug(F101,"cx_net nnetdir","",nnetdir);
8729 x = 0; /* Look up in network directory */
8730 if (*host == '=') { /* If number starts with = sign */
8731 host++; /* strip it */
8732 while (*host == SP) host++; /* and any leading spaces */
8733 debug(F110,"cx_net host 2",host,0);
8735 } else if (*host) { /* We want to look it up. */
8736 if (nnetdir > 0) /* If there is a directory... */
8737 x = lunet(host); /* (sets nhcount) */
8738 else /* otherwise */
8739 nhcount = 0; /* we didn't find any there */
8740 if (x < 0) /* Internal error? */
8741 return(cx_fail(msg,"Network directory lookup error"));
8742 debug(F111,"cx_net lunet nhcount",host,nhcount);
8746 /* New connection wanted. Make a copy of the host name/address... */
8748 if (clskconnx(1) < 0) /* Close current Kermit connection */
8749 return(cx_fail(msg,"Error closing previous connection"));
8751 if (*host) { /* They gave a hostname */
8752 _local = 1; /* Network connection always local */
8754 mdmsav = mdmtyp; /* Remember old modem type */
8755 mdmtyp = -net; /* Special code for network */
8756 } else { /* They just said "set host" */
8757 host = dftty; /* So go back to normal */
8758 _local = dfloc; /* default tty, location, */
8759 if (flag) { /* Close current connection */
8760 setflow(); /* Maybe change flow control */
8761 haveline = 1; /* (* is this right? *) */
8771 /* XXX - Is this right? */
8772 /* Should we be returning without doing anything ? */
8773 /* Yes it's right -- we closed the old connection just above. */
8774 return(success = 1);
8778 if (host != line) /* line[] is a global */
8779 ckstrncpy(line,host,LINBUFSIZ);
8780 ckstrncpy(hostname,host,HOSTNAMLEN);
8781 ckstrncpy(srvbuf,svc,SRVBUFSIZ+1);
8784 if ((nhcount > 1) && msg) {
8786 printf("%d entr%s found for \"%s\"%s\n",
8788 (nhcount == 1) ? "y" : "ies",
8790 (nhcount > 0) ? ":" : "."
8792 for (i = 0; i < nhcount; i++) {
8793 printf("%3d. %-12s => %-9s %s",
8794 i+1,n_name,nh_p2[i],nh_p[i]);
8795 for (k = 0; k < 4; k++) { /* Also list net-specific items */
8796 if (nh_px[k][i]) /* free format... */
8797 printf(" %s",nh_px[k][i]);
8813 for (i = 0; i < n; i++) { /* Loop for each entry found */
8814 debug(F101,"cx_net loop i","",i);
8816 if (nhcount > 0) { /* If we found at least one entry... */
8817 ckstrncpy(line,nh_p[i],LINBUFSIZ); /* Copy current entry */
8818 if (lookup(netcmd,nh_p2[i],nnets,&x) > -1) { /* Net type */
8820 xx = netcmd[x].kwval;
8821 /* User specified SSH so don't let net directory override */
8822 if (net != NET_SSH || xx != NET_TCPB) {
8827 makestr(&slmsg,"Network type not supported");
8829 printf("Error - network type \"%s\" not supported\n",
8834 switch (net) { /* Net-specific directory things */
8836 case NET_SSH: /* SSH */
8837 /* Any SSH specific network directory stuff? */
8838 break; /* NET_SSH */
8839 #endif /* SSHBUILTIN */
8841 case NET_TCPB: { /* TCP/IP TELNET,RLOGIN,... */
8846 /* Extract ":service", if any, from host string */
8847 debug(F110,"cx_net service 1",line,0);
8848 for (q = line; (*q != '\0') && (*q != ':'); q++)
8850 if (*q == ':') { *q++ = NUL; flag = 1; }
8851 debug(F111,"cx_net service 2",line,flag);
8853 /* Get service, if any, from directory entry */
8857 ckstrncpy(srvbuf,nh_px[0][i],SRVBUFSIZ);
8858 debug(F110,"cx_net service 3",srvbuf,0);
8861 ckstrncpy(srvbuf,q,SRVBUFSIZ);
8862 debug(F110,"cx_net service 4",srvbuf,0);
8865 ckstrncpy(hostname,line,HOSTNAMLEN);
8867 /* If we have a service, append to host name/address */
8869 ckstrncat(line, ":", LINBUFSIZ);
8870 ckstrncat(line, srvbuf, LINBUFSIZ);
8871 debug(F110,"cx_net service 5",line,0);
8874 /* If no service given but command was RLOGIN */
8875 else if (ttnproto == NP_RLOGIN) { /* add this... */
8876 ckstrncat(line, ":login",LINBUFSIZ);
8877 debug(F110,"cx_net service 6",line,0);
8879 #ifdef CK_AUTHENTICATION
8881 else if (ttnproto == NP_K4LOGIN ||
8882 ttnproto == NP_K5LOGIN) { /* add this... */
8883 ckstrncat(line, ":klogin",LINBUFSIZ);
8884 debug(F110,"cx_net service 7",line,0);
8886 else if (ttnproto == NP_EK4LOGIN ||
8887 ttnproto == NP_EK5LOGIN) { /* add this... */
8888 ckstrncat(line, ":eklogin",LINBUFSIZ);
8889 debug(F110,"cx_net service 8",line,0);
8891 #endif /* CK_KERBEROS */
8892 #endif /* CK_AUTHENTICATION */
8893 #endif /* RLOGCODE */
8894 else { /* Otherwise, add ":telnet". */
8895 ckstrncat(line, ":telnet", LINBUFSIZ);
8896 debug(F110,"cx_net service 9",line,0);
8898 if (username) { /* This is a parameter... */
8899 ckstrncpy(uidbuf,username,UIDBUFLEN);
8902 /* Fifth field, if any, is user ID (for rlogin) */
8904 if (nh_px[1][i] && !uidflag)
8905 ckstrncpy(uidbuf,username,UIDBUFLEN);
8907 if (IS_RLOGIN() && !uidbuf[0])
8908 return(cx_fail(msg,"Username required"));
8909 #endif /* RLOGCODE */
8910 #endif /* TCPSOCKET */
8913 case NET_PIPE: /* Pipe */
8915 if (!pipename[0]) { /* User didn't give a pipename */
8916 if (nh_px[0][i]) { /* But directory entry has one */
8917 if (strcmp(pipename,"\\pipe\\")) {
8918 ckstrncpy(pipename,"\\pipe\\",LINBUFSIZ);
8919 ckstrncat(srvbuf,nh_px[0][i],PIPENAML-6);
8921 ckstrncpy(pipename,nh_px[0][i],PIPENAML);
8923 debug(F110,"cx_net pipeneme",pipename,0);
8929 case NET_SLAT: /* LAT / CTERM */
8931 if (!slat_pwd[0]) { /* User didn't give a password */
8932 if (nh_px[0][i]) { /* But directory entry has one */
8933 ckstrncpy(slat_pwd,nh_px[0][i],18);
8934 debug(F110,"cx_net SuperLAT password",slat_pwd,0);
8937 #endif /* SUPERLAT */
8940 case NET_SX25: /* X.25 keyword parameters */
8944 int k; /* Cycle through the four fields */
8945 for (k = 0; k < 4; k++) {
8946 if (!nh_px[k][i]) /* Bail out if none left */
8948 if (!ckstrcmp(nh_px[k][i],"cug=",4,0)) {
8949 closgr = atoi(nh_px[k][i]+4);
8950 debug(F101,"X25 CUG","",closgr);
8951 } else if (!ckstrcmp(nh_px[k][i],"cud=",4,0)) {
8953 ckstrncpy(udata,nh_px[k][i]+4,MAXCUDATA);
8954 debug(F110,"X25 CUD",cudata,0);
8955 } else if (!ckstrcmp(nh_px[k][i],"rev=",4,0)) {
8956 revcall = !ckstrcmp(nh_px[k][i]+4,"=on",3,0);
8957 debug(F101,"X25 REV","",revcall);
8959 } else if (!ckstrcmp(nh_px[k][i],"pad=",4,0)) {
8962 s1 = s2 = nh_px[k][i]+4; /* PAD parameters */
8963 while (*s2) { /* Pick them apart */
8969 } else if (*s2 == ',') {
8973 debug(F111,"X25 PAD",x3par,x3val);
8975 x3par <= MAXPADPARMS)
8976 padparms[x3par] = x3val;
8987 default: /* Nothing special for other nets */
8992 { /* No directory entries found. */
8993 ckstrncpy(line,hostname,LINBUFSIZ); /* Put this back... */
8994 /* If the user gave a TCP service */
8995 if (net == NET_TCPB || net == NET_SSH)
8996 if (*srvbuf) { /* Append it to host name/address */
8997 ckstrncat(line, ":", LINBUFSIZ);
8998 ckstrncat(line, srvbuf,LINBUFSIZ);
9002 Get here with host name/address and all net-specific
9003 parameters set, ready to open the connection.
9005 mdmtyp = -net; /* This should have been done */
9006 /* already but just in case ... */
9008 debug(F110,"cx_net net line[] before ttopen",line,0);
9009 debug(F101,"cx_net net mdmtyp before ttopen","",mdmtyp);
9010 debug(F101,"cx_net net ttnproto","",ttnproto);
9013 if (net == NET_SSH) {
9014 makestr(&ssh_hst,hostname); /* Stash everything */
9016 if (!sl_uid_saved) {
9017 ckstrncpy(sl_uidbuf,uidbuf,UIDBUFLEN);
9020 ckstrncpy(uidbuf,username,UIDBUFLEN);
9023 makestr(&ssh_prt,srvbuf);
9025 makestr(&ssh_prt,NULL);
9028 makestr(&ssh_cmd,brstrip(command));
9031 makestr(&ssh_cmd,NULL);
9035 if (!sl_ssh_ver_saved) {
9036 sl_ssh_ver = ssh_ver;
9037 sl_ssh_ver_saved = 1;
9039 #endif /* SSHTEST */
9044 if (!sl_ssh_xfw_saved) {
9045 sl_ssh_xfw = ssh_xfw;
9046 sl_ssh_xfw_saved = 1;
9048 #endif /* SSHTEST */
9051 } else /* NET_SSH */
9052 #endif /* SSHBUILTIN */
9054 if (net == NET_TCPB) {
9058 ttnproto = protocol;
9064 ttnproto = protocol;
9070 ttnproto = NP_TELNET;
9076 ttnproto = NP_TELNET;
9091 ttnproto = protocol;
9098 #ifdef CK_AUTHENTICATION
9099 if ((ttnproto == NP_TELNET || ttnproto == NP_KERMIT) &&
9101 if (!sl_auth_saved) {
9103 for (x = 0; x < AUTHTYPLSTSZ; x++)
9104 sl_auth_type_user[x] = auth_type_user[x];
9107 if (!sl_topt_a_s_saved) {
9108 sl_topt_a_su = TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION);
9109 sl_topt_a_s_saved = 1;
9111 if (!sl_topt_a_c_saved) {
9112 sl_topt_a_cm = TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION);
9113 sl_topt_a_c_saved = 1;
9117 auth_type_user[0] = AUTHTYPE_AUTO;
9118 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_RQ;
9119 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_RQ;
9122 auth_type_user[0] = AUTHTYPE_NULL;
9123 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_RF;
9124 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_RF;
9128 auth_type_user[0] = AUTHTYPE_SRP;
9129 auth_type_user[1] = AUTHTYPE_NULL;
9130 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9131 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9136 auth_type_user[0] = AUTHTYPE_SSL;
9137 auth_type_user[1] = AUTHTYPE_NULL;
9138 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9139 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9144 auth_type_user[0] = AUTHTYPE_NTLM;
9145 auth_type_user[1] = AUTHTYPE_NULL;
9146 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9147 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9151 case AUTHTYPE_KERBEROS_V4:
9152 auth_type_user[0] = AUTHTYPE_KERBEROS_V4;
9153 auth_type_user[1] = AUTHTYPE_NULL;
9154 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9155 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9158 case AUTHTYPE_KERBEROS_V5:
9159 auth_type_user[0] = AUTHTYPE_KERBEROS_V5;
9160 auth_type_user[1] = AUTHTYPE_NULL;
9161 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9162 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9164 #endif /* CK_KERBEROS */
9168 If the user requires a particular type of Kerberos connection,
9169 make sure we have a valid TGT.
9171 makestr(&slmsg,"Authentication failure");
9172 if ((ttnproto == NP_TELNET || ttnproto == NP_KERMIT) &&
9174 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) == TN_NG_MU ||
9176 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) == TN_NG_MU)
9179 if ( auth_type_user[0] == AUTHTYPE_KERBEROS_V4 ) {
9180 extern int krb4_autoget;
9181 if (!ck_krb4_is_installed())
9183 "Required authentication method (Kerberos 4) is not installed"));
9185 /* This code results in false failures when using */
9186 /* kerberos to machines in realms other than the */
9187 /* default since we don't know the realm of the */
9188 /* other machine until perform the reverse DNS */
9190 else if (line[0] != '*' && !ck_krb4_is_tgt_valid() &&
9192 krb4_autoget && !ck_krb4_autoget_TGT(NULL))) {
9194 "Kerberos 4: Ticket Getting Ticket not valid"));
9196 #endif /* COMMENT */
9197 } else if (auth_type_user[0] == AUTHTYPE_KERBEROS_V5) {
9198 extern int krb5_autoget;
9199 if (!ck_krb5_is_installed()) {
9201 "Required authentication method (Kerberos 5) is not installed"));
9204 /* This code results in false failures when using */
9205 /* kerberos to machines in realms other than the */
9206 /* default since we don't know the realm of the */
9207 /* other machine until perform the reverse DNS */
9209 else if (line[0] != '*' && !ck_krb5_is_tgt_valid() &&
9211 krb5_autoget && !ck_krb5_autoget_TGT(NULL))) {
9213 "Kerberos 5: Ticket Getting Ticket not valid."));
9215 #endif /* COMMENT */
9217 #endif /* CK_KERBEROS */
9219 if (auth_type_user[0] == AUTHTYPE_NTLM) {
9220 if (!ck_ntlm_is_installed()) {
9222 "Required authentication method (NTLM) is not installed"));
9223 } else if (line[0] != '*' && !ck_ntlm_is_valid(0)) {
9224 return(cx_fail(msg,"NTLM: Credentials are unavailable."));
9229 if (auth_type_user[0] == AUTHTYPE_SSL) {
9230 if (!ck_ssleay_is_installed()) {
9232 "Required authentication method (SSL) is not installed"));
9237 if (auth_type_user[0] == AUTHTYPE_SRP) {
9238 if (!ck_srp_is_installed()) {
9240 "Required authentication method (SRP) is not installed"));
9245 #endif /* CK_AUTHENTICATION */
9246 #ifdef CK_ENCRYPTION
9247 if ((ttnproto == NP_TELNET || ttnproto == NP_KERMIT) &&
9250 sl_cx_type = cx_type;
9253 if (!sl_topt_e_s_saved) {
9254 sl_topt_e_su = TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION);
9255 sl_topt_e_sm = TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION);
9256 sl_topt_e_s_saved = 1;
9258 if (!sl_topt_e_c_saved) {
9259 sl_topt_e_cu = TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION);
9260 sl_topt_e_cm = TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION);
9261 sl_topt_e_c_saved = 1;
9264 if (cx_type == CX_AUTO) {
9265 TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
9266 TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
9267 TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
9268 TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
9269 } else if (cx_type == CX_NONE) {
9270 TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
9271 TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
9272 TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
9273 TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
9275 TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
9276 TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
9277 TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
9278 TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
9281 if (ttnproto == NP_EK4LOGIN || ttnproto == NP_EK5LOGIN ||
9282 (ttnproto == NP_TELNET || ttnproto == NP_KERMIT) &&
9284 TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) == TN_NG_MU &&
9285 TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_MU) ||
9287 TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) == TN_NG_MU &&
9288 TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_MU))
9290 if (!ck_crypt_is_installed()) {
9292 "Required Encryption methods are not installed"));
9295 #endif /* CK_ENCRYPTION */
9299 if (ttnproto == NP_K4LOGIN || ttnproto == NP_EK4LOGIN) {
9300 extern int krb4_autoget;
9304 /* We don't have the full hostname at yet so */
9305 /* we do a DNS lookup before calling ttopen() */
9307 realm = ck_krb4_realmofhost(ckgetfqhostname(hostname));
9308 ckmakmsg(tgt,256,"krbtgt.",realm,"@",realm);
9309 if (!ck_krb4_is_installed()) {
9311 "Required authentication method (Kerberos 4) is not installed"
9314 if ((ck_krb4_tkt_isvalid(tgt) <= 0) &&
9316 krb4_autoget && !ck_krb4_autoget_TGT(realm))) {
9318 "Kerberos 4: Ticket Getting Ticket not valid"));
9324 if (ttnproto == NP_K5LOGIN || ttnproto == NP_EK5LOGIN ||
9325 ttnproto == NP_K5U2U)
9327 extern int krb5_autoget;
9331 /* Must get full hostname before calling ttopen() */
9333 realm = ck_krb5_realmofhost(ckgetfqhostname(hostname));
9334 ckmakmsg(tgt,256,"krbtgt/",realm,"@",realm);
9336 if (!ck_krb5_is_installed()) {
9338 "Required authentication method (Kerberos 5) not installed"));
9339 } else if (!((ck_krb5_tkt_isvalid(NULL,tgt) > 0) ||
9340 ck_krb5_is_tgt_valid()) &&
9342 krb5_autoget && !ck_krb5_autoget_TGT(realm))) {
9344 "Kerberos 5: Ticket Getting Ticket not valid."));
9348 #endif /* CK_KERBEROS */
9349 #endif /* RLOGCODE */
9354 if (!sl_uid_saved) {
9355 ckstrncpy(sl_uidbuf,uidbuf,UIDBUFLEN);
9358 ckstrncpy(uidbuf,username,UIDBUFLEN);
9361 #endif /* RLOGCODE */
9364 sl_tn_wait = tn_wait_flg;
9367 tn_wait_flg = param3;
9370 } /* if (net == NET_TCPB) */
9371 #endif /* TCPSOCKET */
9377 ckstrncpy(pwbuf,password,PWBUFL+1);
9383 #endif /* CK_SECURITY */
9386 /* Try to open - network */
9387 ckstrncpy(ttname,line,TTNAMLEN);
9388 y = ttopen(line, &_local, mdmtyp, 0 );
9391 /* If the connection failed and we are using an HTTP Proxy
9392 * and the reason for the failure was an authentication
9393 * error, then we need to give the user to ability to
9394 * enter a username and password, just like a browser.
9396 * I tried to do all of this within the netopen() call
9397 * but it is much too much work.
9399 while (y < 0 && tcp_http_proxy != NULL ) {
9401 if (tcp_http_proxy_errno == 401 ||
9402 tcp_http_proxy_errno == 407 ) {
9403 char uid[UIDBUFLEN];
9405 struct txtbox tb[2];
9409 tb[0].t_len = UIDBUFLEN;
9410 tb[0].t_lbl = "Proxy Userid: ";
9411 tb[0].t_dflt = NULL;
9415 tb[1].t_lbl = "Proxy Passphrase: ";
9416 tb[1].t_dflt = NULL;
9419 ok = uq_mtxt("Proxy Server Authentication Required\n",
9423 char * proxy_user, * proxy_pwd;
9425 proxy_user = tcp_http_proxy_user;
9426 proxy_pwd = tcp_http_proxy_pwd;
9428 tcp_http_proxy_user = uid;
9429 tcp_http_proxy_pwd = pwd;
9431 ckstrncpy(ttname,line,TTNAMLEN);
9432 y = ttopen(line, &_local, mdmtyp, 0);
9433 memset(pwd,0,sizeof(pwd));
9434 tcp_http_proxy_user = proxy_user;
9435 tcp_http_proxy_pwd = proxy_pwd;
9444 makestr(&slmsg,"Network connection failure");
9446 if (msg && hints && !xcmdsrc && IS_RLOGIN()) {
9447 makestr(&slmsg,"RLOGIN failure");
9448 if (socket_errno == EACCES) {
9449 printf("*************************\n");
9451 "Hint: RLOGIN requires privileges to open an outbound port.\n");
9453 "(Use SET HINTS OFF to suppress future hints.)\n");
9454 printf("*************************\n");
9457 #else /* Not VMS... */
9460 debug(F111,"set host line, errno","",errno);
9461 makestr(&slmsg,ck_errstr());
9464 printf("Can't connect to %s\n",line);
9467 if (hints && !xcmdsrc && IS_RLOGIN()) {
9468 makestr(&slmsg,"RLOGIN failure");
9469 printf("*************************\n");
9471 "Hint: RLOGIN requires privileges to open an outbound port.\n");
9473 "(Use SET HINTS OFF to suppress future hints.)\n");
9474 printf("*************************\n");
9478 } else printf("Can't connect to %s\n",line);
9481 if (msg) printf("Can't open connection to %s\n",line);
9493 /* This works but it messes up interactive anonymous login */
9496 /* If we have connected to an Internet Kermit service */
9497 /* and a /USER: switch was given, then log in. */
9499 if (TELOPT_U(TELOPT_KERMIT) || TELOPT_ME(TELOPT_KERMIT)) {
9500 debug(F111,"cx_net IKSD /USER:",uidbuf,haveuser);
9501 if (haveuser /* && cx == 0 */ ) { /* /USER: given */
9502 char * psw = pwbuf; /* Do we have a password? */
9503 if (!*psw) { /* No... */
9504 if (!strcmp(uidbuf,"anonymous") ||
9505 !strcmp(uidbuf,"ftp")) {
9506 extern char myhost[];
9507 char * u = (char *)sl_uidbuf;
9508 char * h = (char *)myhost;
9509 if (!*u) u = "nobody";
9510 if (!*h) h = "nowhere";
9511 ckmakmsg(tmpbuf,TMPBUFSIZ,u,"@",h,NULL);
9513 debug(F110,"cx_net IKSD anon",psw,0);
9515 readpass(" Password: ",pwbuf,PWBUFL);
9518 sstate = setgen('I',uidbuf,psw,"");
9521 #endif /* IKS_OPTION */
9523 #endif /* COMMENT */
9527 duplex = 0; /* Remote echo */
9539 cxtype = CXT_NETBIOS;
9557 debug(F101,"cx_net post ttopen success","",success);
9559 local = dfloc; /* Go back to normal */
9561 ckstrncpy(ttname,dftty,TTNAMLEN); /* Restore default tty name */
9564 network = 0; /* No network connection active */
9566 if (mdmtyp < 0) { /* Switching from net to async? */
9567 if (mdmsav > -1) /* Restore modem type from last */
9568 mdmtyp = mdmsav; /* SET MODEM command, if any. */
9573 return(0); /* Return failure */
9575 if (_local > -1) local = _local; /* Opened ok, set local/remote. */
9576 makestr(&slmsg,NULL);
9577 network = (mdmtyp < 0); /* Remember connection type. */
9578 ckstrncpy(ttname,s,TTNAMLEN); /* Copy name into real place. */
9579 debug(F110,"cx_net ok",ttname,0);
9580 debug(F101,"cx_net network","",network);
9582 if ((reliable != SET_OFF || !setreliable)) /* Assume not reliable. */
9585 if (!network || istncomport())
9586 speed = ttgspd(); /* Get the current speed. */
9587 debug(F101,"cx_net local","",local);
9589 debug(F101,"cx_net net","",net);
9591 /* Force prefixing of 255 on TCP/IP connections... */
9595 #endif /* SSHBUILTIN */
9597 debug(F101,"cx_net reliable A","",reliable);
9599 ctlp[(unsigned)255] = 1;
9600 #endif /* CK_SPEED */
9601 if ((reliable != SET_OFF || !setreliable)) {
9603 if (istncomport()) { /* Telnet communication port */
9604 reliable = SET_OFF; /* Transport is not reliable */
9605 debug(F101,"cx_net reliable istncomport()","",1);
9607 reliable = SET_ON; /* Transport is reliable end to end */
9608 debug(F101,"cx_net reliable istncomport()","",0);
9611 reliable = SET_ON; /* Transport is reliable end to end */
9612 #endif /* ifdef TN_COMPORT */
9614 debug(F101,"cx_net reliable B","",reliable);
9615 } else if (net == NET_SX25 ||
9619 duplex = 1; /* Local echo for X.25 */
9620 if (reliable != SET_OFF || !setreliable)
9621 reliable = SET_ON; /* Transport is reliable end to end */
9626 debug(F101,"cx_net reliable","",reliable);
9629 if (mdmtyp <= 0) /* Network or Direct Connection */
9630 DialerSend(OPT_KERMIT_CONNECT, 0);
9635 setflow(); /* Set appropriate flow control */
9640 #endif /* CKLOGDIAL */
9644 if (nmac) { /* Any macros defined? */
9646 k = mlook(mactab,"on_open",nmac); /* Look this up */
9647 if (k >= 0) { /* If found, */
9648 if (dodo(k,ttname,0) > -1) /* set it up, */
9649 parser(1); /* and execute it */
9655 if (local && (cx || sx)) { /* /CONNECT or /SERVER switch given */
9656 if (cx) { /* /CONNECT */
9658 /* Command was confirmed so we can pre-pop command level. */
9659 /* This is so CONNECT module won't think we're executing a */
9660 /* script if CONNECT was the final command in the script. */
9672 success = doconect(0, cmdlvl == 0 ? 1 : 0);
9675 debug(F101,"cx_net post doconect success","",success);
9678 } else if (sx) { /* /SERVER */
9684 if (local) displa = 1;
9686 reqoff(); /* No DOS requestors while server */
9699 return(success = 1);
9701 #endif /* NETCONN */
9703 /* c x _ s e r i a l -- Make a serial connection */
9707 device = string pointer to device name.
9708 cx = 1 to automatically enter Connect mode, 0 otherwise.
9709 sx = 1 to automatically enter Server mode, 0 otherwise.
9710 shr = 1 if device should be opened in shareable mode, 0 otherwise.
9711 flag = if no dev name given: 1 = close current connection, 0 = resume.
9712 gui = 1 if called from GUI dialog, 0 otherwise.
9715 0 on failure and no message printed, slmsg set to failure message.
9716 -9 on failure and message printed, ditto.
9719 /* these are bit flags */
9726 cx_serial(char *device,
9727 int cx, int sx, int shr, int flag, int gui, int special)
9728 #else /* CK_ANSIC */
9729 cx_serial(device, cx, sx, shr, flag, gui, special)
9730 char * device; int cx, sx, shr, flag, gui, special;
9731 #endif /* CK_ANSIC */
9733 int i, n, x, y, msg;
9737 debug(F110,"cx_serial device",device,0);
9739 msg = (gui == 0) && msgflg; /* Whether to print messages */
9745 debug(F101,"cx_serial mdmtyp","",mdmtyp);
9746 if (clskconnx(1) < 0) /* Close the Kermit connection */
9747 return(success = 0);
9748 if (*s) { /* They gave a device name */
9749 _local = -1; /* Let ttopen decide about it */
9750 } else { /* They just said "set line" */
9751 s = dftty; /* so go back to normal tty */
9752 _local = dfloc; /* and mode. */
9756 extern int ok_to_share;
9761 #ifdef OS2 /* Must wait until after ttclos() */
9762 #ifdef NT /* to change these settings */
9764 tttapi = special & CX_TAPI;
9765 #endif /* CK_TAPI */
9767 ttslip = special & CX_SLIP;
9768 ttppp = special & CX_PPP;
9770 ttshare = shr; /* Shareable device ? */
9771 debug(F110,"OS2 SET PORT final s",s,"");
9774 /* Open the new line */
9776 ckstrncpy(ttname,s,TTNAMLEN);
9777 if ((y = ttopen(s,&_local,mdmtyp,cdtimo)) > -1) {
9778 cxtype = (mdmtyp > 0) ? CXT_MODEM : CXT_DIRECT;
9782 /* if the line is a tapi device, then we need to auto-execute */
9783 /* SET MODEM TYPE TAPI - which we do the equivalent of here. */
9787 initmdm(38); /* From ckudia.c n_TAPI == 38 */
9789 #endif /* CK_TAPI */
9792 } else { /* Failed */
9794 if (!strcmp(s,dftty)) /* Do not generate an error with dftty */
9796 else if (y == -6 && ttslip) {
9797 makestr(&slmsg,"Can't access SLIP driver");
9798 if (msg) printf("?%s\n",slmsg);
9799 } else if (y == -6 && ttppp) {
9800 makestr(&slmsg,"Can't access PPP driver");
9801 if (msg) printf("?%s\n",slmsg);
9803 #endif /* OS2ONLY */
9805 makestr(&slmsg,"Timed out - no carrier");
9807 printf("?%s\n",slmsg);
9809 printf("\n*************************\n");
9811 "HINT (Use SET HINTS OFF to suppress future hints):\n");
9813 "Try SET CARRIER OFF and SET LINE again, or else\n");
9814 printf("SET MODEM, SET LINE, and then DIAL.\n");
9815 printf("*************************\n\n");
9818 } else if (y == -3) {
9819 makestr(&slmsg,"Access to lock denied");
9823 "Sorry, write access to UUCP lockfile directory denied.\n");
9826 printf("\n*************************\n");
9828 "HINT (Use SET HINTS OFF to suppress future hints):\n");
9830 "Please read the installation instructions file, %sckuins.txt,\n",
9831 k_info_dir ? k_info_dir : ""
9834 "or the UNIX appendix of the manual, \"Using C-Kermit\"\n"
9837 "or visit http://www.columbia.edu/kermit/ckuins.html \n"
9839 printf("*************************\n\n");
9841 #endif /* NOHINTS */
9843 printf("Sorry, access to lock denied: %s\n",s);
9846 } else if (y == -4) {
9847 makestr(&slmsg,"Access to device denied");
9849 printf("Sorry, access to device denied: %s\n",s);
9853 printf("\n*************************\n");
9855 "HINT (Use SET HINTS OFF to suppress future hints):\n");
9857 "Please read the installation instructions file, %sckuins.txt,\n",
9858 k_info_dir ? k_info_dir : ""
9861 "or the UNIX appendix of the manual, \"Using C-Kermit\".\n"
9863 printf("*************************\n\n");
9865 #endif /* NOHINTS */
9868 } else if (y == -5) {
9869 makestr(&slmsg,"Device is in use or unavailable");
9873 "Sorry, device is in use or otherwise unavailable: %s\n",s);
9875 printf("Sorry, device is in use: %s\n",s);
9877 } else { /* Other error. */
9878 makestr(&slmsg,"Device open failed");
9886 int x; /* Find a safe, long buffer */
9887 makestr(&slmsg,ck_errstr());
9889 debug(F111,"cx_serial serial errno",slmsg,errno);
9892 printf("Connection to %s failed: %s\n",s,slmsg);
9894 printf("Sorry, can't open connection: %s\n",s);
9897 network = 0; /* No network connection active */
9900 local = dfloc; /* Go back to normal */
9902 ckstrncpy(ttname,dftty,TTNAMLEN); /* Restore default tty name */
9905 if (mdmtyp < 0) { /* Switching from net to async? */
9906 if (mdmsav > -1) /* Restore modem type from last */
9907 mdmtyp = mdmsav; /* SET MODEM command, if any. */
9912 return(msg ? -9 : 0); /* Return failure */
9915 local = _local; /* Opened ok, set local/remote. */
9916 makestr(&slmsg,NULL); /* Erase SET LINE message */
9917 ckstrncpy(ttname,s,TTNAMLEN); /* Copy name into real place. */
9918 debug(F110,"cx_serial ok",ttname,0);
9920 if ((reliable != SET_OFF || !setreliable)) /* Assume not reliable. */
9925 setflow(); /* Set appropriate flow control */
9929 #endif /* CKLOGDIAL */
9933 if (nmac) { /* Any macros defined? */
9935 k = mlook(mactab,"on_open",nmac); /* Look this up */
9936 if (k >= 0) { /* If found, */
9937 if (dodo(k,ttname,0) > -1) /* set it up, */
9938 parser(1); /* and execute it */
9944 if (local && (cx || sx)) { /* /CONNECT or /SERVER switch given */
9946 if (carrier != CAR_OFF) { /* Looking for carrier? */
9947 /* Open() turns on DTR -- wait up to a second for CD to come up */
9949 for (i = 0; i < 10; i++) { /* WAIT 1 CD... */
9951 if (x < 0 || x & BM_DCD)
9956 if (cx) { /* /CONNECT */
9957 /* Command was confirmed so we can pre-pop command level. */
9958 /* This is so CONNECT module won't think we're executing a */
9959 /* script if CONNECT was the final command in the script. */
9971 success = doconect(0, cmdlvl == 0 ? 1 : 0);
9976 } else if (sx) { /* /SERVER */
9982 if (local) displa = 1;
9984 reqoff(); /* No DOS requestors while server */
9997 return(success = 1);
10001 /* S E T L I N -- parse name of and then open communication device. */
10004 xx == XYLINE for a serial (tty) line, XYHOST for a network host,
10005 zz == 0 means if user doesn't give a device name, continue current
10006 active connection (if any);
10007 zz != 0 means if user doesn't give a device name, then close the
10008 current connection and restore the default communication device.
10009 fc == 0 to just make the connection, 1 to also CONNECT (e.g. "telnet").
10015 extern char pwbuf[], * g_pswd;
10016 extern int pwflg, pwcrypt, g_pflg, g_pcpt, nolocal;
10018 /* int tn_wait_sv; */
10021 int c, i, haveswitch = 0;
10024 int wild = 0; /* Filespec has wildcards */
10025 int cx = 0; /* Connect after */
10026 int sx = 0; /* Become server after */
10027 int a_type = -1; /* Authentication type */
10028 int e_type = -1; /* Telnet /ENCRYPT type */
10029 #ifdef CK_ENCRYPTION
10030 int encrypt = 0; /* Encrypted? */
10031 #endif /* CK_ENCRYPTION */
10032 int shr = 0; /* Share serial device */
10033 int confirmed = 0; /* Command has been entered */
10034 struct FDB sw, tx, nx;
10042 #endif /* TCPSOCKET */
10044 char srvbuf[SRVBUFSIZ+1];
10050 int xxslip = 0, xxppp = 0;
10056 debug(F101,"setlin fc","",fc);
10057 debug(F101,"setlin zz","",zz);
10058 debug(F101,"setlin xx","",xx);
10061 if (xx == XXSSH) { /* SSH becomes PTY SSH ... */
10065 #endif /* SSHCMD */
10068 /* tn_wait_sv = tn_wait_flg; */
10069 wait = tn_wait_flg;
10071 /* tn_wait_sv = 0; */
10073 #endif /* TNCODE */
10078 makestr(&slmsg,"Making connections is disabled");
10079 printf("?Sorry, making connections is disabled\n");
10085 if (fc != 0 || zz == 0) /* Preset /CONNECT switch */
10088 debug(F101,"setlin cx","",cx);
10098 makestr(&tmpstring,NULL);
10099 #endif /* CK_SECURITY */
10101 makestr(&tmpusrid,NULL);
10102 #endif /* NETCONN */
10104 autoflow = 1; /* Enable automatic flow setting */
10106 if (xx == XYHOST) { /* SET HOST <hostname> */
10108 makestr(&slmsg,"Network connections not supported");
10109 printf("?%s\n",slmsg);
10111 #else /* NETCONN */
10113 if ((mynet == NET_CMD || mynet == NET_PTY || dossh) && nopush) {
10114 makestr(&slmsg,"Access to external commands is disabled");
10115 printf("?Sorry, access to external commands is disabled\n");
10118 #endif /* NOPUSH */
10121 if (dossh) { /* SSH connection via pty */
10123 k = ckstrncpy(line, sshcmd ? sshcmd : defsshcmd, LINBUFSIZ);
10124 debug(F111,"setlin sshcmd 1",line,k);
10125 if ((x = cmtxt("Optional switches and hostname","",&s,xxstring))<0)
10128 printf("?SSH to where?\n");
10131 if (k < LINBUFSIZ) {
10134 debug(F111,"setlin sshcmd 2",line,k);
10135 } if (k < LINBUFSIZ) {
10136 ckstrncpy(&line[k],s,LINBUFSIZ-k);
10137 debug(F111,"setlin sshcmd 3",line,k);
10139 printf("?Too long\n");
10142 x = cx_net( NET_PTY, /* network type */
10143 0, /* protocol (not used) */
10145 NULL, /* service (not used) */
10146 NULL, /* username (not used) */
10147 NULL, /* password (not used) */
10148 NULL, /* command (not used) */
10149 -1,-1,-1, /* params 1-3 (not used) */
10150 1, /* connect immediately */
10152 zz, /* close current? */
10154 debug(F111,"setlin cx_net",line,x);
10157 #endif /* SSHCMD */
10160 Here we parse optional switches and then the hostname or whatever,
10161 which depends on the network type. The tricky part is, the network type
10162 can be set by a switch.
10165 makestr(&g_pswd,pwbuf); /* Save global pwbuf */
10166 g_pflg = pwflg; /* and flag */
10173 if (mynet != NET_FILE) {
10174 #endif /* NETFILE */
10175 ss = (mynet == NET_CMD || mynet == NET_PTY) ?
10176 "Command, or switch" :
10177 (mynet == NET_TCPA || mynet == NET_TCPB
10178 || mynet == NET_SSH) ?
10179 "Hostname, ip-address, or switch" :
10182 if (mynet == NET_TCPB &&
10183 (ttnproto == NP_TELNET || ttnproto == NP_KERMIT)) {
10186 cmfdbi(&sw,_CMKEY,ss,"","",nshteltab,4,xxstring,
10191 else if (mynet == NET_TCPB && ttnproto == NP_RLOGIN) {
10194 cmfdbi(&sw,_CMKEY,ss,"","",nshrlgtab,4,xxstring,
10198 #endif /* RLOGCODE */
10201 cmfdbi(&sw,_CMKEY,ss,"","",nshtab,4,xxstring,shtab,&nx);
10205 #endif /* NETFILE */
10206 if (mynet == NET_TCPB || mynet == NET_SLAT ||
10207 mynet == NET_SSH || mynet == NET_DEC) {
10208 cmfdbi(&nx,_CMFLD,"Host","","",0,0,xxstring,NULL,NULL);
10210 } else if (mynet == NET_FILE) {
10211 cmfdbi(&nx,_CMIFI,"Filename","","",0,0,xxstring,NULL,NULL);
10212 #endif /* NETFILE */
10214 } else if (mynet == NET_CMD || mynet == NET_PTY) {
10215 cmfdbi(&nx,_CMTXT,"Command","","",0,0,xxstring,NULL,NULL);
10216 #endif /* PTYORPIPE */
10218 cmfdbi(&nx,_CMTXT,"Host","","",0,0,xxstring,NULL,NULL);
10221 x = cmfdb(haveswitch ? &sw : &nx);
10222 debug(F101,"setlin cmfdb","",x);
10227 if ((x = cmcfm()) < 0) {
10234 if (cmresult.fcode != _CMKEY) { /* Not a switch */
10235 ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Save the data */
10236 s = line; /* that was parsed... */
10237 if (cmresult.fcode == _CMIFI) {
10238 wild = cmresult.nresult;
10239 } else if (cmresult.fcode == _CMTXT) {
10242 break; /* and break out of this loop */
10244 c = cmgbrk(); /* Have switch - get break character */
10245 getval = (c == ':' || c == '='); /* Must parse an agument? */
10246 if (getval && !(cmresult.kflags & CM_ARG)) {
10247 printf("?This switch does not take arguments\n");
10250 if (!getval && (cmgkwflgs() & CM_ARG)) {
10251 printf("?This switch requires an argument\n");
10254 switch (cmresult.nresult) { /* It's a switch.. */
10255 case SL_CNX: /* /CONNECT */
10259 case SL_SRV: /* /SERVER */
10264 case SL_CMD: /* /COMMAND */
10268 #endif /* NETCMD */
10270 case SL_PTY: /* /PTY */
10274 #endif /* NETPTY */
10275 case SL_NET: /* /NETWORK-TYPE */
10276 if ((x = cmkey(netcmd,nnets,"","",xxstring)) < 0)
10282 case SL_PSW: /* /PASSWORD: */
10286 if ((x = cmfld("Password","",&s,xxstring)) < 0) {
10288 makestr(&tmpstring,"");
10294 if ((x = (int)strlen(s)) > PWBUFL) {
10295 makestr(&slmsg,"Internal error");
10296 printf("?Sorry, too long - max = %d\n",PWBUFL);
10299 makestr(&tmpstring,s);
10302 #endif /* CK_SECURITY */
10304 case SL_UID: /* /USERID: */
10307 if ((x = cmfld("Userid","",&s,xxstring)) < 0) {
10309 makestr(&tmpusrid,"");
10315 if ((x = (int)strlen(s)) > 63) {
10316 makestr(&slmsg,"Internal error");
10317 printf("?Sorry, too long - max = %d\n",63);
10320 makestr(&tmpusrid,s);
10325 #ifdef CK_AUTHENTICATION
10328 a_type = AUTHTYPE_SRP;
10330 #endif /* CK_SRP */
10333 a_type = AUTHTYPE_SSL;
10335 #endif /* CK_SSL */
10338 a_type = AUTHTYPE_NTLM;
10343 a_type = AUTHTYPE_KERBEROS_V4;
10344 if (ttnproto == NP_RLOGIN)
10346 #ifdef CK_ENCRYPTION
10347 encrypt ? NP_EK4LOGIN :
10348 #endif /* CK_ENCRYPTION */
10350 else if (ttnproto == NP_K5LOGIN)
10351 ttnproto = NP_K4LOGIN;
10352 #ifdef CK_ENCRYPTION
10353 else if (ttnproto == NP_EK5LOGIN)
10354 ttnproto = NP_EK4LOGIN;
10355 #endif /* CK_ENCRYPTION */
10358 a_type = AUTHTYPE_KERBEROS_V5;
10359 if (ttnproto == NP_RLOGIN)
10361 #ifdef CK_ENCRYPTION
10362 encrypt ? NP_EK5LOGIN :
10363 #endif /* CK_ENCRYPTION */
10365 else if (ttnproto == NP_K4LOGIN)
10366 ttnproto = NP_K5LOGIN;
10367 #ifdef CK_ENCRYPTION
10368 else if (ttnproto == NP_EK4LOGIN)
10369 ttnproto = NP_EK5LOGIN;
10370 #endif /* CK_ENCRYPTION */
10372 #endif /* CK_KERBEROS */
10374 extern struct keytab autyptab[];
10376 if ((x = cmkey(autyptab,nautyp,"type of authentication",
10377 "automatic",xxstring)) < 0)
10382 #endif /* CK_AUTHENTICATION */
10383 #ifdef CK_ENCRYPTION
10385 switch (ttnproto) {
10387 ttnproto = NP_EK4LOGIN;
10391 ttnproto = NP_EK5LOGIN;
10396 static struct keytab * tnetbl = NULL;
10397 static int ntnetbl = 0;
10398 x = ck_get_crypt_table(&tnetbl,&ntnetbl);
10399 debug(F101,"ck_get_crypt_table x","",x);
10400 debug(F101,"ck_get_crypt_table n","",ntnetbl);
10401 if (x < 1 || !tnetbl || ntnetbl < 1) /* Didn't get it */
10404 makestr(&slmsg,"Internal error");
10405 printf("?Oops, types not loaded\n");
10408 if ((x = cmkey(tnetbl,ntnetbl,"type of encryption",
10409 "automatic",xxstring)) < 0)
10416 #endif /* CK_ENCRYPTION */
10427 if (mynet == NET_FILE) { /* Parsed by cmifi() */
10428 if ((x = cmcfm()) < 0) /* Needs confirmation */
10430 x = cx_net(mynet, /* nettype */
10431 0, /* protocol (not used) */
10434 NULL, /* alternate username */
10435 NULL, /* password */
10436 NULL, /* command to execute */
10440 cx, /* enter CONNECT mode */
10441 sx, /* enter SERVER mode */
10442 zz, /* close connection if open */
10446 #endif /* NETFILE */
10449 if (mynet == NET_CMD || mynet == NET_PTY) {
10452 if ((x = cmtxt("Rest of command","",&s,xxstring)) < 0)
10455 strncat(line," ",LINBUFSIZ);
10456 strncat(line,s,LINBUFSIZ);
10460 /* s == line - so we must protect the line buffer */
10463 ckstrncpy(line,p,LINBUFSIZ);
10466 x = cx_net( mynet, /* nettype */
10467 0, /* protocol (not used) */
10470 NULL, /* alternate username */
10471 NULL, /* password */
10472 NULL, /* command to execute */
10476 cx, /* enter CONNECT mode */
10477 sx, /* enter SERVER mode */
10478 zz, /* close connection if open */
10482 #endif /* NETCMD */
10484 #ifdef NPIPE /* Named pipe */
10485 if (mynet == NET_PIPE) { /* Needs backslash twiddling */
10487 if (strcmp(line,"*")) { /* If remote, begin with */
10490 ckstrncpy(line,"\\\\",LINBUFSIZ); /* server name */
10491 ckstrncat(line,p,LINBUFSIZ);
10496 ckstrncat(line,"\\pipe\\", LINBUFSIZ); /* Make pipe name */
10497 ckstrncat(line,pipename, LINBUFSIZ); /* Add name of pipe */
10499 x = cx_net(mynet, /* nettype */
10500 0, /* protocol (not used) */
10503 NULL, /* alternate username */
10504 NULL, /* password */
10505 NULL, /* command to execute */
10509 cx, /* enter CONNECT mode */
10510 sx, /* enter SERVER mode */
10511 zz, /* close connection if open */
10519 if (mynet == NET_SLAT) { /* Needs password, etc. */
10520 slat_pwd[0] = NUL; /* Erase any previous password */
10522 if (*line) { /* If they gave a host name... */
10524 "password,\n or carriage return if no password required",
10530 ckstrncpy(slat_pwd,s,18); /* Set the password, if any */
10532 if ((x = cmcfm()) < 0) return(x); /* Confirm the command */
10534 x = cx_net(mynet, /* nettype */
10535 0, /* protocol (not used) */
10538 NULL, /* alternate username */
10539 NULL, /* password */
10540 NULL, /* command to execute */
10544 cx, /* enter CONNECT mode */
10545 sx, /* enter SERVER mode */
10546 zz, /* close connection if open */
10550 #endif /* SUPERLAT */
10553 if (mynet == NET_DEC) {
10554 if (!line[0]) { /* If they gave a host name... */
10555 printf("?hostname required\n");
10558 if ((x = cmcfm()) < 0) return(x); /* Confirm the command */
10560 x = cx_net(mynet, /* nettype */
10561 0, /* protocol (not used) */
10564 NULL, /* alternate username */
10565 NULL, /* password */
10566 NULL, /* command to execute */
10570 cx, /* enter CONNECT mode */
10571 sx, /* enter SERVER mode */
10572 zz, /* close connection if open */
10576 #endif /* DECNET */
10579 if (mynet == NET_SSH) { /* SSH connection */
10580 int k, havehost = 0, trips = 0;
10581 int tmpver = -1, tmpxfw = -1, tmpssh_cas;
10583 extern int sl_ssh_xfw, sl_ssh_xfw_saved;
10584 extern int sl_ssh_ver, sl_ssh_ver_saved;
10585 #endif /* SSHTEST */
10586 extern struct keytab sshopnsw[];
10587 extern int nsshopnsw;
10588 extern char *ssh_tmpcmd, *ssh_tmpport;
10589 struct FDB sw, kw, fl;
10591 debug(F110,"setlin SSH service 0",srvbuf,0);
10592 debug(F110,"setlin SSH host s 2",s,0);
10593 if (*s) { /* If they gave a host name... */
10594 debug(F110,"setlin SSH host s 1",s,0);
10596 makestr(&slmsg,"Incoming connections not supported");
10598 "?Sorry, incoming connections not supported for SSH.\n"
10602 ckstrncpy(line,s,LINBUFSIZ);
10604 printf("?hostname required\n");
10608 /* Parse [ port ] [ switches ] */
10609 cmfdbi(&kw, /* Switches */
10611 "Port number or service name,\nor switch",
10620 cmfdbi(&fl, /* Port number or service name */
10631 trips = 0; /* Explained below */
10632 while (1) { /* Parse port and switches */
10633 y = cmfdb(&kw); /* Get a field */
10634 if (y == -3) /* User typed CR so quit from loop */
10636 if (y < 0) /* Other parse error, pass it back */
10638 switch (cmresult.fcode) { /* Field or Keyword? */
10639 case _CMFLD: /* Field */
10640 ckstrncpy(srvbuf,cmresult.sresult,SRVBUFSIZ);
10642 case _CMKEY: /* Keyword */
10643 switch (cmresult.nresult) { /* Which one? */
10646 printf("?This switch requires an argument\n");
10650 if ((y = cmfld("Password","",&s,xxstring)) < 0) {
10652 makestr(&tmpstring,"");
10658 if ((y = (int)strlen(s)) > PWBUFL) {
10659 makestr(&slmsg,"Internal error");
10660 printf("?Sorry, too long - max = %d\n",PWBUFL);
10663 makestr(&tmpstring,s);
10666 case SSHSW_USR: /* /USER: */
10668 printf("?This switch requires an argument\n");
10671 if ((y = cmfld("Username","",&s,xxstring)) < 0)
10674 makestr(&tmpusrid,s);
10677 if ((y = cmnum("Number","",10,&z,xxstring)) < 0)
10679 if (z < 1 || z > 2) {
10680 printf("?Out of range: %d\n",z);
10687 if ((y = cmfld("Text","",&s,xxstring)) < 0)
10689 makestr(&ssh_tmpcmd,s);
10690 tmpssh_cas = (cmresult.nresult == SSHSW_SUB);
10693 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0)
10701 if (trips++ == 0) { /* After first time through */
10702 cmfdbi(&kw, /* only parse switches, not port. */
10715 if ((y = cmcfm()) < 0) /* Get confirmation */
10718 debug(F110,"setlin pre-cx_net line",line,0);
10719 debug(F110,"setlin pre-cx_net srvbuf",srvbuf,0);
10720 x = cx_net( mynet, /* nettype */
10721 0, /* protocol (not used) */
10724 tmpusrid, /* alternate username */
10725 tmpstring, /* password */
10726 ssh_tmpcmd, /* command to execute */
10727 tmpver, /* param1 - ssh version */
10728 tmpssh_cas, /* param2 - ssh cas */
10729 tmpxfw, /* param3 - ssh x11fwd */
10730 cx, /* enter CONNECT mode */
10731 sx, /* enter SERVER mode */
10732 zz, /* close connection if open */
10736 makestr(&tmpusrid,NULL);
10738 makestr(&ssh_tmpcmd,NULL);
10740 #endif /* SSHBUILTIN */
10743 if (mynet == NET_TCPB) { /* TCP/IP connection */
10744 debug(F110,"setlin service 0",srvbuf,0);
10745 debug(F110,"setlin host s 2",s,0);
10746 if (*s) { /* If they gave a host name... */
10747 debug(F110,"setlin host s 1",s,0);
10750 makestr(&slmsg,"Incoming connections not supported");
10752 "?Sorry, incoming connections not supported in this version of Kermit.\n"
10756 #endif /* NOLISTEN */
10758 /* Allow a username if rlogin is requested */
10759 if (mynet == NET_TCPB &&
10760 (ttnproto == NP_RLOGIN || ttnproto == NP_K5LOGIN ||
10761 ttnproto == NP_EK5LOGIN || ttnproto == NP_K4LOGIN ||
10762 ttnproto == NP_EK4LOGIN
10766 /* Check for "host:service" */
10767 for ( ; (*s != '\0') && (*s != ':'); s++) ;
10768 if (*s) { /* Service, save it */
10770 ckstrncpy(srvbuf,++s,SRVBUFSIZ);
10771 } else { /* No :service, then use default. */
10773 switch (ttnproto) {
10775 ckstrncpy(srvbuf,"513",SRVBUFSIZ); /* "login" */
10779 ckstrncpy(srvbuf,"543",SRVBUFSIZ); /* "klogin" */
10783 ckstrncpy(srvbuf,"2105",SRVBUFSIZ); /* "eklogin" */
10787 switch (ttnproto) {
10789 ckstrncpy(srvbuf,"login",SRVBUFSIZ);
10793 ckstrncpy(srvbuf,"klogin",SRVBUFSIZ);
10797 ckstrncpy(srvbuf,"eklogin",SRVBUFSIZ);
10803 y = cmfld("Userid on remote system",
10804 uidbuf,&s,xxstring);
10805 if (y < 0 && y != -3)
10807 if ((int)strlen(s) > 63) {
10808 makestr(&slmsg,"Internal error");
10809 printf("Sorry, too long\n");
10812 makestr(&tmpusrid,s);
10814 } else { /* TELNET or SET HOST */
10815 #endif /* RLOGCODE */
10816 /* Check for "host:service" */
10817 for ( ; (*s != '\0') && (*s != ':'); s++) ;
10818 if (*s) { /* Service, save it */
10820 ckstrncpy(srvbuf,++s,SRVBUFSIZ);
10821 } else if (!confirmed) {
10822 /* No :service, let them type one. */
10823 if (*line != '*') { /* Not incoming */
10824 if (mynet == NET_TCPB && ttnproto == NP_KERMIT) {
10826 "TCP service name or number",
10827 "kermit",&s,xxstring)
10831 } else if (mynet == NET_TCPB &&
10832 ttnproto == NP_RLOGIN) {
10834 "TCP service name or number,\n or carriage return for rlogin (513)",
10835 "login",&s,xxstring)
10838 #ifdef CK_AUTHENTICATION
10840 } else if (mynet == NET_TCPB &&
10841 (ttnproto == NP_K4LOGIN ||
10842 ttnproto == NP_K5LOGIN)) {
10844 "TCP service name or number,\n or carriage return for klogin (543)",
10845 "klogin",&s,xxstring)
10848 } else if (mynet == NET_TCPB &&
10849 (ttnproto == NP_EK4LOGIN ||
10850 ttnproto == NP_EK5LOGIN)) {
10852 "TCP service name or number,\n or carriage return for eklogin (2105)",
10853 "eklogin",&s,xxstring)
10856 #endif /* CK_KERBEROS */
10857 #endif /* CK_AUTHENTICATION */
10858 #endif /* RLOGCODE */
10860 /* Do not set a default value in this call */
10861 /* If you do then it will prevent entries */
10862 /* in the network directory from accessing */
10863 /* alternate ports. */
10866 "TCP service name or number",
10871 } else { /* Incoming connection */
10872 if ((x = cmfld("TCP service name or number",
10877 if (*s) /* If they gave a service, */
10878 ckstrncpy(srvbuf,s,SRVBUFSIZ); /* copy it */
10879 debug(F110,"setlin service 0.5",srvbuf,0);
10883 #endif /* RLOGCODE */
10886 switch (ttnproto) {
10888 defproto = "/rlogin";
10891 defproto = "/k4login";
10894 defproto = "/k5login";
10897 defproto = "/ek4login";
10900 defproto = "/ek5login";
10904 defproto = "/telnet";
10907 defproto = "/default";
10909 if ((x = cmkey(tcprawtab,ntcpraw,"Switch",defproto,
10913 else if ((x = cmcfm()) < 0)
10917 if ((x = cmcfm()) < 0)
10922 debug(F110,"setlin pre-cx_net line",line,0);
10923 debug(F110,"setlin pre-cx_net srvbuf",srvbuf,0);
10924 x = cx_net( mynet, /* nettype */
10925 rawflg /* protocol */,
10928 tmpusrid, /* alternate username */
10929 tmpstring, /* password */
10930 NULL, /* command to execute */
10931 a_type, /* param1 - telnet authtype */
10932 e_type, /* param2 - telnet enctype */
10933 wait, /* param3 - telnet wait */
10934 cx, /* enter CONNECT mode */
10935 sx, /* enter SERVER mode */
10936 zz, /* close connection if open */
10940 #endif /* TCPSOCKET */
10944 makestr(&tmpstring,NULL);
10945 #endif /* CK_SECURITY */
10947 makestr(&tmpusrid,NULL);
10948 debug(F111,"setlin cx_net",line,x);
10950 #endif /* NETCONN */
10953 /* Serial tty device, possibly modem, connection... */
10958 COM1..COM8 = Regular COM port
10959 1..8 = Synonym for COM1..COM8, is translated to COM1..COM8
10960 _n = (n is a number) = open file handle
10961 string = any text string = name of some other kind of device,
10962 taken literally, as given.
10964 s = "Communication device name";
10968 cktapiBuildLineTable(&tapilinetab, &_tapilinetab, &ntapiline);
10969 if (!(tapilinetab && _tapilinetab && ntapiline > 0) &&
10970 xx == XYTAPI_LIN ) {
10971 makestr(&slmsg,"TAPI device not configured");
10972 printf("\nNo TAPI Line Devices are configured for this system\n");
10975 if (xx == XYTAPI_LIN) { /* Default (first) TAPI line */
10976 s = "tapi"; /* (whatever it is) */
10977 } else { /* Query the user */
10978 #endif /* CK_TAPI */
10980 /* Now parse optional switches and then device name */
10983 cmfdbi(&sw,_CMKEY,"Device name, or switch",
10984 "","",npsltab,4,xxstring,psltab,&fl);
10985 cmfdbi(&fl,_CMFLD,"",dftty,"",0,0,xxstring,NULL,NULL);
10988 debug(F101,"setlin cmfdb","",x);
10993 if ((x = cmcfm()) < 0) {
11000 if (cmresult.fcode == _CMFLD) {
11001 s = cmresult.sresult;
11003 } else if (cmresult.fcode == _CMKEY) {
11004 switch (cmresult.nresult) {
11005 case SL_CNX: /* /CONNECT */
11009 case SL_SRV: /* /SERVER */
11013 case SL_SHR: /* /SHARE */
11016 case SL_NSH: /* /NOSHARE */
11024 #endif /* CK_TAPI */
11026 debug(F110,"OS2 SET PORT s",s,0);
11027 y = lookup(os2devtab,s,nos2dev,&x); /* Look up in keyword table */
11028 debug(F101,"OS2 SET PORT x","",x);
11029 debug(F101,"OS2 SET PORT y","",y);
11030 if ((y > -1) && (x >= 0 && x < 8)) { /* User typed a digit 1..8 */
11031 s = os2devtab[x+8].kwd; /* Substitite its real name */
11035 xxslip = xxppp = 0;
11037 debug(F110,"OS2 SET PORT subst s",s,"");
11039 } else if ((y >-1) && (x >= 16 && x < 24)) { /* SLIP access */
11040 s = os2devtab[x-8].kwd; /* Substitite its real name */
11041 debug(F110,"OS2 SET PORT SLIP subst s",s,"");
11044 } else if ((y >-1) && (x >= 24 && x < 32)) { /* PPP access */
11045 s = os2devtab[x-16].kwd; /* Substitite its real name */
11046 debug(F110,"OS2 SET PORT PPP subst s",s,"");
11049 if ((y = cmkey(os2ppptab,
11051 "PPP driver interface",
11056 debug(F101,"OS2 SET PORT PPP INTERFACE y","",y);
11057 xxppp = (y % 10) + 1;
11059 } else if (*s == '_') { /* User used "_" prefix */
11060 s++; /* Remove it */
11061 /* Rest must be numeric */
11062 debug(F110,"OS2 SET PORT HANDLE _subst s",s,0);
11064 makestr(&slmsg,"Invalid file handle");
11065 printf("?Invalid format for file handle\n");
11071 xxslip = xxppp = 0;
11073 } else { /* A normal COMx port or a string */
11074 s = brstrip(s); /* Strip braces if any */
11077 /* Windows TAPI support - Look up in keyword table */
11078 if (tapilinetab && _tapilinetab && ntapiline > 0) {
11079 if (!ckstrcmp(s,"tapi",4,0)) {
11081 /* Find out what the lowest numbered TAPI device is */
11082 /* and use it as the default. */
11083 int j = 9999, k = -1;
11084 for (i = 0; i < ntapiline; i++) {
11085 if (tapilinetab[i].kwval < j) {
11086 j = tapilinetab[i].kwval;
11091 s = _tapilinetab[k].kwd;
11095 if ((y = cmkey(_tapilinetab,ntapiline,
11096 "TAPI device name",s,xxstring)) < 0)
11101 /* Get the non Underscored string */
11102 for (i = 0; i < ntapiline; i++ ) {
11103 if (tapilinetab[i].kwval == y) {
11104 s = tapilinetab[i].kwd;
11111 #endif /* CK_TAPI */
11113 /* not OS/2 SLIP or PPP */
11114 xxslip = xxppp = 0;
11117 ckstrncpy(tmpbuf,s,TMPBUFSIZ); /* Copy to a safe place */
11119 if ((x = cmcfm()) < 0)
11124 cmfdbi(&sw,_CMKEY,"Device name, or switch",
11125 "","",npsltab,4,xxstring,psltab,&tx);
11126 cmfdbi(&tx,_CMTXT,"",dftty,"",0,0,xxstring,NULL,NULL);
11127 while (!confirmed) {
11129 debug(F101,"setlin cmfdb","",x);
11134 if ((x = cmcfm()) < 0) {
11141 switch (cmresult.fcode) {
11143 ckstrncpy(tmpbuf,cmresult.sresult,TMPBUFSIZ);
11145 debug(F110,"setlin CMTXT",tmpbuf,0);
11148 case _CMKEY: /* Switch */
11149 debug(F101,"setlin CMKEY",tmpbuf,cmresult.nresult);
11150 switch (cmresult.nresult) {
11151 case SL_CNX: /* /CONNECT */
11155 case SL_SRV: /* /SERVER */
11160 case SL_SHR: /* /SHARE */
11163 case SL_NSH: /* /NOSHARE */
11170 debug(F101,"setlin bad cmfdb result","",cmresult.fcode);
11171 makestr(&slmsg,"Internal error");
11172 printf("?Internal parsing error\n");
11178 if ((x = cmcfm()) < 0)
11181 debug(F110,"setlin pre-cx_serial s",s,0);
11182 debug(F110,"setlin pre-cx_serial line",line,0);
11183 x = cx_serial(s,cx,sx,shr,zz,0,
11186 (xxtapi ? CX_TAPI : 0)
11188 (xxslip ? CX_SLIP : 0) | (xxppp ? CX_PPP : 0)
11194 debug(F111,"setlin cx_serial",line,x);
11197 #endif /* NOLOCAL */
11201 C-Library based file-i/o package for scripts. This should be portable to
11202 all C-Kermit versions since it uses the same APIs we have always used for
11203 processing command files. The entire channel i/o package is contained
11204 herein, apart from some keyword table entries in the main keyword table
11205 and the help text in the HELP command module.
11207 On platforms like VMS and VOS, this package handles only UNIX-style
11208 stream files. If desired, it can be replaced for those platforms by
11209 <#>ifdef'ing out this code and adding the equivalent replacement routines
11210 to the ck?fio.c module, e.g. for RMS-based file i/o in ckvfio.c.
11213 /* Define NOSTAT if the <#>include causes trouble. */
11217 #ifdef VAXC /* As it does in VAX C */
11221 #endif /* NOSTAT */
11224 #include <sys/stat.h>
11225 #endif /* NOSTAT */
11228 static int z_lt = 1; /* Length of line terminator */
11230 static int z_lt = 2;
11231 #endif /* NLCHAR */
11233 struct ckz_file { /* C-Kermit file struct */
11234 FILE * z_fp; /* Includes the C-Lib file struct */
11235 unsigned int z_flags; /* Plus C-Kermit mode flags, */
11236 long z_nline; /* current line number if known, */
11237 char z_name[CKMAXPATH+2]; /* and the file's name. */
11239 static struct ckz_file * z_file = NULL; /* Array of C-Kermit file structs */
11240 static int z_inited = 0; /* Flag for array initialized */
11241 int z_maxchan = Z_MAXCHAN; /* Max number of C-Kermit channels */
11242 int z_openmax = CKMAXOPEN; /* Max number of open files overall */
11243 int z_nopen = 0; /* How many channels presently open */
11244 int z_error = 0; /* Most recent error */
11245 int z_filcount = -1; /* Most recent FILE COUNT result */
11247 #define RD_LINE 0 /* FILE READ options */
11250 #define RD_TRIM 8 /* Like Snobol &TRIM = 1 */
11251 #define RD_UNTA 9 /* Untabify */
11253 #define WR_LINE RD_LINE /* FILE WRITE options */
11254 #define WR_CHAR RD_CHAR
11255 #define WR_SIZE RD_SIZE
11261 extern int ckmaxfiles; /* Filled in by sysinit(). */
11264 /* See ckcker.h for error numbers */
11265 /* See ckcdeb.h for Z_MAXCHAN and CKMAXOPEN definitions */
11266 /* NOTE: For VMS we might be able to fill in ckmaxfiles */
11267 /* from FILLM and CHANNELCNT -- find out about these... */
11269 static char * fopnargs[] = { /* Mode combinations for fopen() */
11271 /* All combinations of rwa */
11272 "", "r", "w", "rw", "a", "ra", "wa", "rwa", /* Text mode */
11273 "b", "rb", "wb", "rwb", "ab", "rab", "wab", "rwab" /* Binary mode */
11275 /* Combinations and syntax permitted by C libraries... */
11276 "", "r", "w", "r+", "a", "", "a", "", /* Text mode */
11278 "", "rb", "wb", "r+b", "ab", "", "ab", "" /* Binary modes for K95 */
11281 "", "rb", "wb", "r+b", "ab", "", "ab", "" /* Binary modes for VMS */
11283 "", "r", "w", "r+", "a", "", "a", "" /* Binary modes for UNIX */
11286 #endif /* COMMENT */
11288 static int nfopnargs = sizeof(fopnargs) / sizeof(char *);
11290 char * /* Error messages */
11291 ckferror(n) int n; {
11293 case FX_NER: return("No error");
11294 case FX_SYS: return(ck_errstr());
11295 case FX_EOF: return("End of file");
11296 case FX_NOP: return("File not open");
11297 case FX_CHN: return("Channel out of range");
11298 case FX_RNG: return("Parameter out of range");
11299 case FX_NMF: return("Too many files open");
11300 case FX_FOP: return("Operation conflicts with OPEN mode");
11301 case FX_NYI: return("OPEN mode not supported");
11302 case FX_BOM: return("Illegal combination of OPEN modes");
11303 case FX_ACC: return("Access denied");
11304 case FX_FNF: return("File not found");
11305 case FX_OFL: return("Buffer overflow");
11306 case FX_LNU: return("Current line number unknown");
11307 case FX_ROO: return("Off limits");
11308 case FX_UNK: return("Operation fails - reason unknown");
11309 default: return("Error number out of range");
11314 Z _ O P E N -- Open a file for the requested type of access.
11317 name: Name of file to be opened.
11318 flags: Any combination of FM_xxx values except FM_EOF (ckcker.h).
11320 >= 0 on success: The assigned channel number
11321 < 0 on failure: A negative FX_xxx error code (ckcker.h).
11324 z_open(name, flags) char * name; int flags; {
11328 debug(F111,"z_open",name,flags);
11329 if (!name) name = ""; /* Check name argument */
11331 return(z_error = FX_BFN);
11332 if (flags & FM_CMD) /* Opening pipes not implemented yet */
11333 return(z_error = FX_NYI); /* (and not portable either) */
11334 debug(F101,"z_open nfopnargs","",nfopnargs);
11335 if (flags < 0 || flags >= nfopnargs) /* Range check flags */
11336 return(z_error = FX_RNG);
11337 mode = fopnargs[flags]; /* Get fopen() arg */
11338 debug(F111,"z_open fopen args",mode,flags);
11339 if (!mode[0]) /* Check for illegal combinations */
11340 return(z_error = FX_BOM);
11341 if (!z_inited) { /* If file structs not inited */
11342 debug(F101,"z_open z_maxchan 1","",z_maxchan);
11344 debug(F101,"z_open ckmaxfiles","",ckmaxfiles);
11345 if (ckmaxfiles > 0) { /* Set in ck?tio.c: sysinit() */
11347 x = ckmaxfiles - ZNFILS - 5;
11348 if (x > z_maxchan) /* sysconf() value greater than */
11349 z_maxchan = x; /* value from header files. */
11350 debug(F101,"z_open z_maxchan 2","",z_maxchan);
11353 if (z_maxchan < Z_MINCHAN) /* Allocate at least this many. */
11354 z_maxchan = Z_MINCHAN;
11355 debug(F101,"z_open z_maxchan 3","",z_maxchan);
11356 /* Note: This could be a pretty big chunk of memory */
11357 /* if z_maxchan is a big number. If this becomes a problem */
11358 /* we'll need to malloc and free each element at open/close time */
11359 if (!(z_file = (struct ckz_file *)
11360 malloc(sizeof(struct ckz_file) * (z_maxchan + 1))))
11361 return(z_error = FX_NMF);
11362 for (i = 0; i < z_maxchan; i++) {
11363 z_file[i].z_fp = NULL;
11364 z_file[i].z_flags = 0;
11365 z_file[i].z_nline = 0;
11366 *(z_file[i].z_name) = '\0';
11368 z_inited = 1; /* Remember we did */
11370 for (n = -1, i = 0; i < z_maxchan; i++) {
11371 if (!z_file[i].z_fp) {
11376 if (n < 0 || n >= z_maxchan) /* Any free channels? */
11377 return(z_error = FX_NMF); /* No, fail. */
11380 z_file[n].z_flags = 0; /* In case of failure... */
11382 t = fopen(name, mode); /* Try to open the file. */
11383 if (!t) { /* Failed... */
11384 debug(F111,"z_open error",name,errno);
11386 if (errno == EMFILE)
11387 return(z_error = FX_NMF);
11388 #endif /* EMFILE */
11389 return(z_error = (errno ? FX_SYS : FX_UNK)); /* Return error code */
11392 #ifdef O_SEQUENTIAL
11393 if (t) /* Caching hint for NT */
11394 _setmode(_fileno(t),O_SEQUENTIAL);
11395 #endif /* O_SEQUENTIAL */
11397 z_nopen++; /* Open, count it. */
11398 z_file[n].z_fp = t; /* Stash the file pointer */
11399 z_file[n].z_flags = flags; /* and the flags */
11401 zfnqfp(name,CKMAXPATH,z_file[n].z_name); /* and the file's full name */
11402 return(n); /* Return the channel number */
11406 z_close(channel) int channel; { /* Close file on given channel */
11409 if (!z_inited) /* Called before any files are open? */
11410 return(z_error = FX_NOP);
11411 if (channel >= z_maxchan) /* Channel out of range? */
11412 return(z_error = FX_CHN);
11413 if (!(t = z_file[channel].z_fp)) /* Channel wasn't open? */
11414 return(z_error = FX_NOP);
11415 errno = 0; /* Set errno 0 to get a good reading */
11416 x = fclose(t); /* Try to close */
11417 if (x == EOF) /* On failure */
11418 return(z_error = FX_SYS); /* indicate system error. */
11419 z_nopen--; /* Closed OK, decrement open count */
11420 z_file[channel].z_fp = NULL; /* Set file pointer to NULL */
11421 z_file[channel].z_nline = 0; /* Current line number is 0 */
11422 z_file[channel].z_flags = 0; /* Set flags to 0 */
11423 *(z_file[channel].z_name) = '\0'; /* Clear name */
11424 return(z_error = 0);
11428 Z _ O U T -- Output string to channel.
11431 channel: Channel number to write to.
11432 s: String to write.
11433 length > -1: How many characters of s to write.
11434 length < 0: Write entire NUL-terminated string.
11435 flags == 0: Supply line termination.
11436 flags > 0: Don't supply line termination.
11437 flags < 0: Write 'length' NUL characters.
11439 If flags > -1 and s is empty or NULL and length == 1, write 1 NUL.
11441 Number of characters written to channel on success, or
11442 negative FX_xxx error code on failure.
11445 z_out(channel,s,length,flags) int channel, flags, length; char * s; {
11450 if (!s) s = ""; /* Guard against null pointer */
11453 debug(F111,"z_out",s,channel);
11454 debug(F101,"z_out length","",length);
11455 debug(F101,"z_out flags","",flags);
11458 if (!z_inited) /* File i/o inited? */
11459 return(z_error = FX_NOP);
11460 if (channel >= z_maxchan) /* Channel in range? */
11461 return(z_error = FX_CHN);
11462 if (!(t = z_file[channel].z_fp)) /* File open? */
11463 return(z_error = FX_NOP);
11464 if (!((z_file[channel].z_flags) & (FM_WRI|FM_APP))) /* In write mode? */
11465 return(z_error = FX_FOP);
11466 n = length; /* Length of string to write */
11467 if (n < 0) { /* Negative means get it ourselves */
11468 if (flags < 0) /* Except when told to write NULs in */
11469 return(z_error = FX_RNG); /* which case args are inconsistent */
11470 n = strlen(s); /* Get length of string arg */
11472 errno = 0; /* Reset errno */
11473 debug(F101,"z_out n","",n);
11474 if (flags < 0) { /* Writing NULs... */
11476 for (i = 0; i < n; i++) {
11477 x = fwrite(&c,1,1,t);
11479 return(z_error = (errno ? FX_SYS : FX_UNK));
11481 z_file[channel].z_nline = -1; /* Current line no longer known */
11484 } else { /* Writing string arg */
11485 if (n == 1 && !s[0]) /* Writing one char but it's NUL */
11486 x = fwrite(&c,1,1,t);
11487 else /* Writing non-NUL char or string */
11488 x = fwrite(s,1,n,t);
11489 debug(F101,"z_out fwrite",ckitoa(x),errno);
11490 if (x < n) /* Failure to write requested amount */
11491 return(z_error = (errno ? FX_SYS : FX_UNK)); /* Return error */
11492 if (flags == 0) { /* If supplying line termination */
11493 if (fwrite("\n",1,1,t)) /* do that */
11494 x += z_lt; /* count the terminator */
11495 if (z_file[channel].z_nline > -1) /* count this line */
11496 z_file[channel].z_nline++;
11498 z_file[channel].z_nline = -1; /* Current line no longer known */
11505 #define Z_INBUFLEN 64
11508 Z _ I N -- Multichannel i/o file input function.
11511 channel number to read from.
11512 s = address of destination buffer.
11513 buflen = destination buffer length.
11514 length = Number of bytes to read, must be < buflen.
11515 flags: 0 = read a line; nonzero = read the given number of bytes.
11517 Number of bytes read into buffer or a negative error code.
11518 A terminating NUL is deposited after the last byte that was read.
11521 z_in(channel,s,buflen,length,flags)
11522 int channel, buflen, length, flags; char * s;
11528 if (!z_inited) /* Check everything... */
11529 return(z_error = FX_NOP);
11530 if (channel >= z_maxchan)
11531 return(z_error = FX_CHN);
11532 if (!(t = z_file[channel].z_fp))
11533 return(z_error = FX_NOP);
11534 if (!((z_file[channel].z_flags) & FM_REA))
11535 return(z_error = FX_FOP);
11536 if (!s) /* Check destination */
11537 return(z_error = FX_RNG);
11539 if (length == 0) /* Read 0 bytes - easy. */
11540 return(z_error = 0);
11541 debug(F101,"z_in channel","",channel);
11542 debug(F101,"z_in buflen","",buflen);
11543 debug(F101,"z_in length","",length);
11544 debug(F101,"z_in flags","",flags);
11545 if (length < 0 || buflen < 0) /* Check length args */
11546 return(z_error = FX_RNG);
11547 if (buflen <= length)
11548 return(z_error = FX_RNG);
11549 errno = 0; /* Reset errno */
11550 if (flags) { /* Read block or byte */
11551 i = fread(s,1,length,t);
11554 debug(F111,"z_in block",s,i);
11555 debug(F101,"z_in block errno","",errno);
11556 debug(F101,"z_in block ferror","",ferror(t));
11557 debug(F101,"z_in block feof","",feof(t));
11560 z_file[channel].z_nline = -1; /* Current line no longer known */
11561 } else { /* Read line */
11563 /* This method is used because it's simpler than the others */
11564 /* and also marginally faster. */
11565 debug(F101,"z_in getc loop","",ftell(t));
11566 for (i = 0; i < length; i++) {
11567 if ((x = getc(t)) == EOF) {
11568 debug(F101,"z_in getc error","",ftell(t));
11573 if (s[i] == '\n') {
11578 debug(F111,"z_in line byte loop",ckitoa(errno),i);
11579 debug(F111,"z_in line got",s,z_file[channel].z_nline);
11580 if (z_file[channel].z_nline > -1)
11581 z_file[channel].z_nline++;
11584 /* Straightforward but strlen() slows it down. */
11587 if (fgets(s,length,t)) {
11589 if (i > 0 && s[i-1] == '\n') i--;
11591 debug(F111,"z_in line fgets",ckitoa(errno),i);
11592 if (z_file[channel].z_nline > -1)
11593 z_file[channel].z_nline++;
11595 /* This is a do-it-yourself fgets() with its own readahead and */
11596 /* putback. It's a bit faster than real fgets() but not enough */
11597 /* to justify the added complexity or the risk of the ftell() and */
11598 /* fseek() calls failing. */
11601 for (i = 0; !flag && i <= (length - Z_INBUFLEN); i += Z_INBUFLEN) {
11602 k = ((length - i) < Z_INBUFLEN) ? length - i : Z_INBUFLEN;
11603 if ((x = fread(s+i,1,k,t)) < 1)
11606 for (j = 0; j < x; j++) {
11607 if (s[i+j] == '\n') {
11612 pos -= (x - j - 1);
11613 x = fseek(t, pos, 0);
11617 return(z_error = FX_SYS);
11621 if (z_file[channel].z_nline > -1)
11622 z_file[channel].z_nline++;
11623 debug(F111,"z_in line chunk loop",ckitoa(errno),i);
11624 #endif /* COMMENT2 */
11625 #endif /* COMMENT */
11627 debug(F111,"z_in i",ckitoa(errno),i);
11628 if (i < 0) i = 0; /* NUL-terminate result */
11634 if (i == 0 && feof(t)) /* EOF on reading? */
11635 return(z_error = FX_EOF); /* Return EOF code */
11636 return(errno ? (z_error = -1) : i); /* Return length or system error */
11640 z_flush(channel) int channel; { /* Flush output channel */
11643 if (!z_inited) /* Regular checks */
11644 return(z_error = FX_NOP);
11645 if (channel >= z_maxchan)
11646 return(z_error = FX_CHN);
11647 if (!(t = z_file[channel].z_fp))
11648 return(z_error = FX_NOP);
11649 if (!((z_file[channel].z_flags) & (FM_WRI|FM_APP))) /* Write access? */
11650 return(z_error = FX_FOP);
11651 errno = 0; /* Reset errno */
11652 x = fflush(t); /* Try to flush */
11653 return(x ? (z_error = FX_SYS) : 0); /* Return system error or 0 if OK */
11658 z_seek(int channel, long pos) /* Move file pointer to byte */
11660 z_seek(channel,pos) int channel; long pos; /* (seek to given position) */
11661 #endif /* CK_ANSIC */
11665 if (!z_inited) /* Check... */
11666 return(z_error = FX_NOP);
11667 if (channel >= z_maxchan)
11668 return(z_error = FX_CHN);
11669 if (!(t = z_file[channel].z_fp))
11670 return(z_error = FX_NOP);
11673 pos = (pos == -2) ? -1L : 0L;
11676 rc = fseek(t,pos,x); /* Try to seek */
11677 debug(F111,"z_seek",ckitoa(errno),rc);
11678 if (rc < 0) /* OK? */
11679 return(z_error = FX_SYS); /* No. */
11680 z_file[channel].z_nline = ((pos || x) ? -1 : 0);
11681 return(z_error = 0);
11686 z_line(int channel, long pos) /* Move file pointer to line */
11688 z_line(channel,pos) int channel; long pos; /* (seek to given position) */
11689 #endif /* CK_ANSIC */
11692 long current = 0L, prev = -1L, old = -1L;
11695 if (!z_inited) /* Check... */
11696 return(z_error = FX_NOP);
11697 if (channel >= z_maxchan)
11698 return(z_error = FX_CHN);
11699 if (!(t = z_file[channel].z_fp))
11700 return(z_error = FX_NOP);
11701 debug(F101,"z_line pos","",pos);
11702 if (pos < 0L) { /* EOF wanted */
11704 n = z_file[channel].z_nline;
11705 debug(F101,"z_line n","",n);
11706 if (n < 0 || pos < 0) {
11710 while (1) { /* This could take a while... */
11711 if ((x = getc(t)) == EOF)
11721 debug(F101,"z_line old","",old);
11722 debug(F101,"z_line prev","",prev);
11724 if ((x = z_seek(channel,old)) < 0)
11725 return(z_error = x);
11729 z_file[channel].z_nline = n;
11730 return(z_error = 0);
11732 if (pos == 0L) { /* Rewind wanted */
11733 z_file[channel].z_nline = 0L;
11735 debug(F100,"z_line rewind","",0);
11738 tmpbuf[255] = NUL; /* Make sure buf is NUL terminated */
11739 current = z_file[channel].z_nline; /* Current line */
11741 If necessary the following could be optimized, e.g. for positioning
11742 to a previous line in a large file without starting over.
11744 if (current < 0 || pos < current) { /* Not known or behind us... */
11745 debug(F101,"z_line rewinding","",pos);
11746 if ((x = z_seek(channel, 0L)) < 0) /* Rewind */
11747 return(z_error = x);
11748 if (pos == 0) /* If 0th line wanted we're done */
11749 return(z_error = 0);
11752 while (current < pos) { /* Search for specified line */
11753 if (fgets(tmpbuf,255,t)) {
11754 len = strlen(tmpbuf);
11755 if (len > 0 && tmpbuf[len-1] == '\n') {
11757 debug(F111,"z_line read",ckitoa(len),current);
11758 } else if (len == 0) {
11759 return(z_error = FX_UNK);
11762 z_file[channel].z_nline = -1L;
11763 debug(F101,"z_line premature EOF","",current);
11764 return(z_error = FX_EOF);
11767 z_file[channel].z_nline = current;
11768 debug(F101,"z_line result","",current);
11774 z_getname(channel) int channel; { /* Return name of file on channel */
11780 if (channel >= z_maxchan) {
11784 if (!(t = z_file[channel].z_fp)) {
11788 return((char *)(z_file[channel].z_name));
11792 z_getmode(channel) int channel; { /* Return OPEN modes of channel */
11793 FILE * t; /* 0 if file not open */
11796 struct _stat statbuf;
11798 struct stat statbuf;
11800 #endif /* NOSTAT */
11804 if (channel >= z_maxchan)
11805 return(z_error = FX_CHN);
11806 if (!(t = z_file[channel].z_fp))
11808 x = z_file[channel].z_flags;
11809 if (feof(t)) { /* This might not work for */
11810 x |= FM_EOF; /* output files */
11812 /* But this does if we can use it. */
11813 } else if (stat(z_file[channel].z_name,&statbuf) > -1) {
11814 if (ftell(t) == statbuf.st_size)
11816 #endif /* NOSTAT */
11822 z_getpos(channel) int channel; { /* Get file pointer position */
11823 FILE * t; /* on this channel */
11826 return(z_error = FX_NOP);
11827 if (channel >= z_maxchan)
11828 return(z_error = FX_CHN);
11829 if (!(t = z_file[channel].z_fp))
11830 return(z_error = FX_NOP);
11832 return((x < 0L) ? (z_error = FX_SYS) : x);
11836 z_getline(channel) int channel; { /* Get current line number */
11837 FILE * t; /* in file on this channel */
11840 return(z_error = FX_NOP);
11841 if (channel >= z_maxchan)
11842 return(z_error = FX_CHN);
11843 if (!(t = z_file[channel].z_fp))
11844 return(z_error = FX_NOP);
11845 debug(F101,"z_getline","",z_file[channel].z_nline);
11846 rc = z_file[channel].z_nline;
11847 return((rc < 0) ? (z_error = FX_LNU) : rc);
11851 z_getfnum(channel) int channel; { /* Get file number / handle */
11852 FILE * t; /* for file on this channel */
11854 return(z_error = FX_NOP);
11855 if (channel >= z_maxchan)
11856 return(z_error = FX_CHN);
11857 if (!(t = z_file[channel].z_fp))
11858 return(z_error = FX_NOP);
11864 Line-oriented counts and seeks are as dumb as they can be at the moment.
11865 Later we can speed them up by building little indexes.
11868 z_count(channel, what) int channel, what; { /* Count bytes or lines in file */
11871 long pos, count = 0L;
11872 if (!z_inited) /* Check stuff... */
11873 return(z_error = FX_NOP);
11874 if (channel >= z_maxchan)
11875 return(z_error = FX_CHN);
11876 if (!(t = z_file[channel].z_fp))
11877 return(z_error = FX_NOP);
11878 pos = ftell(t); /* Save current file pointer */
11881 if (what == RD_CHAR) { /* Size in bytes requested */
11882 if (!fseek(t,0L,2)) { /* Seek to end */
11883 count = ftell(t); /* Get file pointer */
11884 fseek(t,pos,0); /* Restore file file pointer */
11886 } else /* Fallback in case seek fails */
11887 return(zgetfs(z_file[channel].z_name));
11889 rewind(t); /* Line count requested - rewind. */
11890 while (1) { /* Count lines. */
11891 if ((x = getc(t)) == EOF) /* Stupid byte loop */
11892 break; /* but it works as well as anything */
11893 if (x == '\n') /* else... */
11896 x = fseek(t,pos,0); /* Restore file pointer */
11900 /* User interface for generalized channel-oriented file i/o */
11902 struct keytab fctab[] = { /* FILE subcommands */
11903 { "close", FIL_CLS, 0 },
11904 { "count", FIL_COU, 0 },
11905 { "flush", FIL_FLU, 0 },
11906 { "list", FIL_LIS, 0 },
11907 { "open", FIL_OPN, 0 },
11908 { "read", FIL_REA, 0 },
11909 { "rewind", FIL_REW, 0 },
11910 { "seek", FIL_SEE, 0 },
11911 { "status", FIL_STA, 0 },
11912 { "write", FIL_WRI, 0 }
11914 int nfctab = (sizeof (fctab) / sizeof (struct keytab));
11916 static struct keytab fcswtab[] = { /* OPEN modes */
11917 { "/append", FM_APP, 0 },
11918 { "/binary", FM_BIN, 0 },
11920 { "/command", FM_CMD, 0 }, /* Not implemented */
11921 #endif /* COMMENT */
11922 { "/read", FM_REA, 0 },
11923 { "/write", FM_WRI, 0 }
11925 static int nfcswtab = (sizeof (fcswtab) / sizeof (struct keytab));
11927 static struct keytab fclkwtab[] = { /* CLOSE options */
11931 static struct keytab fsekwtab[] = { /* SEEK symbols */
11935 static int nfsekwtab = (sizeof (fsekwtab) / sizeof (struct keytab));
11937 #define SEE_LINE RD_LINE /* SEEK options */
11938 #define SEE_CHAR RD_CHAR
11942 static struct keytab fskswtab[] = {
11943 { "/absolute", SEE_ABS, 0 },
11944 { "/byte", SEE_CHAR, 0 },
11945 { "/character", SEE_CHAR, CM_INV },
11946 { "/line", SEE_LINE, 0 },
11947 { "/relative", SEE_REL, 0 }
11949 static int nfskswtab = (sizeof (fskswtab) / sizeof (struct keytab));
11951 #define COU_LINE RD_LINE /* COUNT options */
11952 #define COU_CHAR RD_CHAR
11956 static struct keytab fcoswtab[] = {
11957 { "/bytes", COU_CHAR, 0 },
11958 { "/characters",COU_CHAR, CM_INV },
11959 { "/lines", COU_LINE, 0 },
11960 { "/list", COU_LIS, 0 },
11961 { "/nolist", COU_NOL, 0 },
11962 { "/quiet", COU_NOL, CM_INV }
11964 static int nfcoswtab = (sizeof (fcoswtab) / sizeof (struct keytab));
11966 static struct keytab frdtab[] = { /* READ types */
11967 { "/block", RD_SIZE, CM_INV|CM_ARG },
11968 { "/byte", RD_CHAR, CM_INV },
11969 { "/character", RD_CHAR, 0 },
11970 { "/line", RD_LINE, 0 },
11971 { "/size", RD_SIZE, CM_ARG },
11972 { "/trim", RD_TRIM, 0 },
11973 { "/untabify", RD_UNTA, 0 }
11975 static int nfrdtab = (sizeof (frdtab) / sizeof (struct keytab));
11977 static struct keytab fwrtab[] = { /* WRITE types */
11978 { "/block", WR_SIZE, CM_INV|CM_ARG },
11979 { "/byte", WR_CHAR, CM_INV },
11980 { "/character", WR_CHAR, 0 },
11981 { "/line", WR_LINE, 0 },
11982 { "/lpad", WR_LPAD, CM_ARG },
11983 { "/rpad", WR_RPAD, CM_ARG },
11984 { "/size", WR_SIZE, CM_ARG },
11985 { "/string", WR_STRI, 0 }
11987 static int nfwrtab = (sizeof (fwrtab) / sizeof (struct keytab));
11989 static char blanks[] = "\040\040\040\040"; /* Some blanks for formatting */
11992 dofile(op) int op; { /* Do the FILE command */
11993 char vnambuf[VNAML]; /* Buffer for variable names */
11994 char *vnp = NULL; /* Pointer to same */
11995 char zfilnam[CKMAXPATH+2];
11997 struct FDB fl, sw, nu;
11999 int rsize, filmode = 0, relative = -1, eofflg = 0;
12000 int rc, x, y, cx, n, getval, dummy, confirmed, listing = -1;
12001 int charflag = 0, sizeflag = 0;
12002 int pad = 32, wr_lpad = 0, wr_rpad = 0, rd_trim = 0, rd_untab = 0;
12004 if (op == XXFILE) { /* FILE command was given */
12005 /* Get subcommand */
12006 if ((cx = cmkey(fctab,nfctab,"Operation","",xxstring)) < 0) {
12008 printf("?File operation required\n");
12013 } else { /* Shorthand command was given */
12015 case XXF_CL: cx = FIL_CLS; break; /* FCLOSE */
12016 case XXF_FL: cx = FIL_FLU; break; /* FFLUSH */
12017 case XXF_LI: cx = FIL_LIS; break; /* FLIST */
12018 case XXF_OP: cx = FIL_OPN; break; /* etc... */
12019 case XXF_RE: cx = FIL_REA; break;
12020 case XXF_RW: cx = FIL_REW; break;
12021 case XXF_SE: cx = FIL_SEE; break;
12022 case XXF_ST: cx = FIL_STA; break;
12023 case XXF_WR: cx = FIL_WRI; break;
12024 case XXF_CO: cx = FIL_COU; break;
12025 default: return(-2);
12028 switch (cx) { /* Do requested subcommand */
12029 case FIL_OPN: /* OPEN */
12030 cmfdbi(&sw, /* Switches */
12031 _CMKEY, /* fcode */
12032 "Variable or switch", /* hlpmsg */
12034 "", /* addtl string data */
12035 nfcswtab, /* addtl numeric data 1: tbl size */
12036 4, /* addtl numeric data 2: 4 = cmswi */
12037 xxstring, /* Processing function */
12038 fcswtab, /* Keyword table */
12039 &fl /* Pointer to next FDB */
12041 cmfdbi(&fl, /* Anything that doesn't match */
12042 _CMFLD, /* fcode */
12043 "Variable", /* hlpmsg */
12053 x = cmfdb(&sw); /* Parse something */
12056 printf("?Variable name and file name required\n");
12061 if (cmresult.fcode == _CMFLD)
12063 else if (cmresult.fcode == _CMKEY) {
12067 (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
12068 printf("?This switch does not take an argument\n");
12072 /* Uncomment if we add any switches ere that take args */
12073 if (!getval && (cmgkwflgs() & CM_ARG)) {
12074 printf("?This switch requires an argument\n");
12075 return(-9); /* (none do...) */
12077 #endif /* COMMENT */
12078 filmode |= cmresult.nresult; /* OR in the file mode */
12082 /* Not a switch - get the string */
12083 ckstrncpy(vnambuf,cmresult.sresult,VNAML);
12084 if (!vnambuf[0] || chknum(vnambuf)) { /* (if there is one...) */
12085 printf("?Variable name required\n");
12088 vnp = vnambuf; /* Check variable-name syntax */
12089 if (vnambuf[0] == CMDQ &&
12090 (vnambuf[1] == '%' || vnambuf[1] == '&'))
12093 if (*vnp == '%' || *vnp == '&') {
12094 if ((y = parsevar(vnp,&x,&dummy)) < 0) {
12095 printf("?Syntax error in variable name\n");
12099 if (!(filmode & FM_RWA)) /* If no access mode specified */
12100 filmode |= FM_REA; /* default to /READ. */
12102 y = 0; /* Now parse the filename */
12103 if ((filmode & FM_RWA) == FM_WRI)
12104 x = cmofi("Name of new file","",&s,xxstring);
12105 else if ((filmode & FM_RWA) == FM_REA)
12106 x = cmifi("Name of existing file","",&s,&y,xxstring);
12108 x = cmiofi("Filename","",&s,&y,xxstring);
12109 debug(F101,"fopen /append x","",x);
12112 if (zchko(s) < 0) {
12113 printf("Can't create \"%s\"\n",s);
12116 } else if (x < 0) {
12118 printf("?Filename required\n");
12123 if (y) { /* No wildcards */
12124 printf("?Wildcards not allowed here\n");
12127 if (filmode & (FM_APP|FM_WRI)) { /* Check output access */
12129 if (zchko(s) < 0) { /* and set error code if denied */
12131 printf("?Write access denied - \"%s\"\n",s);
12136 ckstrncpy(zfilnam,s,CKMAXPATH); /* Is OK - make safe copy */
12137 if ((x = cmcfm()) < 0) /* Get confirmation of command */
12139 if ((n = z_open(zfilnam,filmode)) < 0) {
12140 printf("?OPEN failed - %s: %s\n",zfilnam,ckferror(n));
12143 addmac(vnambuf,ckitoa(n)); /* Assign channel number to variable */
12144 return(success = 1);
12146 case FIL_REW: /* REWIND */
12147 if ((x = cmnum("Channel number","",10,&n, xxstring)) < 0) {
12149 printf("?Channel number required\n");
12154 if ((x = cmcfm()) < 0)
12156 if ((rc = z_seek(n,0L)) < 0) {
12157 printf("?REWIND failed - Channel %d: %s\n",n,ckferror(rc));
12160 return(success = 1);
12162 case FIL_CLS: /* CLOSE */
12163 cmfdbi(&sw, /* Second FDB - switches */
12164 _CMKEY, /* fcode */
12165 "Channel number; or keyword",
12167 "", /* addtl string data */
12168 1, /* addtl numeric data 1: tbl size */
12169 0, /* addtl numeric data 2: 4 = cmswi */
12170 xxstring, /* Processing function */
12171 fclkwtab, /* Keyword table */
12172 &nu /* Pointer to next FDB */
12174 cmfdbi(&nu, /* First FDB - command switches */
12175 _CMNUM, /* fcode */
12178 "", /* addtl string data */
12179 10, /* addtl numeric data 1: radix */
12180 0, /* addtl numeric data 2: 0 */
12181 xxstring, /* Processing function */
12182 NULL, /* Keyword table */
12183 NULL /* Pointer to next FDB */
12185 x = cmfdb(&sw); /* Parse something */
12188 printf("?Channel number or ALL required\n");
12193 if (cmresult.fcode == _CMNUM)
12194 n = cmresult.nresult;
12195 else if (cmresult.fcode == _CMKEY)
12197 if ((x = cmcfm()) < 0)
12203 for (i = 0; i < z_maxchan; i++) {
12206 printf("?CLOSE failed - Channel %d: %s\n",n,ckferror(x));
12211 debug(F101,"FILE CLOSE ALL","",count);
12212 } else if ((x = z_close(n)) < 0) {
12213 printf("?CLOSE failed - Channel %d: %s\n",n,ckferror(x));
12216 return(success = rc);
12218 case FIL_REA: /* READ */
12219 case FIL_WRI: /* WRITE */
12221 cmfdbi(&sw, /* Switches */
12222 _CMKEY, /* fcode */
12223 "Channel or switch", /* hlpmsg */
12225 "", /* addtl string data */
12226 (cx == FIL_REA) ? nfrdtab : nfwrtab,
12227 4, /* addtl numeric data 2: 4 = cmswi */
12228 xxstring, /* Processing function */
12229 (cx == FIL_REA) ? frdtab : fwrtab, /* Keyword table */
12230 &nu /* Pointer to next FDB */
12232 cmfdbi(&nu, /* Channel number */
12233 _CMNUM, /* fcode */
12236 "", /* addtl string data */
12237 10, /* addtl numeric data 1: radix */
12238 0, /* addtl numeric data 2: 0 */
12239 xxstring, /* Processing function */
12240 NULL, /* Keyword table */
12241 NULL /* Pointer to next FDB */
12244 x = cmfdb(&sw); /* Parse something */
12247 printf("?Channel number required\n");
12252 if (cmresult.fcode == _CMNUM) /* Channel number */
12254 else if (cmresult.fcode == _CMKEY) { /* Switch */
12258 (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
12259 printf("?This switch does not take an argument\n");
12262 if (!getval && (cmgkwflgs() & CM_ARG)) {
12263 printf("?This switch requires an argument\n");
12266 switch (cmresult.nresult) {
12278 if ((x = cmnum("Bytes","",10,&rsize, xxstring)) < 0) {
12280 printf("?Number required\n");
12295 if ((x = cmnum("Numeric ASCII character value",
12296 "32",10,&pad, xxstring)) < 0)
12298 if (cmresult.nresult == WR_LPAD)
12310 debug(F101,"FILE READ rsize 2","",rsize);
12314 (cmresult.fcode == _CMKEY);
12316 n = cmresult.nresult; /* Channel */
12317 debug(F101,"FILE READ/WRITE channel","",n);
12319 if (cx == FIL_WRI) { /* WRITE */
12321 if ((x = cmtxt("Text","",&s,xxstring)) < 0)
12323 ckstrncpy(line,s,LINBUFSIZ); /* Make a safe copy */
12325 s = brstrip(s); /* Strip braces */
12326 if (charflag) { /* Write one char */
12327 len = 1; /* So length = 1 */
12328 rsize = 1; /* Don't supply terminator */
12329 } else if (!sizeflag) { /* Write a string */
12330 len = -1; /* So length is unspecified */
12331 } else { /* Write a block of given size */
12333 if (rsize > TMPBUFSIZ) {
12335 printf("?Buffer overflow\n");
12338 len = rsize; /* rsize is really length */
12339 rsize = 1; /* Don't supply a terminator */
12340 xx = strlen(s); /* Size of given string */
12341 if (xx >= len) { /* Bigger or equal */
12343 } else if (wr_lpad) { /* Smaller, left-padding requested */
12344 for (i = 0; i < len - xx; i++) /* Must make a copy */
12346 ckstrncpy(tmpbuf+i,s,TMPBUFSIZ-i);
12348 s = tmpbuf; /* Redirect write source */
12349 } else if (wr_rpad) { /* Smaller with right-padding */
12350 for (i = xx; i < len; i++)
12355 if ((rc = z_out(n,s,len,rsize)) < 0) { /* Try to write */
12356 printf("?Channel %d WRITE error: %s\n",n,ckferror(rc));
12359 } else { /* FIL_REA READ */
12362 x = cmfld("Variable name","",&s,NULL);
12363 debug(F111,"FILE READ cmfld",s,x);
12365 if (x == -3 || !*s) {
12366 if ((x = cmcfm()) < 0)
12373 ckstrncpy(vnambuf,s,VNAML);
12374 debug(F111,"FILE READ vnambuf",vnambuf,confirmed);
12375 if (vnambuf[0]) { /* Variable name given, check it */
12384 if (vnambuf[0] == CMDQ &&
12385 (vnambuf[1] == '%' || vnambuf[1] == '&'))
12388 if (*vnp == '%' || *vnp == '&') {
12389 if ((y = parsevar(vnp,&x,&dummy)) < 0) {
12390 printf("?Syntax error in variable name\n");
12395 debug(F111,"FILE READ variable",vnambuf,confirmed);
12398 if ((x = cmcfm()) < 0)
12401 line[0] = NUL; /* Clear destination buffer */
12402 if (rsize >= LINBUFSIZ) /* Don't overrun it */
12403 rsize = LINBUFSIZ - 1;
12405 if (rsize == 0) { /* Read a line */
12406 rc = z_in(n,line,LINBUFSIZ,LINBUFSIZ-1,0);
12408 rc = z_in(n,line,LINBUFSIZ,rsize,1); /* Read a block */
12410 if (rc < 0) { /* Error... */
12411 debug(F101,"FILE READ error","",rc);
12412 debug(F101,"FILE READ errno","",errno);
12413 if (rc == FX_EOF) { /* EOF - fail but no error message */
12414 return(success = 0);
12415 } else { /* Other error - fail and print msg */
12416 printf("?READ error: %s\n",ckferror(rc));
12420 if (rsize == 0) { /* FREAD /LINE postprocessing */
12421 if (rd_trim) { /* Trim */
12425 for (i = k-1; i > 0; i--) {
12426 if (line[i] == SP || line[i] == '\t')
12433 if (rd_untab) { /* Untabify */
12434 if (untabify(line,tmpbuf,TMPBUFSIZ) > -1)
12435 ckstrncpy(line,tmpbuf,LINBUFSIZ);
12438 debug(F110,"FILE READ data",line,0);
12439 if (vnambuf[0]) /* Read OK - If variable name given */
12440 addmac(vnambuf,line); /* Assign result to variable */
12441 else /* otherwise */
12442 printf("%s\n",line); /* just print it */
12444 return(success = 1);
12446 case FIL_SEE: /* SEEK */
12447 case FIL_COU: /* COUNT */
12448 rsize = RD_CHAR; /* Defaults to /BYTE */
12449 cmfdbi(&sw, /* Switches */
12450 _CMKEY, /* fcode */
12451 "Channel or switch", /* hlpmsg */
12453 "", /* addtl string data */
12454 ((cx == FIL_SEE) ? nfskswtab : nfcoswtab),
12455 4, /* addtl numeric data 2: 4 = cmswi */
12456 xxstring, /* Processing function */
12457 ((cx == FIL_SEE) ? fskswtab : fcoswtab),
12458 &nu /* Pointer to next FDB */
12460 cmfdbi(&nu, /* Channel number */
12461 _CMNUM, /* fcode */
12464 "", /* addtl string data */
12465 10, /* addtl numeric data 1: radix */
12466 0, /* addtl numeric data 2: 0 */
12467 xxstring, /* Processing function */
12468 NULL, /* Keyword table */
12469 NULL /* Pointer to next FDB */
12472 x = cmfdb(&sw); /* Parse something */
12475 printf("?Channel number required\n");
12480 if (cmresult.fcode == _CMNUM) /* Channel number */
12482 else if (cmresult.fcode == _CMKEY) { /* Switch */
12486 (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
12487 printf("?This switch does not take an argument\n");
12490 if (cx == FIL_SEE) {
12491 switch (cmresult.nresult) {
12492 case SEE_REL: relative = 1; break;
12493 case SEE_ABS: relative = 0; break;
12494 default: rsize = cmresult.nresult;
12496 } else if (cx == FIL_COU) {
12497 switch (cmresult.nresult) {
12498 case COU_LIS: listing = 1; break;
12499 case COU_NOL: listing = 0; break;
12500 default: rsize = cmresult.nresult;
12505 (cmresult.fcode == _CMKEY);
12507 n = cmresult.nresult; /* Channel */
12508 debug(F101,"FILE SEEK/COUNT channel","",n);
12509 if (cx == FIL_COU) {
12510 if ((x = cmcfm()) < 0)
12512 z_filcount = z_count(n,rsize);
12513 if (z_filcount < 0) {
12515 printf("?COUNT error: %s\n",ckferror(rc));
12519 listing = !xcmdsrc;
12521 printf(" %ld %s%s\n",
12523 ((rsize == RD_CHAR) ? "byte" : "line"),
12524 ((z_filcount == 1L) ? "" : "s")
12526 return(success = (z_filcount > -1) ? 1 : 0);
12528 cmfdbi(&sw, /* SEEK symbolic targets (EOF) */
12529 _CMKEY, /* fcode */
12530 "Channel number;\n or keyword",
12532 "", /* addtl string data */
12533 nfsekwtab, /* addtl numeric data 1: table size */
12534 0, /* addtl numeric data 2: 4 = cmswi */
12535 xxstring, /* Processing function */
12536 fsekwtab, /* Keyword table */
12537 &nu /* Pointer to next FDB */
12539 cmfdbi(&nu, /* Channel number */
12540 _CMNUM, /* fcode */
12543 "", /* addtl string data */
12544 10, /* addtl numeric data 1: radix */
12545 0, /* addtl numeric data 2: 0 */
12546 xxstring, /* Processing function */
12547 NULL, /* Keyword table */
12548 NULL /* Pointer to next FDB */
12550 x = cmfdb(&sw); /* Parse something */
12553 printf("?Channel number or EOF required\n");
12558 if (cmresult.fcode == _CMNUM) {
12559 y = cmresult.nresult;
12560 debug(F110,"FILE SEEK atmbuf",atmbuf,0);
12561 if (relative < 0) {
12562 if (cx == FIL_SEE && (atmbuf[0] == '+' || atmbuf[0] == '-'))
12567 } else if (cmresult.fcode == _CMKEY) {
12568 eofflg = cmresult.nresult;
12572 if ((x = cmcfm()) < 0)
12574 z = y; /* Convert to long */
12575 y = 1; /* Recycle this */
12577 debug(F101,"FILE SEEK relative","",relative);
12578 debug(F101,"FILE SEEK rsize","",rsize);
12580 if (rsize == RD_CHAR) { /* Seek to byte position */
12581 if (relative > 0) {
12586 printf("?Relative SEEK failed: %s\n",ckferror(rc));
12591 if (z < 0 && !eofflg) { /* Negative arg but not relative */
12592 y = 0; /* Remember this was bad */
12593 z = 0; /* but substitute 0 */
12596 debug(F101,"FILE SEEK /CHAR z","",z);
12597 if (z < 0 && !eofflg) {
12599 return(success = 0);
12601 if ((rc = z_seek(n,z)) < 0) {
12602 if (rc == FX_EOF) return(success = 0);
12603 printf("?SEEK /BYTE failed - Channel %d: %s\n",n,ckferror(rc));
12606 } else { /* Seek to line */
12607 if (relative > 0) {
12609 pos = z_getline(n);
12610 debug(F101,"FILE SEEK /LINE pos","",pos);
12613 printf("?Relative SEEK failed: %s\n",ckferror(rc));
12618 debug(F101,"FILE SEEK /LINE z","",z);
12619 debug(F101,"FILE SEEK /LINE eofflg","",eofflg);
12620 if (z < 0 && !eofflg) {
12622 return(success = 0);
12624 if ((rc = z_line(n,z)) < 0) {
12625 if (rc == FX_EOF) return(success = 0);
12626 printf("?SEEK /LINE failed - Channel %d: %s\n",n,ckferror(rc));
12630 return(success = y);
12632 case FIL_LIS: { /* LIST open files */
12634 extern int cmd_rows, cmd_cols;
12635 #endif /* CK_TTGWSIZ */
12636 extern int xaskmore;
12637 int i, x, n = 0, paging = 0;
12640 if ((x = cmcfm()) < 0)
12644 if (cmd_rows > 0 && cmd_cols > 0)
12645 #endif /* CK_TTGWSIZ */
12648 printf("System open file limit: %4d\n", z_openmax);
12649 printf("Maximum for FILE OPEN: %4d\n", z_maxchan);
12650 printf("Files currently open: %4d\n\n", z_nopen);
12652 for (i = 0; i < z_maxchan; i++) {
12653 s = z_getname(i); /* Got one? */
12657 printf("%2d. %s",i,s); /* Print name */
12658 n++; /* Count it */
12659 x = z_getmode(i); /* Get modes & print them */
12661 if (x & FM_REA) ckstrncat(m,"R",8);
12662 if (x & FM_WRI) ckstrncat(m,"W",8);
12663 if (x & FM_APP) ckstrncat(m,"A",8);
12664 if (x & FM_BIN) ckstrncat(m,"B",8);
12670 printf(" %ld",z_getpos(i)); /* And file position too */
12674 if (paging > 0) { /* Pause at end of screen */
12675 if (n > cmd_rows - 3) {
12682 #endif /* CK_TTGWSIZ */
12685 return(success = 1);
12688 case FIL_FLU: /* FLUSH */
12689 if ((x = cmnum("Channel number","",10,&n, xxstring)) < 0) {
12691 printf("?Channel number required\n");
12696 if ((x = cmcfm()) < 0)
12698 if ((rc = z_flush(n)) < 0) {
12699 printf("?FLUSH failed - Channel %d: %s\n",n,ckferror(rc));
12702 return(success = 1);
12704 case FIL_STA: /* STATUS */
12705 if ((x = cmnum("Channel number","",10,&n, xxstring)) < 0) {
12707 printf("?Channel number required\n");
12712 if ((x = cmcfm()) < 0)
12714 p = blanks + 3; /* Tricky formatting... */
12718 if ((rc = z_getmode(n)) < 0) {
12719 printf("Channel %d:%s%s\n",n,p,ckferror(rc));
12720 return(success = 0);
12722 printf("Channel %d:%sNot open\n",n,p);
12723 return(success = 0);
12727 if (!s) s = "(name unknown)";
12728 printf("Channel %d:%sOpen\n",n,p);
12729 printf(" File: %s\n Modes: ",s);
12730 if (rc & FM_REA) printf(" /READ");
12731 if (rc & FM_WRI) printf(" /WRITE");
12732 if (rc & FM_APP) printf(" /APPEND");
12733 if (rc & FM_BIN) printf(" /BINARY");
12734 if (rc & FM_CMD) printf(" /COMMAND");
12735 if (rc & FM_EOF) printf(" [EOF]");
12736 printf("\n Size: %ld\n",z_count(n,RD_CHAR));
12737 printf(" At byte: %ld\n",z_getpos(n));
12740 printf(" At line: %ld\n",xx);
12741 return(success = 1);
12747 #endif /* CKCHANNELIO */
12750 /* Save Key maps and in OS/2 Mouse maps */
12752 savkeys(name,disp) char * name; int disp; {
12754 static struct filinfo xx;
12755 int savfil, i, j, k;
12761 xx.bs = 0; xx.cs = 0; xx.rl = 0; xx.org = 0; xx.cc = 0;
12762 xx.typ = 0; xx.dsp = XYFZ_A; xx.os_specific = "";
12764 savfil = zopeno(ZMFILE,name,NULL,&xx);
12765 } else savfil = zopeno(ZMFILE,name,NULL,NULL);
12770 zsout(ZMFILE, "; Kermit 95 SAVE KEYMAP file: ");
12774 "if eq \"\\v(program)\" \"C-Kermit\" set mskermit keycodes on");
12777 "if NOT eq \"\\v(program)\" \"C-Kermit\" stop 1 C-Kermit required.");
12778 zsoutl(ZMFILE,"set mskermit keycodes off");
12783 zsout(ZMFILE, "; C-Kermit SAVE KEYMAP file: ");
12787 zsoutl(ZMFILE,"; Clear previous keyboard mappings ");
12788 zsoutl(ZMFILE,"set key clear");
12790 for (k = 0; k < nttkey; k++) {
12791 if (!ttkeytab[k].flgs) {
12793 "set terminal key ",
12798 zsoutl(ZMFILE,buf);
12804 for (i = 0; i < KMSIZE; i++) {
12806 int len = strlen((char *)macrotab[i]);
12811 ckitoa(mskkeys ? cktomsk(i) : i),
12825 for (j = 0; j < len; j++) {
12826 char ch = macrotab[i][j];
12827 if (ch <= SP || ch >= DEL ||
12828 ch == '-' || ch == ',' ||
12829 ch == '{' || ch == '}' ||
12830 ch == ';' || ch == '?' ||
12831 ch == '.' || ch == '\'' ||
12832 ch == '\\' || ch == '/' ||
12834 ckmakmsg(buf,1024,"\\{",ckitoa((int)ch),"}",NULL);
12837 ckmakmsg(buf,1024,ckctoa((char)ch),NULL,NULL,NULL);
12842 ckmakmsg(buf,1024,"\t; ",keyname(i),NULL,NULL);
12843 zsoutl(ZMFILE,buf);
12847 } else if ( keymap[i] != i ) {
12849 if (IS_KVERB(keymap[i])) {
12850 for (j = 0; j < nkverbs; j++)
12851 if (kverbs[j].kwval == (keymap[i] & ~F_KVERB))
12853 if (j != nkverbs) {
12856 sprintf(buf, "set key \\%d \\K%s\t; %s",
12857 mskkeys ? cktomsk(i) : i,
12858 kverbs[j].kwd, keyname(i)
12861 ckmakxmsg(buf, /* 12 string args */
12864 ckitoa(mskkeys ? cktomsk(i) : i),
12869 NULL, NULL, NULL, NULL, NULL, NULL);
12870 #endif /* COMMENT */
12871 zsoutl(ZMFILE,buf);
12874 sprintf(buf, "set key \\%d \\K%s", i, kverbs[j].kwd);
12882 #endif /* COMMENT */
12883 zsoutl(ZMFILE,buf);
12887 #endif /* NOKVERBS */
12891 sprintf(buf, "set key \\%d \\{%d}\t; %s",
12892 mskkeys ? cktomsk(i) : i,
12897 ckmakxmsg(buf, /* 8 string args */
12900 ckitoa(mskkeys ? cktomsk(i) : i),
12905 NULL,NULL,NULL,NULL,NULL,NULL);
12906 #endif /* COMMENT */
12907 zsoutl(ZMFILE,buf);
12910 sprintf(buf, "set key \\%d \\{%d}", i, keymap[i]);
12912 ckmakxmsg(buf,1024,
12918 NULL,NULL,NULL,NULL,NULL,NULL,NULL);
12919 #endif /* COMMENT */
12920 zsoutl(ZMFILE,buf);
12926 /* OS/2 also has the SET TERMINAL KEY <termtype> defines */
12927 for (k = 0; k < nttkey; k++) {
12928 extern struct keynode * ttkeymap[];
12929 struct keynode * pnode = NULL;
12931 if (ttkeytab[k].flgs) /* Don't process CM_INV or CM_ABR */
12935 ckmakmsg(buf,1024,"; SET TERMINAL KEY ",ttkeytab[k].kwd,NULL,NULL);
12936 zsoutl(ZMFILE,buf);
12938 for (pnode = ttkeymap[ttkeytab[k].kwval];
12940 pnode = pnode->next
12942 switch (pnode->def.type) {
12945 sprintf(buf, "set terminal key %s \\%d \\{%d}\t; %s",
12947 mskkeys ? cktomsk(pnode->key) : pnode->key,
12948 pnode->def.key.scancode,
12949 keyname(pnode->key)
12954 "set terminal key ",
12958 cktomsk(pnode->key) :
12961 ckitoa(pnode->def.key.scancode),
12963 keyname(pnode->key),
12964 NULL,NULL,NULL,NULL
12966 #endif /* COMMENT */
12967 zsoutl(ZMFILE,buf);
12970 for (j = 0; j < nkverbs; j++)
12971 if (kverbs[j].kwval == (pnode->def.kverb.id & ~F_KVERB))
12973 if (j != nkverbs) {
12975 sprintf(buf, "set terminal key %s \\%d \\K%s\t; %s",
12977 mskkeys ? cktomsk(pnode->key) : pnode->key,
12978 kverbs[j].kwd, keyname(pnode->key)
12983 "set terminal key ",
12987 cktomsk(pnode->key) :
12992 keyname(pnode->key),
12993 NULL,NULL,NULL,NULL
12995 #endif /* COMMENT */
12996 zsoutl(ZMFILE,buf);
13000 int len = strlen((char *)pnode->def.macro.string);
13002 sprintf(buf,"set terminal key %s \\%d ",
13004 mskkeys ? cktomsk(pnode->key) : pnode->key);
13008 "set terminal key ",
13012 cktomsk(pnode->key) :
13015 NULL,NULL,NULL,NULL,NULL,NULL,NULL
13017 #endif /* COMMENT */
13020 for (j = 0; j < len; j++) {
13021 char ch = pnode->def.macro.string[j];
13022 if (ch <= SP || ch >= DEL ||
13023 ch == '-' || ch == ',' ||
13024 ch == '{' || ch == '}' ||
13025 ch == ';' || ch == '?' ||
13026 ch == '.' || ch == '\'' ||
13027 ch == '\\' || ch == '/' ||
13030 "\\{",ckitoa((int)ch),"}",NULL);
13034 ckctoa((char)ch),NULL,NULL,NULL);
13038 ckmakmsg(buf,1024,"\t; ",keyname(pnode->key),NULL,NULL);
13039 zsoutl(ZMFILE,buf);
13043 int len = strlen((char *)pnode->def.literal.string);
13045 sprintf(buf,"set terminal key %s /literal \\%d ",
13047 mskkeys ? cktomsk(pnode->key) : pnode->key);
13051 "set terminal key ",
13055 cktomsk(pnode->key) :
13058 NULL,NULL,NULL,NULL,NULL,NULL,NULL);
13059 #endif /* COMMENT */
13062 for (j = 0; j < len; j++) {
13063 char ch = pnode->def.literal.string[j];
13064 if (ch <= SP || ch >= DEL ||
13065 ch == '-' || ch == ',' ||
13066 ch == '{' || ch == '}' ||
13067 ch == ';' || ch == '?' ||
13068 ch == '.' || ch == '\'' ||
13069 ch == '\\' || ch == '/' ||
13072 "\\{",ckitoa((int)ch),"}",NULL);
13076 ckctoa((char)ch),NULL,NULL,NULL);
13080 ckmakmsg(buf,1024,"\t; ",keyname(pnode->key),NULL,NULL);
13081 zsoutl(ZMFILE,buf);
13087 "set terminal key %s /literal \\%d \\{%d}\\{%d}\t; %s",
13089 mskkeys ? cktomsk(pnode->key) : pnode->key,
13090 ISDG200(ttkeytab[k].kwval) ? 30 : 27,
13091 pnode->def.esc.key & ~F_ESC,
13092 keyname(pnode->key)
13097 "set terminal key ",
13101 cktomsk(pnode->key) :
13104 ckitoa(ISDG200(ttkeytab[k].kwval) ? 30 : 27),
13106 ckitoa(pnode->def.esc.key & ~F_ESC),
13108 keyname(pnode->key),
13111 #endif /* COMMENT */
13112 zsoutl(ZMFILE,buf);
13117 "set terminal key %s /literal \\%d \\{27}[\\{%d}\t; %s",
13119 mskkeys ? cktomsk(pnode->key) : pnode->key,
13120 pnode->def.csi.key & ~F_CSI,
13121 keyname(pnode->key)
13126 "set terminal key ",
13130 cktomsk(pnode->key) :
13133 ckitoa(pnode->def.csi.key & ~F_CSI),
13135 keyname(pnode->key),
13136 NULL,NULL,NULL,NULL
13138 #endif /* COMMENT */
13139 zsoutl(ZMFILE,buf);
13149 zsoutl(ZMFILE,"; End");
13151 return(success = 1);
13153 return(success = 0);
13156 #endif /* NOSETKEY */
13163 static struct keytab trmtrmopt[] = {
13164 { "scrollback", SV_SCRL, 0 }
13166 #endif /* NOLOCAL */
13169 static struct keytab cmdtrmopt[] = {
13171 { "history", SV_HIST, 0 },
13172 #endif /* CK_RECALL */
13175 { "scrollback", SV_SCRL, 0 },
13176 #endif /* NOLOCAL */
13180 static int ncmdtrmopt = (sizeof (cmdtrmopt) / sizeof (struct keytab)) - 1;
13184 _PROTOTYP(int savscrbk, (int, char *, int));
13185 #endif /* NOLOCAL */
13189 _PROTOTYP(int savhistory, (char *, int));
13190 #endif /* CK_RECALL */
13193 dosave(xx) int xx; {
13194 int x, y = 0, disp;
13196 extern struct keytab disptb[];
13198 struct zfnfp * fnp;
13199 #endif /* ZFNQFP */
13202 if (xx == XSKEY) { /* SAVE KEYMAP.. */
13203 z = cmofi("Name of Kermit command file","keymap.ksc",&s,xxstring);
13205 #endif /* NOSETKEY */
13207 case XSCMD: /* SAVE COMMAND.. */
13208 if ((y = cmkey(cmdtrmopt, ncmdtrmopt, "What to save",
13219 case XSTERM: /* SAVE TERMINAL.. */
13220 if ((y = cmkey(trmtrmopt,1,
13221 "What to save","scrollback",xxstring)) < 0)
13224 #endif /* NOLOCAL */
13227 z = cmofi("Filename",
13228 ((y == SV_SCRL) ? "scrollbk.txt" : "history.txt"),
13234 #endif /* NOSETKEY */
13235 if (z < 0) /* Check output-file parse results */
13238 printf("?Sorry, %s is a directory name\n",s);
13242 if ((fnp = zfnqfp(s,TMPBUFSIZ - 1,tmpbuf))) {/* Convert to full pathname */
13244 if ((int) strlen(fnp->fpath) > 0)
13247 #endif /* ZFNQFP */
13249 ckstrncpy(line,s,LINBUFSIZ); /* Make safe copy of pathname */
13254 /* Get NEW/APPEND disposition */
13255 if ((z = cmkey(disptb,2,"Disposition","new",xxstring)) < 0)
13259 if ((x = cmcfm()) < 0) /* Get confirmation */
13262 switch (xx) { /* Do action.. */
13264 case XSKEY: /* SAVE KEYMAP */
13265 return (savkeys(s,disp));
13266 #endif /* NOSETKEY */
13268 case XSCMD: /* SAVE COMMAND.. */
13271 if (y == SV_SCRL) /* .. SCROLLBACK */
13272 return(success = savscrbk(VCMD,s,disp));
13273 #endif /* NOLOCAL */
13276 if (y == SV_HIST) /* .. HISTORY */
13277 return(success = savhistory(s,disp));
13279 #endif /* NORECALL */
13283 case XSTERM: /* SAVE TERMINAL SCROLLBACK */
13284 return(success = savscrbk(VTERM,s,disp));
13285 #endif /* NOLOCAL */
13295 Read text with a custom prompt into given buffer using command parser but
13296 with no echoing or entry into recall buffer.
13299 readtext(prmpt, buffer, bufsiz) char * prmpt; char * buffer; int bufsiz; {
13301 extern int on_recall; /* Around Password prompting */
13302 #endif /* CK_RECALL */
13307 extern int startflags;
13308 int vmode_sav = vmode;
13310 if (!prmpt) prmpt = "";
13312 if (win95_popup && !(startflags & 96)
13317 return(popup_readtext(vmode,NULL,prmpt,buffer,bufsiz,0));
13319 if (vmode == VTERM) {
13321 VscrnIsDirty(VTERM);
13322 VscrnIsDirty(VCMD);
13325 #endif /* NOLOCAL */
13329 #endif /* CK_RECALL */
13330 cmsavp(psave,PROMPTL); /* Save old prompt */
13331 cmsetp(prmpt); /* Make new prompt */
13332 concb((char)escape); /* Put console in cbreak mode */
13333 cmini(1); /* and echo mode */
13334 if (pflag) prompt(xxstring); /* Issue prompt if at top level */
13335 cmres(); /* Reset the parser */
13336 for (rc = -1; rc < 0; ) { /* Prompt till they answer */
13337 rc = cmtxt("","",&s,NULL); /* Get a literal line of text */
13338 cmres(); /* Reset the parser again */
13340 ckstrncpy(buffer,s,bufsiz);
13341 cmsetp(psave); /* Restore original prompt */
13345 if (vmode != vmode_sav) {
13347 VscrnIsDirty(VCMD);
13348 VscrnIsDirty(VTERM);
13351 #endif /* NOLOCAL */
13356 /* A general function to allow a Password or other information */
13357 /* to be read from the command prompt without it going into */
13358 /* the recall buffer or being echo'd. */
13361 readpass(prmpt, buffer, bufsiz) char * prmpt; char * buffer; int bufsiz; {
13364 if (!prmpt) prmpt = "";
13365 printf("%s", prmpt);
13367 /* Some linkers won't allow this because it's unsafe */
13369 #else /* COMMENT */
13371 int c, i; char * p;
13373 for (i = 0; i < bufsiz-1; i++) {
13374 if ((c = getchar()) == EOF)
13382 #endif /* COMMENT */
13386 extern int on_recall; /* around Password prompting */
13387 #endif /* CK_RECALL */
13392 extern int startflags;
13393 int vmode_sav = vmode;
13395 #endif /* NOLOCAL */
13398 #endif /* CKSYSLOG */
13399 if (!prmpt) prmpt = "";
13401 debok = 0; /* Don't log */
13403 if (win95_popup && !(startflags & 96)
13408 x = popup_readpass(vmode,NULL,prmpt,buffer,bufsiz,0);
13413 #endif /* NOLOCAL */
13416 savlog = ckxsyslog; /* Save and turn off syslogging */
13418 #endif /* CKSYSLOG */
13421 if (vmode == VTERM) {
13423 VscrnIsDirty(VTERM);
13424 VscrnIsDirty(VCMD);
13427 #endif /* NOLOCAL */
13430 #endif /* CK_RECALL */
13431 cmsavp(psave,PROMPTL); /* Save old prompt */
13432 cmsetp(prmpt); /* Make new prompt */
13433 concb((char)escape); /* Put console in cbreak mode */
13434 cmini(0); /* and no-echo mode */
13435 if (pflag) prompt(xxstring); /* Issue prompt if at top level */
13436 cmres(); /* Reset the parser */
13437 for (rc = -1; rc < 0; ) { /* Prompt till they answer */
13438 rc = cmtxt("","",&s,NULL); /* Get a literal line of text */
13439 cmres(); /* Reset the parser again */
13441 ckstrncpy(buffer,s,bufsiz);
13442 printf("\r\n"); /* Echo a CRLF */
13443 cmsetp(psave); /* Restore original prompt */
13444 cmini(1); /* Restore echo mode */
13447 if (vmode != vmode_sav) {
13449 VscrnIsDirty(VCMD);
13450 VscrnIsDirty(VTERM);
13453 #endif /* NOLOCAL */
13455 ckxsyslog = savlog; /* Restore syslogging */
13456 #endif /* CKSYSLOG */
13463 struct keytab authtab[] = { /* Available authentication types */
13465 { "k4", AUTH_KRB4, CM_INV },
13466 { "k5", AUTH_KRB5, CM_INV },
13467 { "kerberos4", AUTH_KRB4, 0 },
13468 { "kerberos5", AUTH_KRB5, 0 },
13469 { "krb4", AUTH_KRB4, CM_INV },
13470 { "krb5", AUTH_KRB5, CM_INV },
13471 #endif /* CK_KERBEROS */
13473 { "ntlm", AUTH_NTLM, 0 },
13476 { "srp", AUTH_SRP, 0 },
13477 #endif /* CK_SRP */
13479 { "ssl", AUTH_SSL, 0 },
13480 #endif /* CK_SSL */
13483 int authtabn = sizeof(authtab)/sizeof(struct keytab)-1;
13486 struct keytab kerbtab[] = { /* Kerberos authentication types */
13487 { "k4", AUTH_KRB4, CM_INV },
13488 { "k5", AUTH_KRB5, CM_INV },
13489 { "kerberos4", AUTH_KRB4, 0 },
13490 { "kerberos5", AUTH_KRB5, 0 },
13491 { "krb4", AUTH_KRB4, CM_INV },
13492 { "krb5", AUTH_KRB5, CM_INV }
13494 int kerbtabn = sizeof(kerbtab)/sizeof(struct keytab);
13496 static struct keytab krb_s_tbl[] = { /* AUTHENTICATE command switches: */
13497 { "/cache", KRB_S_CA, CM_ARG }
13499 static int krb_s_n = sizeof(krb_s_tbl)/sizeof(struct keytab);
13501 static struct keytab krb_v_tbl[] = { /* KERBEROS version values: */
13503 { "5", 5, 0 }, /* (add others as needed...) */
13504 { "auto", 0, 0 } /* Note: 0 = auto */
13506 static int krb_v_n = sizeof(krb_v_tbl)/sizeof(struct keytab);
13508 static struct keytab krb_a_tbl[] = { /* KERBEROS actions: */
13509 { "destroy", KRB_A_DE, 0 },
13510 { "initialize", KRB_A_IN, 0 },
13511 { "list-credentials", KRB_A_LC, 0 }
13513 static int krb_a_n = sizeof(krb_a_tbl)/sizeof(struct keytab);
13515 static struct keytab krb4_i_tbl[] = { /* KERBEROS 4 INITIALIZE switches: */
13516 { "/brief", KRB_I_BR, 0 }, /* /BRIEF */
13517 { "/instance", KRB_I_IN, CM_ARG }, /* /INSTANCE: */
13518 { "/lifetime", KRB_I_LF, CM_ARG }, /* /LIFETIME: */
13519 { "/not-preauth", KRB_I_NPA, 0 }, /* /NOT-PREAUTH */
13520 { "/password", KRB_I_PW, CM_ARG }, /* /PASSWORD: */
13522 { "/popup", KRB_I_POP, 0 }, /* /POPUP */
13524 { "/preauth", KRB_I_PA, 0 }, /* /PREAUTH */
13525 { "/realm", KRB_I_RL, CM_ARG }, /* /REALM: */
13526 { "/verbose", KRB_I_VB, 0 }, /* /VERBOSE */
13529 static int krb4_i_n = sizeof(krb4_i_tbl)/sizeof(struct keytab) - 1;
13531 static struct keytab krb5_i_tbl[] = { /* KERBEROS 5 INITIALIZE switches: */
13532 { "/addresses", KRB_I_ADR, CM_ARG },
13533 { "/forwardable", KRB_I_FW, 0 }, /* /FORWARDABLE */
13534 { "/instance", KRB_I_IN, CM_ARG }, /* /INSTANCE: */
13535 { "/k4", KRB_I_K4, CM_INV }, /* /KERBEROS4 */
13536 { "/kerberos4", KRB_I_K4, 0 }, /* /KERBEROS4 */
13537 { "/krb4", KRB_I_K4, CM_INV }, /* /KERBEROS4 */
13538 { "/lifetime", KRB_I_LF, CM_ARG }, /* /LIFETIME: */
13539 { "/no-addresses", KRB_I_NAD, 0 }, /* /NO-ADDRESSES */
13540 { "/no-k4", KRB_I_NK4, CM_INV },/* /NO-KERBEROS4 */
13541 { "/no-kerberos4", KRB_I_NK4, 0 }, /* /NO-KERBEROS4 */
13542 { "/no-krb4", KRB_I_NK4, CM_INV },/* /NO-KERBEROS4 */
13543 { "/not-forwardable", KRB_I_NFW, 0 }, /* /NOT-FORWARDABLE */
13544 { "/not-proxiable", KRB_I_NPR, 0 }, /* /NOT-PROXIABLE */
13545 { "/password", KRB_I_PW, CM_ARG }, /* /PASSWORD: */
13547 { "/popup", KRB_I_POP, 0 }, /* /POPUP */
13549 { "/postdate", KRB_I_PD, CM_ARG }, /* /POSTDATE: */
13550 { "/pr", KRB_I_PR, CM_INV|CM_ABR }, /* to allow for */
13551 { "/pro", KRB_I_PR, CM_INV|CM_ABR }, /* different spellings */
13552 { "/prox", KRB_I_PR, CM_INV|CM_ABR },
13553 { "/proxiable", KRB_I_PR, 0 }, /* /PROXIABLE */
13554 { "/proxyable", KRB_I_PR, CM_INV }, /* /PROXYABLE */
13555 { "/realm", KRB_I_RL, CM_ARG }, /* /REALM: */
13556 { "/renew", KRB_I_RN, 0 }, /* /RENEW */
13557 { "/renewable", KRB_I_RB, CM_ARG }, /* /RENEWABLE: */
13558 { "/service", KRB_I_SR, CM_ARG }, /* /SERVICE: */
13559 { "/validate", KRB_I_VA, 0 }, /* /VALIDATE */
13562 static int krb5_i_n = sizeof(krb5_i_tbl)/sizeof(struct keytab) - 1;
13564 static struct keytab klctab[] = { /* List Credentials switches*/
13565 { "/addresses", XYKLCAD, 0 },
13566 { "/encryption", XYKLCEN, 0 },
13567 { "/flags", XYKLCFL, 0 }
13569 static int nklctab = sizeof(klctab)/sizeof(struct keytab);
13571 extern int krb_action;
13572 extern struct krb_op_data krb_op;
13574 extern struct krb5_list_cred_data krb5_lc;
13575 extern struct krb5_init_data krb5_init;
13576 extern char * krb5_d_principal; /* Default principal */
13577 extern char * krb5_d_instance;
13578 extern char * krb5_d_realm; /* Default realm */
13579 extern char * krb5_d_cc; /* Default credentials cache */
13580 extern char * krb5_d_srv; /* Default service name */
13581 extern int krb5_d_lifetime; /* Default lifetime */
13582 extern int krb5_d_forwardable;
13583 extern int krb5_d_proxiable;
13584 extern int krb5_d_renewable;
13585 extern int krb5_autoget;
13586 extern int krb5_autodel;
13587 extern int krb5_d_getk4;
13588 extern int krb5_d_no_addresses;
13589 extern int krb5_checkaddrs;
13590 extern char * krb5_d_addrs[];
13591 extern char * k5_keytab; /* Keytab file */
13593 extern struct krb4_init_data krb4_init;
13594 extern char * krb4_d_principal; /* Default principal */
13595 extern char * krb4_d_realm; /* Default realm */
13596 extern char * krb4_d_srv; /* Default service name */
13597 extern int krb4_d_lifetime; /* Default lifetime */
13598 extern int krb4_d_preauth;
13599 extern char * krb4_d_instance;
13600 extern int krb4_autoget;
13601 extern int krb4_autodel;
13602 extern int krb4_checkaddrs;
13603 extern char * k4_keytab; /* Keytab file */
13604 #endif /* CK_KERBEROS */
13611 extern int ckxsyslog, ckxwtmp, ckxanon;
13613 extern int ckxpriv;
13616 extern int ckxperms;
13617 #endif /* CK_PERMS */
13618 extern char * anonfile, * userfile, * anonroot;
13620 extern char * anonacct;
13623 extern char * iks_domain;
13625 #endif /* CK_LOGIN */
13627 extern char * wtmpfile;
13628 #endif /* CKWTMP */
13630 extern char * dbfile;
13631 extern int dbenabled;
13634 extern int logintimo;
13635 #endif /* CK_LOGIN */
13636 extern int srvcdmsg, success, iksdcf, noinit, arg_x;
13637 extern char * cdmsgfile[], * cdmsgstr, *kermrc;
13638 char * bannerfile = NULL;
13639 char * helpfile = NULL;
13640 extern int xferlog;
13641 extern char * xferfile;
13645 printf("?Command disabled\r\n");
13646 return(success = 0);
13649 printf("IKS Settings\r\n");
13652 printf(" Anonymous Account: %s\r\n",anonacct?anonacct:"<none>");
13654 printf(" Anonymous Initfile: %s\r\n",anonfile?anonfile:"<none>");
13655 printf(" Anonymous Login: %d\r\n",ckxanon);
13656 printf(" Anonymous Root: %s\r\n",anonroot?anonroot:"<none>");
13657 #endif /* CK_LOGIN */
13658 printf(" Bannerfile: %s\r\n",bannerfile?bannerfile:"<none>");
13659 printf(" CDfile: %s\r\n",cdmsgfile[0]?cdmsgfile[0]:"<none>");
13660 for ( i=1;i<16 && cdmsgfile[i];i++ )
13661 printf(" CDfile: %s\r\n",cdmsgfile[i]);
13662 printf(" CDMessage: %d\r\n",srvcdmsg);
13664 printf(" DBfile: %s\r\n",dbfile?dbfile:"<none>");
13665 printf(" DBenabled: %d\r\n",dbenabled);
13669 printf(" Default-domain: %s\r\n",iks_domain?iks_domain:".");
13671 #endif /* CK_LOGIN */
13672 printf(" Helpfile: %s\r\n",helpfile?helpfile:"<none>");
13673 printf(" Initfile: %s\r\n",kermrc?kermrc:"<none>");
13674 printf(" No-Initfile: %d\r\n",noinit);
13677 printf(" Permission code: %0d\r\n",ckxperms);
13678 #endif /* CK_PERM */
13680 printf(" Privileged Login: %d\r\n",ckxpriv);
13682 #endif /* CK_LOGIN */
13683 printf(" Server-only: %d\r\n",arg_x);
13684 printf(" Syslog: %d\r\n",ckxsyslog);
13685 printf(" Timeout (seconds): %d\r\n",logintimo);
13686 printf(" Userfile: %s\r\n",userfile?userfile:"<none>");
13689 printf(" Wtmplog: %d\r\n",ckxwtmp);
13690 printf(" Wtmpfile: %s\r\n",wtmpfile?wtmpfile:"<none>");
13691 #endif /* CKWTMP */
13692 #endif /* CK_LOGIN */
13693 printf(" Xferfile: %s\r\n",xferfile?xferfile:"<none>");
13694 printf(" Xferlog: %d\r\n",xferlog);
13695 #else /* IKSDCONF */
13696 printf("?Nothing to show.\r\n");
13697 #endif /* IKSDCONF */
13698 return(success = 1);
13701 #ifdef CK_AUTHENTICATION
13703 sho_auth(cx) int cx; {
13704 extern int auth_type_user[], cmd_rows;
13707 int kv = 0, all = 0, n = 0;
13710 if (inserver && isguest) {
13711 printf("?Sorry, command disabled.\r\n");
13712 return(success = 0);
13717 } else if (auth_type_user[0] != AUTHTYPE_AUTO) {
13718 kv = auth_type_user[0];
13721 kv = AUTHTYPE_KERBEROS_V4;
13725 case AUTHTYPE_KERBEROS_V4:
13726 kv = all ? AUTHTYPE_KERBEROS_V5 : 0;
13727 if (ck_krb4_is_installed()) {
13728 printf(" Authentication: Kerberos 4\n");
13729 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13731 printf(" Authentication: Kerberos 4 (not installed)\n");
13732 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13736 printf(" Keytab file: %s\n",
13737 k4_keytab ? k4_keytab : "(none)");
13738 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13739 if (krb_action < 0) {
13742 for (p = "", i = 0; i < krb_a_n; i++) {
13743 if (krb_action == krb_a_tbl[i].kwval) {
13744 p = krb_a_tbl[i].kwd;
13749 printf(" Action: %s\n", p);
13750 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13751 printf(" Default lifetime %d\n",krb4_d_lifetime);
13752 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13753 printf(" Lifetime: %d (minutes)\n",krb4_init.lifetime);
13754 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13755 printf(" Default preauth: %d\n",krb4_d_preauth);
13756 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13757 printf(" Preauth: %d\n",krb4_init.preauth);
13758 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13759 printf(" Default principal: \"%s\"\n",
13760 krb4_d_principal ? krb4_d_principal : "");
13761 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13762 printf(" Principal: \"%s\"\n",
13763 krb4_init.principal ? krb4_init.principal : "");
13764 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13765 printf(" Default realm: \"%s\"\n",
13766 krb4_d_realm ? krb4_d_realm : "");
13767 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13768 printf(" Realm: \"%s\"\n",
13769 krb4_init.realm ? krb4_init.realm : "");
13770 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13771 printf(" Default instance: \"%s\"\n",
13772 krb4_d_instance ? krb4_d_instance : "");
13773 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13774 printf(" Instance: \"%s\"\n",
13775 krb4_init.instance ? krb4_init.instance : "");
13776 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13777 printf(" Auto-Get TGTs: %d\n",krb4_autoget);
13778 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13779 printf(" Auto-Destroy TGTs: %s\n",
13780 krb4_autodel==KRB_DEL_NO?"never":
13781 krb4_autodel==KRB_DEL_CL?"on-close":"on-exit");
13782 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13783 printf(" Check IP Addresses: %d\n",krb4_checkaddrs);
13784 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13786 printf(" Password: \"%s\"\n",
13787 krb4_init.password ? krb4_init.password : "");
13788 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13789 #endif /* COMMENT */
13790 #endif /* CK_KERBEROS */
13792 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13794 case AUTHTYPE_KERBEROS_V5:
13795 kv = all ? AUTHTYPE_SSL : 0;
13796 if (ck_krb5_is_installed()) {
13797 if (ck_gssapi_is_installed())
13798 printf(" Authentication: Kerberos 5 plus GSSAPI\n");
13800 printf(" Authentication: Kerberos 5\n");
13801 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13803 printf(" Authentication: Kerberos 5 (not installed)\n");
13804 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13809 printf(" Cache file: %s\n",
13810 krb_op.cache ? krb_op.cache : "(none)");
13811 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13812 printf(" Default cache: %s\n",
13813 krb5_d_cc ? krb5_d_cc : "(none)");
13814 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13815 printf(" Keytab file: %s\n",
13816 k5_keytab ? k5_keytab : "(none)");
13817 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13818 if (krb_action < 0) {
13821 for (p = "", i = 0; i < krb_a_n; i++) {
13822 if (krb_action == krb_a_tbl[i].kwval) {
13823 p = krb_a_tbl[i].kwd;
13828 printf(" Action: %s\n", p);
13829 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13831 printf(" Default forwardable %d\n",krb5_d_forwardable);
13832 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13833 printf(" Forwardable: %d\n",krb5_init.forwardable);
13834 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13835 printf(" Default lifetime %d\n",krb5_d_lifetime);
13836 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13837 printf(" Lifetime: %d (minutes)\n",krb5_init.lifetime);
13838 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13839 printf(" Postdate: \"%s\"\n",
13840 krb5_init.postdate ? krb5_init.postdate: "");
13841 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13842 printf(" Default proxiable: %d\n",krb5_d_proxiable);
13843 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13844 printf(" Proxiable: %d\n",krb5_init.proxiable);
13845 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13846 printf(" Renew: %d\n",krb5_init.renew);
13847 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13848 printf(" Default renewable: %d (minutes)\n",krb5_d_renewable);
13849 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13850 printf(" Renewable: %d (minutes)\n",krb5_init.renewable);
13851 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13852 printf(" Service: \"%s\"\n",
13853 krb5_init.service ? krb5_init.service : "");
13854 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13855 printf(" Validate: %d\n",krb5_init.validate);
13856 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13857 printf(" Default principal: \"%s\"\n",
13858 krb5_d_principal ? krb5_d_principal : "");
13859 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13860 printf(" Principal: \"%s\"\n",
13861 krb5_init.principal ? krb5_init.principal : "");
13862 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13863 printf(" Default instance: \"%s\"\n",
13864 krb5_d_instance ? krb5_d_instance : "");
13865 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13866 printf(" Default realm: \"%s\"\n",
13867 krb5_d_realm ? krb5_d_realm : "");
13868 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13869 printf(" Realm: \"%s\"\n",
13870 krb5_init.realm ? krb5_init.realm : "");
13871 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13872 printf(" Auto-Get TGTs: %d\n",krb5_autoget);
13873 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13874 printf(" Auto-Destroy TGTs: %s\n",
13875 krb5_autodel==KRB_DEL_NO?"never":
13876 krb5_autodel==KRB_DEL_CL?"on-close":"on-exit");
13877 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13878 printf(" Default get K4 TGTs: %d\n",krb5_d_getk4);
13879 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13880 printf(" Get K4 TGTs: %d\n",krb5_init.getk4);
13881 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13882 printf(" Check IP Addresses: %d\n",krb5_checkaddrs);
13883 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13884 printf(" No IP Addresses: %d\n",krb5_d_no_addresses);
13885 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13886 printf(" IP-Addresses: ");
13887 if (krb5_init.addrs && krb5_init.addrs[0]) {
13888 for (i = 0; krb5_init.addrs[i]; i++) {
13891 printf("%s",krb5_init.addrs[i]);
13893 } else if (krb5_d_addrs[0]) {
13894 for (i = 0;i < KRB5_NUM_OF_ADDRS && krb5_d_addrs[i];i++) {
13897 printf("%s",krb5_d_addrs[i]);
13900 printf("(use default)");
13903 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13905 printf(" Password: \"%s\"\n",
13906 krb5_init.password ? krb5_init.password : "");
13907 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13908 #endif /* COMMENT */
13909 #endif /* CK_KERBEROS */
13911 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13914 kv = all ? AUTHTYPE_SRP : 0;
13915 if (ck_ssleay_is_installed()) {
13916 printf(" Authentication: SSL/TLS (%s)\n",
13917 SSLeay_version(SSLEAY_VERSION));
13918 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13920 printf(" Authentication: SSL/TLS (not installed)\n");
13921 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13926 printf(" RSA Certs file: %s\n",ssl_rsa_cert_file?
13927 ssl_rsa_cert_file:"(none)");
13928 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13929 printf(" RSA Certs Chain file: %s\n",ssl_rsa_cert_chain_file?
13930 ssl_rsa_cert_chain_file:"(none)");
13931 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13932 printf(" RSA Key file: %s\n",ssl_rsa_key_file?
13933 ssl_rsa_key_file:"(none)");
13934 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13935 printf(" DSA Certs file: %s\n",ssl_dsa_cert_file?
13936 ssl_dsa_cert_file:"(none)");
13937 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13938 printf(" DSA Certs Chain file: %s\n",ssl_dsa_cert_chain_file?
13939 ssl_dsa_cert_chain_file:"(none)");
13940 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13941 printf(" DH Key file: %s\n",ssl_dh_key_file?
13942 ssl_dh_key_file:"(none)");
13943 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13944 printf(" DH Param file: %s\n",ssl_dh_param_file?
13945 ssl_dh_param_file:"(none)");
13946 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13947 printf(" CRL file: %s\n",ssl_crl_file?
13948 ssl_crl_file:"(none)");
13949 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13950 printf(" CRL dir: %s\n",ssl_crl_dir?
13951 ssl_crl_dir:"(none)");
13952 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13953 printf(" Random file: %s\n",ssl_rnd_file?
13954 ssl_rnd_file:"(none)");
13955 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13956 printf(" Verify file: %s\n",ssl_verify_file?
13957 ssl_verify_file:"(none)");
13958 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13959 printf(" Verify dir: %s\n",ssl_verify_dir?
13960 ssl_verify_dir:"(none)");
13961 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13962 printf(" Cipher list: %s\n",ssl_cipher_list ? ssl_cipher_list :
13963 DEFAULT_CIPHER_LIST);
13964 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13965 if (ssl_con == NULL) {
13966 SSL_library_init();
13967 ssl_ctx = (SSL_CTX *)
13968 SSL_CTX_new((SSL_METHOD *)TLSv1_method());
13969 if (ssl_ctx != NULL)
13970 ssl_con= (SSL *) SSL_new(ssl_ctx);
13972 if (ssl_con != NULL) {
13976 for (i = 0; ; i++) {
13977 p = (CHAR *) SSL_get_cipher_list(ssl_con,i);
13981 if (++n > cmd_rows - 3)
13982 if (!askmore()) return(0); else n = 0;
13985 printf(" Certs OK? %s\n",ssl_certsok_flag? "yes" : "no");
13986 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13987 printf(" Debug mode: %s\n", ssl_debug_flag ? "on" : "off");
13988 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13989 printf(" Verbose mode: %s\n", ssl_verbose_flag ? "on" : "off");
13990 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13991 printf(" Verify mode: %s\n",
13992 ssl_verify_flag == SSL_VERIFY_NONE ? "none" :
13993 ssl_verify_flag == SSL_VERIFY_PEER ? "peer-cert" :
13994 "fail-if-no-peer-cert");
13995 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13996 printf(" SSL only? %s\n", ssl_only_flag ? "yes" : "no");
13997 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13998 printf(" TLS only? %s\n", tls_only_flag ? "yes" : "no");
13999 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14000 #endif /* CK_SSL */
14002 case AUTHTYPE_NTLM:
14004 if (ck_ntlm_is_installed()) {
14005 printf(" Authentication: NTLM\n");
14006 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14007 printf(" No options\n");
14008 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14010 printf(" Authentication: NTLM (not installed)\n");
14011 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14015 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14018 kv = all ? AUTHTYPE_NTLM : 0;
14019 if (ck_srp_is_installed()) {
14020 if (ck_krypto_is_installed())
14021 printf(" Authentication: SRP plus Krypto API\n");
14023 printf(" Authentication: SRP\n");
14024 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14025 printf(" No options\n");
14026 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14028 printf(" Authentication: SRP (not installed)\n");
14029 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14033 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14037 return(success = 1);
14039 #endif /* CK_AUTHENTICATION */
14040 #endif /* NOSHOW */
14044 /* C P _ A U T H -- AUTHENTICATE command parsing */
14047 cp_auth() { /* Command_Parse AUTHENTICATE */
14048 int c, i, n; /* Workers */
14049 int rc = 0; /* Return code */
14050 int getval; /* Parsing helpers */
14051 int tmpauth = 0; /* Temporary authentication type */
14052 int kv = 0; /* Temporary Kerberos version */
14053 int tmp_action = -1; /* Temporary Kerberos action */
14054 int tmp_klc = 0; /* Temporary list-credentials */
14055 char tmphlp[256]; /* For building help message */
14057 char * tmppswd = NULL; /* Password */
14058 char * tmpprinz = NULL; /* Principal */
14059 char * tmprealm = NULL; /* Realm */
14060 char * tmpcache = NULL; /* Cache file */
14061 char * tmpinst = NULL; /* K4 Instance */
14062 char * tmpaddrs[KRB5_NUM_OF_ADDRS];
14064 extern int on_recall; /* around Password prompting */
14065 #endif /* CK_RECALL */
14066 struct stringint { /* Temporary array for switch values */
14067 char * sval; /* String value */
14068 int ival; /* Integer value */
14069 } pv[KRB_I_MAX+1]; /* This many */
14070 struct FDB kw, sw, fl; /* FDBs for each parse function */
14072 krb_action = -1; /* Initialize Kerberos action. */
14073 tmp_action = -1; /* And our local copy. */
14074 for (i = 0; i < KRB5_NUM_OF_ADDRS; i++)
14075 tmpaddrs[i] = NULL;
14077 if ((y = cmkey(kerbtab,kerbtabn,"authentication type","",xxstring)) < 0)
14080 printf("?Authentication type not specified - nothing happens\n");
14084 debug(F101,"kerberos authentication","",tmpauth);
14086 case AUTH_KRB4: kv = 4; break; /* Don't assume values are the same */
14087 case AUTH_KRB5: kv = 5; break;
14089 printf("?Authentication type not supported: \"%s\"\n",atmbuf);
14093 /* From here down is Kerberos */
14094 ini_kerb(); /* Reset Init data to defaults */
14096 if (kv == 4) { /* Set K4 defaults */
14098 makestr(&tmprealm,krb4_d_realm);
14099 if (krb4_d_principal)
14100 makestr(&tmpprinz,krb4_d_principal);
14101 if (krb4_d_instance)
14102 makestr(&tmpinst,krb4_d_instance);
14103 } else if (kv == 5) { /* Set K5 defaults */
14105 makestr(&tmpcache,krb5_d_cc);
14107 makestr(&tmprealm,krb5_d_realm);
14108 if (krb5_d_principal)
14109 makestr(&tmpprinz,krb5_d_principal);
14110 if (krb5_d_instance)
14111 makestr(&tmpinst,krb5_d_instance);
14114 for (i = 0; i <= KRB_I_MAX; i++) { /* Initialize switch values */
14115 pv[i].sval = NULL; /* to null pointers */
14116 pv[i].ival = 0; /* and 0 int values */
14119 if (kv == 4) { /* Kerberos 4 */
14120 pv[KRB_I_LF].ival = krb4_d_lifetime;
14121 pv[KRB_I_PA].ival = krb4_d_preauth;
14123 if ((n = cmkey(krb_a_tbl,krb_a_n,"Kerberos 4 action","",xxstring)) < 0)
14126 printf("?Action not specified - nothing happens.\n");
14129 } else if (kv == 5) { /* Kerberos 5 */
14130 pv[KRB_I_FW].ival = krb5_d_forwardable;
14131 pv[KRB_I_PR].ival = krb5_d_proxiable;
14132 pv[KRB_I_LF].ival = krb5_d_lifetime;
14133 pv[KRB_I_RB].ival = krb5_d_renewable;
14134 pv[KRB_I_K4].ival = krb5_d_getk4;
14135 pv[KRB_I_NAD].ival = krb5_d_no_addresses;
14137 /* Make help message that shows switches and action keywords */
14138 ckstrncpy(tmphlp,"Kerberos 5 action, one of the following:\n ",256);
14139 for (i = 0; i < krb_a_n; i++) {
14140 ckstrncat(tmphlp,krb_a_tbl[i].kwd,sizeof(tmphlp));
14141 if (i == krb_a_n - 1)
14142 ckstrncat(tmphlp,"\nor switch",sizeof(tmphlp));
14144 ckstrncat(tmphlp," ",sizeof(tmphlp));
14146 /* Set up first set of chained FDB's */
14148 cmfdbi(&sw, /* First FDB - command switches */
14149 _CMKEY, /* fcode */
14150 tmphlp, /* hlpmsg */
14151 "", /* default (none) */
14152 "", /* addtl string data */
14153 krb_s_n, /* Switch table size */
14154 4, /* addtl numeric data 2: 4 = cmswi */
14155 xxstring, /* Processing function */
14156 krb_s_tbl, /* Switch table */
14157 &kw /* Pointer to next FDB */
14159 cmfdbi(&kw, /* Second FDB - action keywords */
14160 _CMKEY, /* fcode */
14161 "Kerberos action", /* hlpmsg */
14162 "", /* default (none) */
14163 "", /* addtl string data */
14164 krb_a_n, /* Switch table size */
14165 0, /* addtl num data (0 = NOT switch) */
14166 xxstring, /* Processing function */
14167 krb_a_tbl, /* Keyword table */
14168 NULL /* Pointer to next FDB (none) */
14173 while (1) { /* Parse 0 or more switches */
14174 rc = cmfdb(&sw); /* Parse something */
14175 debug(F101,"kerberos cmfdb 1 rc","",rc);
14176 if (rc < 0) { /* Error */
14178 printf("?Action not specified - nothing happens.\n");
14179 return(rc); /* or reparse needed */
14181 if (cmresult.fdbaddr != &sw) /* Break out if not a switch */
14183 c = cmgbrk(); /* Have switch - get break character */
14184 getval = (c == ':' || c == '='); /* Must parse an agument? */
14185 if (getval && !(cmresult.kflags & CM_ARG)) {
14186 printf("?This switch does not take arguments\n");
14187 return(-9); /* OK because nothing malloc'd yet */
14189 if (!getval && (cmgkwflgs() & CM_ARG)) {
14190 printf("?This switch requires an argument\n");
14193 n = cmresult.nresult; /* Numeric result = switch value */
14194 debug(F101,"kerberos command switch","",n);
14196 switch (n) { /* Handle the switch */
14197 case KRB_S_CA: /* /CACHE:<filename> */
14198 p = krb5_d_cc ? krb5_d_cc : "";
14199 if ((y = cmofi("Name of cache file",p,&s,xxstring)) < 0) {
14205 makestr(&tmpcache,s);
14208 printf("?Unexpected switch value - internal error\n");
14209 return(-9); /* (if) nothing malloc'd yet. */
14212 if (cmresult.fdbaddr != &kw) { /* Checking... */
14213 printf("?Unexpected result - internal error\n");
14214 return(-9); /* Nothing malloc'd yet. */
14216 n = cmresult.nresult; /* Get keyword value */
14218 printf("?Unexpected Kerberos version - Internal error\n");
14221 debug(F101,"kerberos action","",n);
14223 case KRB_A_IN: /* INITIALIZE */
14224 case KRB_A_DE: /* DESTROY */
14225 case KRB_A_LC: /* LIST-CREDENTIALS */
14226 tmp_action = n; /* OK, set */
14228 default: /* Not OK, punt. */
14229 printf("?Unexpected action - internal error\n");
14232 if (tmp_action == KRB_A_IN) { /* Action is INITIALIZE */
14234 cmfdbi(&sw, /* INITIALIZE switches */
14235 _CMKEY, /* fcode */
14236 "Principal,\n or optional INITIALIZE switch(es)", /* hlpmsg */
14237 "", /* default (none) */
14238 "", /* addtl string data */
14239 kv == 4 ? krb4_i_n : krb5_i_n, /* Switch table size */
14240 4, /* addtl numeric data 2: 4 = cmswi */
14241 xxstring, /* Processing function */
14242 kv == 4 ? krb4_i_tbl : krb5_i_tbl, /* Switch table */
14243 &fl /* Pointer to next FDB */
14245 cmfdbi(&fl, /* 3rd FDB - command to send from */
14246 _CMFLD, /* fcode */
14247 "Principal", /* hlpmsg */
14248 kv == 4 ? krb4_d_principal : krb5_d_principal, /* principal */
14249 "", /* addtl string data */
14250 0, /* addtl numeric data 1 */
14251 0, /* addtl numeric data 2 */
14256 while (1) { /* Parse INIT switches or principal */
14258 debug(F101,"kerberos cmfdb 2 rc","",rc);
14261 printf("?Principal name required\n");
14264 debug(F101,"kerberos cmfdb 2 fcode","",cmresult.fcode);
14265 if (cmresult.fcode != _CMKEY) /* Not a switch, quit switch loop */
14267 c = cmgbrk(); /* Switch - get break character */
14268 debug(F101,"kerberos cmfdb 2 cmgbrk","",c);
14269 getval = (c == ':' || c == '=');
14270 if (getval && !(cmresult.kflags & CM_ARG)) {
14271 printf("?This switch does not take arguments\n");
14272 return(-9); /* OK because nothing malloc'd yet */
14274 if (!getval && (cmgkwflgs() & CM_ARG)) {
14275 printf("?This switch requires an argument\n");
14278 n = cmresult.nresult; /* Numeric result = switch value */
14280 /* These don't take args... */
14281 case KRB_I_PA: /* /PREAUTH */
14282 case KRB_I_FW: /* /FORWARDABLE */
14283 case KRB_I_PR: /* /PROXIABLE */
14284 case KRB_I_RN: /* /RENEW */
14285 case KRB_I_VA: /* /VALIDATE */
14286 case KRB_I_NPA: /* /NOT-PREAUTH */
14287 case KRB_I_NFW: /* /NOT-FORWARDABLE */
14288 case KRB_I_NPR: /* /NOT-PROXIABLE */
14289 case KRB_I_VB: /* /VERBOSE */
14290 case KRB_I_BR: /* /BRIEF */
14291 case KRB_I_K4: /* /KERBEROS4 */
14292 case KRB_I_NK4: /* /NO-KERBEROS4 */
14293 case KRB_I_POP: /* /POPUP */
14294 case KRB_I_NAD: /* /NO-ADDRESSES */
14296 printf("?This switch does not take a value\n");
14302 pv[KRB_I_PA].ival = 0;
14305 pv[KRB_I_FW].ival = 0;
14308 pv[KRB_I_PR].ival = 0;
14311 pv[KRB_I_BR].ival = 0;
14314 pv[KRB_I_K4].ival = 0;
14321 /* These do take arguments */
14323 case KRB_I_RB: /* /RENEWABLE:<minutes> */
14325 if (!getval) break;
14326 if ((rc = cmnum("Minutes",ckitoa(krb5_init.renewable),
14327 10,&y, xxstring)) < 0)
14332 case KRB_I_LF: /* /LIFETIME:<minutes> */
14334 /* Default is previous value */
14335 sprintf(tmpbuf,"%d", /* SAFE */
14337 krb4_init.lifetime :
14340 if (!getval) break;
14341 if ((rc = cmnum("Minutes",tmpbuf,10,&y, xxstring)) < 0)
14346 case KRB_I_PD: /* /POSTDATE:<timestamp> */
14351 if (!getval) break;
14352 if ((rc = cmdate("date-time","",&s,0,xxstring)) < 0)
14354 makestr(&(pv[n].sval),s);
14357 case KRB_I_SR: /* /SERVICE:<name> */
14362 if (!getval) break;
14363 if ((rc = cmfld("Service-name","",&s,xxstring)) < 0)
14365 makestr(&(pv[n].sval),s);
14368 case KRB_I_RL: /* /REALM:<name> */
14373 if (!getval) break;
14375 p = krb4_d_realm ? krb4_d_realm : "";
14377 p = krb5_d_realm ? krb5_d_realm : "";
14378 if ((rc = cmfld("Realm",p,&s,xxstring)) < 0)
14380 makestr(&(pv[n].sval),s);
14383 case KRB_I_IN: /* /INSTANCE:<name> */
14388 if (!getval) break;
14390 p = krb4_d_instance ? krb4_d_instance : "";
14392 p = krb5_d_instance ? krb5_d_instance : "";
14393 if ((rc = cmfld("Instance",p,&s,xxstring)) < 0)
14395 makestr(&(pv[n].sval),s);
14398 case KRB_I_PW: /* /PASSWORD:<password> */
14404 if (!getval) break;
14405 if ((rc = cmfld("Password","",&s,xxstring)) < 0)
14408 makestr(&(pv[n].sval),s);
14411 case KRB_I_ADR: /* /ADDRESSES:{<address-list>} */
14416 if (!getval) break;
14417 if ((rc = cmfld("List of IP addresses","",&s,xxstring)) < 0)
14419 makelist(s,tmpaddrs,KRB5_NUM_OF_ADDRS);
14420 for (i = 0; i < KRB5_NUM_OF_ADDRS && tmpaddrs[i]; i++) {
14421 if (inet_addr(tmpaddrs[i]) == 0xffffffff) {
14422 printf("invalid ip address: %s\n",tmpaddrs[i]);
14427 pv[KRB_I_NAD].ival = 0;
14431 printf("?Unexpected switch value - internal error\n");
14436 if (cmresult.fcode != _CMFLD) {
14437 printf("?Unexected result - internal error\n");
14441 /* cmresult.sresult may be of the form PRINCIPAL@REALM */
14442 i = ckindex("@",cmresult.sresult,0,0,0);
14444 makestr(&tmprealm,&cmresult.sresult[i]);
14445 cmresult.sresult[i-1] = '\0';
14447 makestr(&tmpprinz,cmresult.sresult); /* Principal (user) */
14449 if ((rc = cmcfm()) < 0) { /* Now get confirmation */
14451 printf("?Principal name required\n");
14455 if (!tmpprinz || !tmpprinz[0]) {
14456 printf("?Principal name required\n");
14459 if (!pv[KRB_I_RN].ival && !pv[KRB_I_VA].ival) {
14460 /* Don't use a password if Validating or Renewing */
14461 if (pv[KRB_I_PW].sval) { /* If they gave a /PASSWORD switch */
14462 makestr(&tmppswd,pv[KRB_I_PW].sval); /* use this value */
14465 /* Password prompting has been moved to ck_krb[45]_initTGT() */
14466 else { /* Otherwise must prompt for it */
14468 if (pv[KRB_I_RL].sval)
14469 sprintf(prmpt,"%s@%s's Password: ",
14470 tmpprinz,pv[KRB_I_RL].sval);
14472 sprintf(prmpt,"%s@%s's Password: ",
14473 tmpprinz,tmprealm);
14475 sprintf(prmpt,"%s's Password: ",tmpprinz);
14477 if (pv[KRB_I_POP].ival) {
14478 char passwd[80]="";
14479 readpass(prmpt,passwd,80);
14480 makestr(&tmppswd,passwd);
14481 memset(passwd,0,80);
14487 #endif /* CK_RECALL */
14488 cmsavp(psave,PROMPTL); /* Save old prompt */
14489 cmsetp(prmpt); /* Make new prompt */
14490 concb((char)escape); /* Put console in cbreak mode */
14491 cmini(0); /* and no-echo mode */
14492 /* Issue prompt if at top level */
14493 if (pflag) prompt(xxstring);
14494 cmres(); /* Reset the parser */
14495 for (rc = -1; rc < 0; ) { /* Prompt till they answer */
14496 /* Get a literal line of text */
14497 rc = cmtxt("","",&s,NULL);
14498 cmres(); /* Reset the parser again */
14500 makestr(&tmppswd,s);
14501 printf("\n"); /* Echo a CRLF */
14502 cmsetp(psave); /* Restore original prompt */
14505 x = 0; /* Check for password */
14510 printf("?Password required\n");
14513 #endif /* COMMENT */
14515 } else if (kv == 5 && tmp_action == KRB_A_LC) { /* LIST-CREDENTIALS */
14518 if ((x = cmkey(klctab,nklctab,"Switch","",xxstring)) < 0) {
14520 if ((rc = cmcfm()) < 0)
14531 } else if ((rc = cmcfm()) < 0) /* DESTROY, just confirm */
14534 /* Done - Move confirmed data to final locations */
14536 krb_action = tmp_action; /* Action requested */
14537 krb_op.version = kv; /* Kerberos version */
14538 krb_op.cache = tmpcache; /* Cache file */
14539 tmpcache = NULL; /* So we don't free it */
14541 switch (krb_action) {
14542 case KRB_A_IN: /* INITIALIZE */
14544 krb5_init.forwardable = pv[KRB_I_FW].ival;
14545 krb5_init.proxiable = pv[KRB_I_PR].ival;
14546 krb5_init.lifetime = pv[KRB_I_LF].ival;
14547 krb5_init.renew = pv[KRB_I_RN].ival;
14548 krb5_init.renewable = pv[KRB_I_RB].ival;
14549 krb5_init.validate = pv[KRB_I_VA].ival;
14551 /* Here we just reassign the pointers and then set them to NULL */
14552 /* so they won't be freed below. */
14554 krb5_init.postdate = pv[KRB_I_PD].sval; pv[KRB_I_PD].sval = NULL;
14555 krb5_init.service = pv[KRB_I_SR].sval; pv[KRB_I_SR].sval = NULL;
14556 if (pv[KRB_I_RL].sval) {
14557 krb5_init.realm = pv[KRB_I_RL].sval; pv[KRB_I_RL].sval = NULL;
14558 } else if (tmprealm) {
14559 krb5_init.realm = tmprealm; tmprealm = NULL;
14561 if (pv[KRB_I_IN].sval) {
14562 krb5_init.instance = pv[KRB_I_IN].sval;
14563 pv[KRB_I_IN].sval = NULL;
14564 } else if ( tmpinst ) {
14565 krb5_init.instance = tmpinst;
14569 krb5_init.principal = tmpprinz;
14572 krb5_init.password = tmppswd;
14575 krb5_init.getk4 = pv[KRB_I_K4].ival;
14576 if (krb5_init.getk4) {
14577 krb4_init.lifetime = pv[KRB_I_LF].ival;
14578 if (krb5_init.realm)
14579 makestr(&krb4_init.realm,krb5_init.realm);
14580 krb4_init.preauth = krb4_d_preauth;
14581 krb4_init.verbose = pv[KRB_I_BR].ival ? 0 : 1;
14582 if (krb5_init.principal)
14583 makestr(&krb4_init.principal,krb5_init.principal);
14584 if (krb5_init.principal)
14585 makestr(&krb4_init.password,krb5_init.password);
14587 krb5_init.no_addresses = pv[KRB_I_NAD].ival;
14589 for (i = 0; i < KRB5_NUM_OF_ADDRS; i++) {
14590 if (krb5_init.addrs[i]) {
14591 free(krb5_init.addrs[i]);
14592 krb5_init.addrs[i] = NULL;
14594 krb5_init.addrs[i] = tmpaddrs[i];
14595 tmpaddrs[i] = NULL;
14598 } else if (kv == 4) { /* Same deal for Kerberos 4 */
14599 krb4_init.lifetime = pv[KRB_I_LF].ival;
14600 if (pv[KRB_I_RL].sval) {
14601 krb4_init.realm = pv[KRB_I_RL].sval;
14602 pv[KRB_I_RL].sval = NULL;
14603 } else if ( tmprealm ) {
14604 krb4_init.realm = tmprealm;
14607 if (pv[KRB_I_IN].sval) {
14608 krb4_init.instance = pv[KRB_I_IN].sval;
14609 pv[KRB_I_IN].sval = NULL;
14610 } else if ( tmpinst ) {
14611 krb4_init.instance = tmpinst;
14614 krb4_init.preauth = pv[KRB_I_PA].ival;
14615 krb4_init.verbose = pv[KRB_I_BR].ival ? 0 : 1;
14618 krb4_init.principal = tmpprinz;
14621 krb4_init.password = tmppswd;
14625 case KRB_A_LC: /* List Credentials */
14626 krb5_lc.encryption = tmp_klc & XYKLCEN;
14627 krb5_lc.flags = tmp_klc & XYKLCFL;
14628 krb5_lc.addr = tmp_klc & XYKLCAD;
14632 /* Common exit - Free temporary storage */
14635 for (i = 0; i <= KRB_I_MAX; i++) { /* Free malloc'd switch data */
14639 for (i = 0; i < KRB5_NUM_OF_ADDRS; i++) {
14643 if (tmpprinz) free(tmpprinz); /* And these too. */
14644 if (tmppswd) free(tmppswd);
14645 if (tmpcache) free(tmpcache);
14646 if (tmprealm) free(tmprealm);
14647 if (tmpinst) free(tmpinst);
14649 return(rc); /* Return the return code */
14651 #endif /* CK_KERBEROS */
14656 ckxlogin(CHAR * userid, CHAR * passwd, CHAR * acct, int promptok)
14657 #else /* CK_ANSIC */
14658 ckxlogin(userid, passwd, acct, promptok)
14659 CHAR * userid; CHAR * passwd; CHAR * acct; int promptok;
14660 #endif /* CK_ANSIC */
14663 extern int on_recall; /* around Password prompting */
14664 #endif /* CK_RECALL */
14667 #endif /* COMMENT */
14668 int rprompt = 0; /* Restore prompt */
14671 #endif /* CKSYSLOG */
14673 extern int what, srvcdmsg;
14675 int x = 0, ok = 0, rc = 0;
14676 CHAR * _u = NULL, * _p = NULL, * _a = NULL;
14678 debug(F111,"ckxlogin userid",userid,promptok);
14679 debug(F110,"ckxlogin passwd",passwd,0);
14681 isguest = 0; /* Global "anonymous" flag */
14683 if (!userid) userid = (CHAR *)"";
14684 if (!passwd) passwd = (CHAR *)"";
14686 debug(F111,"ckxlogin userid",userid,what);
14690 #endif /* CK_RECALL */
14693 savlog = ckxsyslog; /* Save and turn off syslogging */
14694 #endif /* CKSYSLOG */
14696 if ((!*userid || !*passwd) && /* Need to prompt for missing info */
14698 cmsavp(psave,PROMPTL); /* Save old prompt */
14699 debug(F110,"ckxlogin saved",psave,0);
14705 cmsetp("Username: "); /* Make new prompt */
14706 concb((char)escape); /* Put console in cbreak mode */
14709 /* Flush typeahead */
14713 "ckxlogin TELOPT_SB(TELOPT_KERMIT).kermit.me_start",
14715 TELOPT_SB(TELOPT_KERMIT).kermit.me_start
14717 #endif /* IKS_OPTION */
14719 while (ttchk() > 0) {
14721 debug(F101,"ckxlogin flush user x","",x);
14723 doexit(GOOD_EXIT,0); /* Connection lost */
14727 x = tn_doop((CHAR)(x & 0xff),ckxech,ttinc);
14728 debug(F101,"ckxlogin user tn_doop","",x);
14731 "ckxlogin user TELOPT_SB(TELOPT_KERMIT).kermit.me_start",
14733 TELOPT_SB(TELOPT_KERMIT).kermit.me_start
14735 #endif /* IKS_OPTION */
14740 case 1: ckxech = 1; break; /* Turn on echoing */
14741 case 2: ckxech = 0; break; /* Turn off echoing */
14743 case 4: /* IKS event */
14744 if (!TELOPT_SB(TELOPT_KERMIT).kermit.me_start)
14745 break; /* else fall thru... */
14746 #endif /* IKS_OPTION */
14747 case 6: /* Logout */
14752 #endif /* TNCODE */
14754 if (pflag) prompt(xxstring); /* Issue prompt if at top level */
14755 cmres(); /* Reset the parser */
14756 for (x = -1; x < 0;) { /* Prompt till they answer */
14757 /* Get a literal line of text */
14758 x=cmtxt("Your username, or \"ftp\", or \"anonymous\"","",&s,NULL);
14759 if (x == -4 || x == -10) {
14760 printf("\r\n%sLogin cancelled\n",
14761 x == -10 ? "Timed out: " : "");
14763 ckxsyslog = savlog;
14764 #endif /* CKSYSLOG */
14765 doexit(GOOD_EXIT,0);
14767 if (sstate) /* Did a packet come instead? */
14769 cmres(); /* Reset the parser again */
14771 if ((_u = (CHAR *)malloc((int)strlen(s) + 1)) == NULL) {
14772 printf("?Internal error: malloc\n");
14775 strcpy((char *)_u,s); /* safe */
14779 ok = zvuser((char *)userid); /* Verify username */
14780 debug(F111,"ckxlogin zvuser",userid,ok);
14782 if (!*passwd && promptok
14785 #endif /* COMMENT */
14790 savlog = ckxsyslog; /* Save and turn off syslogging */
14792 #endif /* CKSYSLOG */
14794 /* Flush typeahead again */
14796 while (ttchk() > 0) {
14798 debug(F101,"ckxlogin flush user x","",x);
14802 x = tn_doop((CHAR)(x & 0xff),ckxech,ttinc);
14803 debug(F101,"ckxlogin pass tn_doop","",x);
14806 "ckxlogin pass TELOPT_SB(TELOPT_KERMIT).kermit.me_start",
14808 TELOPT_SB(TELOPT_KERMIT).kermit.me_start
14810 #endif /* IKS_OPTION */
14814 case 1: ckxech = 1; break; /* Turn on echoing */
14815 case 2: ckxech = 0; break; /* Turn off echoing */
14816 case 4: /* IKS event */
14817 if (!TELOPT_SB(TELOPT_KERMIT).kermit.me_start)
14818 break; /* else fall thru... */
14819 case 6: /* Logout */
14824 #endif /* TNCODE */
14826 if (!strcmp((char *)userid,"anonymous") ||
14827 !strcmp((char *)userid,"ftp")) {
14830 ckstrncpy(prmpt,"Enter e-mail address as Password: ",80);
14831 } else if (*userid && strlen((char *)userid) < 60) {
14833 extern CHAR * pReferenceDomainName;
14834 if (pReferenceDomainName)
14838 pReferenceDomainName,
14842 NULL,NULL,NULL,NULL,NULL,NULL,NULL
14846 ckmakmsg(prmpt,80,"Enter ",(char *)userid,"'s Password: ",NULL);
14848 ckstrncpy(prmpt,"Enter Password: ",80);
14849 cmsetp(prmpt); /* Make new prompt */
14850 concb((char)escape); /* Put console in cbreak mode */
14851 if (strcmp((char *)userid,"anonymous") &&
14852 strcmp((char *)userid,"ftp")) { /* and if not anonymous */
14854 cmini(0); /* and no-echo mode */
14858 if (pflag) prompt(xxstring); /* Issue prompt if at top level */
14859 cmres(); /* Reset the parser */
14860 for (x = -1; x < 0;) { /* Prompt till they answer */
14863 #endif /* CK_PAM */
14864 x = cmtxt("","",&s,NULL); /* Get a literal line of text */
14865 if (x == -4 || x == -10) {
14866 printf("\r\n%sLogin cancelled\n",
14867 x == -10 ? "Timed out: " : "");
14869 ckxsyslog = savlog;
14870 #endif /* CKSYSLOG */
14871 doexit(GOOD_EXIT,0);
14876 #endif /* CK_PAM */
14877 if (sstate) /* In case of a Kermit packet */
14879 cmres(); /* Reset the parser again */
14881 printf("\r\n"); /* Echo a CRLF */
14882 if ((_p = (CHAR *)malloc((int)strlen(s) + 1)) == NULL) {
14883 printf("?Internal error: malloc\n");
14886 strcpy((char *)_p,s); /* safe */
14892 cmres(); /* Reset the parser */
14894 /* We restore the prompt now because the PAM engine will call */
14895 /* readpass() which will overwrite psave. */
14897 cmsetp(psave); /* Restore original prompt */
14898 debug(F110,"ckxlogin restored",psave,0);
14902 #endif /* CK_PAM */
14905 ckxsyslog = savlog;
14906 #endif /* CKSYSLOG */
14909 ok = zvpass((char *)passwd); /* Check password */
14910 debug(F101,"ckxlogin zvpass","",ok);
14913 /* Fake pam password failure for nonexistent users */
14915 printf("Authentication failure\n");
14919 if (ok > 0 && isguest) {
14922 #endif /* NOPUSH */
14925 rc = ok; /* Set the return code */
14926 if ((char *)uidbuf != (char *)userid)
14927 ckstrncpy(uidbuf,(char *)userid,UIDBUFLEN); /* Remember username */
14929 XCKXLOG: /* Common exit */
14931 ckxsyslog = savlog; /* In case of GOTO above */
14932 #endif /* CKSYSLOG */
14934 cmsetp(psave); /* Restore original prompt */
14935 debug(F110,"ckxlogin restored",psave,0);
14937 if (_u || _p || _a) {
14947 doexit(GOOD_EXIT,0); /* doexit calls zvlogout */
14948 return(0); /* not reached */
14950 #endif /* CK_LOGIN */