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 extern struct mtab *mactab;
108 extern short ctlp[]; /* Control-char prefixing table */
109 #endif /* CK_SPEED */
112 extern char * sndfilter, * g_sfilter;
113 extern char * rcvfilter, * g_rfilter;
114 #endif /* PIPESEND */
116 extern char * snd_move;
117 extern char * snd_rename;
118 extern char * g_snd_move;
119 extern char * g_snd_rename;
120 extern char * rcv_move;
121 extern char * rcv_rename;
122 extern char * g_rcv_move;
123 extern char * g_rcv_rename;
126 extern char *binpatterns[], *txtpatterns[];
128 #endif /* PATTERNS */
130 extern char * remdest;
133 #endif /* CK_TMPDIR */
135 extern struct ck_p ptab[];
137 extern int protocol, remfile, rempipe, remappd, reliable, xreliable, fmask,
138 fncnv, frecl, maxrps, wslotr, bigsbsiz, bigrbsiz, urpsiz, rpsiz, spsiz,
139 bctr, npad, timef, timint, spsizr, spsizf, maxsps, spmax, nfils, displa,
140 atcapr, pkttim, rtimo, fncact, mypadn, fdispla, f_save, pktpaus, setreliable,
141 fnrpath, fnspath, atenci, atenco, atdati, atdato, atleni, atleno, atblki,
142 atblko, attypi, attypo, atsidi, atsido, atsysi, atsyso, atdisi, atdiso;
146 extern int atfrmi, atfrmo;
148 extern int atcrei, atcreo, atacti, atacto;
151 extern int atlpri, atlpro, atgpri, atgpro;
152 #endif /* CK_PERMS */
155 sstate, eol, seol, stchr, mystch, mypadc, padch, ctlq, myctlq;
161 #endif /* IKSDCONF */
164 extern char *cmarg, *cmarg2;
167 extern char optbuf[]; /* Buffer for MAIL or PRINT options */
168 extern int rprintf; /* REMOTE PRINT flag */
169 #endif /* NOFRILLS */
173 extern char * tt_trigger[];
174 #endif /* CK_TRIGGER */
176 extern int tcs_transp;
178 extern int tt_pcterm;
186 int sl_ssh_xfw_saved = 0;
188 int sl_ssh_ver_saved = 0;
189 #endif /* SSHBUILTIN */
191 #ifdef CK_AUTHENTICATION
192 extern int auth_type_user[];
193 int sl_auth_type_user[AUTHTYPLSTSZ] = {AUTHTYPE_NULL, AUTHTYPE_NULL};
194 int sl_auth_saved = 0;
195 int sl_topt_a_su = 0;
196 int sl_topt_a_s_saved = 0;
197 int sl_topt_a_cm = 0;
198 int sl_topt_a_c_saved = 0;
199 #endif /* CK_AUTHENTICATION */
204 int sl_topt_e_su = 0;
205 int sl_topt_e_sm = 0;
206 int sl_topt_e_s_saved = 0;
207 int sl_topt_e_cu = 0;
208 int sl_topt_e_cm = 0;
209 int sl_topt_e_c_saved = 0;
210 #endif /* CK_ENCRYPTION */
211 extern char uidbuf[];
212 static int uidflag = 0;
213 char sl_uidbuf[UIDBUFLEN] = { NUL, NUL };
214 int sl_uid_saved = 0;
221 extern int tn_wait_flg;
226 #ifdef CK_AUTHENTICATION
229 for (x = 0; x < AUTHTYPLSTSZ; x++)
230 auth_type_user[x] = sl_auth_type_user[x];
233 if (sl_topt_a_s_saved) {
234 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = sl_topt_a_su;
235 sl_topt_a_s_saved = 0;
237 if (sl_topt_a_c_saved) {
238 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = sl_topt_a_cm;
239 sl_topt_a_c_saved = 0;
241 #endif /* CK_AUTHENTICATION */
244 cx_type = sl_cx_type;
247 if (sl_topt_e_s_saved) {
248 TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = sl_topt_e_su;
249 TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = sl_topt_e_sm;
250 sl_topt_e_s_saved = 0;
252 if (sl_topt_e_c_saved) {
253 TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = sl_topt_e_cu;
254 TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = sl_topt_e_cm;
255 sl_topt_e_c_saved = 0;
257 #endif /* CK_ENCRYPTION */
259 ckstrncpy(uidbuf,sl_uidbuf,UIDBUFLEN);
264 tn_wait_flg = sl_tn_wait;
269 if (sl_ssh_xfw_saved) {
270 ssh_xfw = sl_ssh_xfw;
271 sl_ssh_xfw_saved = 0;
273 if (sl_ssh_ver_saved) {
274 ssh_ver = sl_ssh_ver;
275 sl_ssh_ver_saved = 0;
277 #endif /* SSHBUILTIN */
280 int oldplex = -1; /* Duplex holder around network */
284 extern int locus, autolocus;
290 /* Note: gcc -Wall wants braces around each keyword table entry. */
292 static struct keytab psltab[] = { /* SET LINE/PORT command options */
293 { "/connect", SL_CNX, 0 },
295 { "/noshare", SL_NSH, 0 },
296 #endif /* OS2ORVMS */
297 { "/server", SL_SRV, 0 },
299 { "/share", SL_SHR, 0 },
300 #endif /* OS2ORVMS */
303 static int npsltab = sizeof(psltab)/sizeof(struct keytab) - 1;
306 static struct keytab shtab[] = { /* SET HOST command options */
308 /* (COMMAND is also a network type) */
309 { "/command", SL_CMD, CM_INV },
311 { "/connect", SL_CNX, 0 },
312 { "/network-type", SL_NET, CM_ARG },
313 { "/nowait", SL_NOWAIT, 0 },
315 #ifdef CK_AUTHENTICATION
316 { "/password", SL_PSW, CM_ARG },
317 #endif /* CK_AUTHENTICATION */
320 { "/pipe", SL_CMD, 0 },
323 { "/pty", SL_PTY, 0 },
325 { "/server", SL_SRV, 0 },
326 { "/timeout", SL_TMO, CM_ARG },
327 { "/userid", SL_UID, CM_ARG },
328 { "/wait", SL_WAIT, 0 },
331 static int nshtab = sizeof(shtab)/sizeof(struct keytab) - 1;
333 static struct keytab shteltab[] = { /* TELNET command options */
334 #ifdef CK_AUTHENTICATION
335 { "/auth", SL_AUTH, CM_ARG },
336 #endif /* CK_AUTHENTICATION */
338 { "/encrypt", SL_ENC, CM_ARG },
339 #endif /* CK_ENCRYPTION */
340 { "/nowait", SL_NOWAIT, 0 },
342 #ifdef CK_AUTHENTICATION
343 { "/password", SL_PSW, CM_ARG },
344 #endif /* CK_AUTHENTICATION */
346 { "/timeout", SL_TMO, CM_ARG },
347 { "/userid", SL_UID, CM_ARG },
348 { "/wait", SL_WAIT, 0 },
351 static int nshteltab = sizeof(shteltab)/sizeof(struct keytab) - 1;
354 static struct keytab shrlgtab[] = { /* SET HOST RLOGIN command options */
357 { "/encrypt", SL_ENC, 0 },
358 #endif /* CK_ENCRYPTION */
359 { "/k4", SL_KRB4, CM_INV },
360 { "/k5", SL_KRB5, CM_INV },
361 { "/kerberos4", SL_KRB4, 0 },
362 { "/kerberos5", SL_KRB5, 0 },
363 { "/kerberos_iv", SL_KRB4, CM_INV },
364 { "/kerberos_v", SL_KRB5, CM_INV },
365 { "/krb4", SL_KRB4, CM_INV },
366 { "/krb5", SL_KRB5, CM_INV },
367 #endif /* CK_KERBEROS */
370 static int nshrlgtab = sizeof(shrlgtab)/sizeof(struct keytab)-1;
371 #endif /* RLOGCODE */
373 extern struct keytab netcmd[];
377 extern int nnetdir; /* Network services directory */
378 extern char *netdir[];
379 _PROTOTYP( VOID ndreset, (void) );
380 char *nh_p[MAXDNUMS + 1]; /* Network directory entry pointers */
381 char *nh_p2[MAXDNUMS + 1]; /* Network directory entry nettype */
382 char *nh_px[4][MAXDNUMS + 1]; /* Network-specific stuff... */
386 char * n_name = NULL; /* Network name pointer */
389 _PROTOTYP(int remtxt, (char **) );
390 _PROTOTYP(VOID rmsg, (void) );
391 _PROTOTYP(static int remcfm, (void) );
395 int mdmsav = -1; /* Save modem type around network */
396 extern int isguest; /* Global flag for anonymous login */
398 extern xx_strp xxstring;
400 extern int success, binary, b_save, ckwarn, msgflg, quiet, cmask, pflag, local,
401 nettype, escape, mdmtyp, duplex, dfloc, network, cdtimo, autoflow, tnlm,
402 sosi, tlevel, lf_opts, backgrd, flow, debses, parity, ttnproto, ckxech,
403 x_ifnum, cmflgs, haveline, cxtype, cxflow[], maclvl;
406 extern struct cmdptr *cmdstk; /* The command stack itself */
408 extern struct cmdptr cmdstk[]; /* The command stack itself */
410 extern FILE * tfile[];
411 extern char * macp[];
413 extern char psave[]; /* For saving & restoring prompt */
414 extern int sprmlen, rprmlen;
417 static struct keytab strmkeytab[] = {
421 static int nstrmkeytab = sizeof(strmkeytab)/sizeof(struct keytab);
423 static struct keytab strmswitab[] = {
426 static int nstrmswitab = sizeof(strmswitab)/sizeof(struct keytab);
428 static struct keytab normrev[] = {
429 { "dark-display", 0, 0 },
430 { "light-display", 1, 0 },
435 static struct keytab prnmtab[] = {
439 { "on", 1, CM_INV }, /* Compatibility with XPRINT version */
441 { "transparent", 3, CM_INV } /* not really transparent */
443 static int nprnmtab = sizeof(prnmtab)/sizeof(struct keytab);
445 extern int tt_diff_upd;
448 #define stricmp _stricmp
449 extern int tt_attr_bug;
451 extern int tt_rows[], tt_cols[];
452 extern int tt_cols_usr;
453 extern int tt_szchng[VNUM];
454 int tt_modechg = TVC_ENA;
455 extern int tt_url_hilite, tt_url_hilite_attr;
456 extern struct _vtG G[4];
459 int send_c1_usr = FALSE;
460 extern int sgrcolors;
461 extern int marginbell, marginbellcol;
462 extern int autoscroll, wy_autopage;
464 extern int dec_nrc, dec_lang, dec_kbd;
466 extern int tt_rows, tt_cols;
469 extern int tt_escape;
474 extern char *tp, *lp; /* Temporary buffer & pointers */
475 extern char ttname[];
478 int tttapi = 0; /* is Line TAPI? */
479 struct keytab * tapilinetab = NULL;
480 struct keytab * _tapilinetab = NULL;
484 #ifdef NETCONN /* Network items */
487 extern int revcall, closgr, cudata, nx25;
489 extern struct keytab x25tab[];
492 extern CHAR padparms[];
493 extern struct keytab padx3tab[];
500 extern bool ttslip,ttppp;
504 extern char pipename[];
508 static struct keytab tcprawtab[] = { /* SET HOST options */
509 { "/default", NP_DEFAULT, CM_INV },
510 #ifdef CK_AUTHENTICATION
513 { "/ek4login", NP_EK4LOGIN, 0 },
514 { "/ek5login", NP_EK5LOGIN, 0 },
515 { "/k4login", NP_K4LOGIN, 0 },
516 { "/k5login", NP_K5LOGIN, 0 },
517 #endif /* RLOGCODE */
519 { "/k5user2user", NP_K5U2U, 0 },
520 #endif /* KRB5_U2U */
521 #endif /* CK_KERBEROS */
522 #endif /* CK_AUTHENTICATION */
523 { "/no-telnet-init", NP_NONE, 0 },
524 { "/none", NP_NONE, CM_INV },
525 { "/raw-socket", NP_TCPRAW, 0 },
527 { "/rlogin", NP_RLOGIN, 0 },
528 #endif /* RLOGCODE */
530 { "/ssl", NP_SSL, 0 },
531 { "/ssl-telnet", NP_SSL_TELNET, 0 },
533 { "/telnet", NP_TELNET, 0 },
535 { "/tls", NP_TLS, 0 },
536 { "/tls-telnet", NP_TLS_TELNET, 0 },
540 static int ntcpraw = (sizeof(tcprawtab) / sizeof(struct keytab)) - 1;
543 _PROTOTYP( int rlog_naws, (void) );
544 #endif /* RLOGCODE */
545 #endif /* TCPSOCKET */
548 extern char slat_pwd[18];
549 #endif /* SUPERLAT */
556 #define mapkey(x) keymap[x]
558 extern MACRO *macrotab;
560 extern struct keytab kverbs[];
562 #endif /* NOKVERBS */
563 #endif /* NOSETKEY */
567 extern MACRO *macrotab;
569 extern struct keytab kverbs[];
571 #endif /* NOKVERBS */
572 #endif /* NOSETKEY */
575 #ifdef OS2 /* AUTODOWNLOAD parameters */
576 extern int adl_kmode, adl_zmode; /* Match Packet to signal download */
577 extern char * adl_kstr; /* KERMIT Download String */
578 extern char * adl_zstr; /* ZMODEM Download String */
579 extern int adl_kc0, adl_zc0; /* Process ADL C0s in emulation */
582 /* Keyword tables ... */
584 extern struct keytab onoff[], rltab[];
588 static struct keytab fdfltab[] = {
589 { "7bit-character-set", 7, 0 },
590 { "8bit-character-set", 8, 0 }
592 static int nfdflt = (sizeof(fdfltab) / sizeof(struct keytab));
595 /* SET FILE parameters */
597 static struct keytab filtab[] = {
600 { "binary-patterns", XYFIBP, 0 },
601 #endif /* PATTERNS */
602 { "bytesize", XYFILS, 0 },
604 { "character-set", XYFILC, 0 },
606 { "collision", XYFILX, 0 },
607 { "default", XYF_DFLT, 0 },
608 { "destination", XYFILY, 0 },
609 { "display", XYFILD, CM_INV },
611 { "download-directory", XYFILG, 0 },
612 #endif /* CK_TMPDIR */
614 { "end-of-line", XYFILA, 0 },
615 { "eol", XYFILA, CM_INV },
617 { "eof", XYFILV, 0 },
618 #endif /* CK_CTRLZ */
620 { "fastlookups", 9997, CM_INV },
621 { "incomplete", XYFILI, 0 },
623 { "inspection", XYF_INSP, CM_INV },
624 #endif /* datageneral */
626 { "label", XYFILL, 0 },
627 #endif /* CK_LABELED */
631 { "listsize", XYF_LSIZ, 0 },
635 { "names", XYFILN, 0 },
637 { "output", XYFILH, 0 },
640 { "patterns", XYFIPA, 0 },
641 #endif /* PATTERNS */
642 #ifdef COMMENT /* Not implemented (but see CHMOD) */
643 { "permissions", XYF_PRM, CM_INV },
644 { "protection", XYF_PRM, 0 },
647 { "record-length", XYFILR, 0 },
650 { "scan", XYF_INSP, 0 },
651 #endif /* datageneral */
655 { "stringspace", XYF_SSPA, 0 },
660 { "t", XYFILT, CM_INV|CM_ABR },
661 { "text-patterns", XYFITP, 0 },
662 #endif /* PATTERNS */
664 { "type", XYFILT, 0 },
666 { "ucs", XYFILU, 0 },
669 { "warning", XYFILW, CM_INV }
672 static int nfilp = (sizeof(filtab) / sizeof(struct keytab));
674 struct keytab pathtab[] = {
675 { "absolute", PATH_ABS, 0 },
676 { "none", PATH_OFF, CM_INV },
677 { "off", PATH_OFF, 0 },
678 { "on", PATH_ABS, CM_INV },
679 { "relative", PATH_REL, 0 }
681 int npathtab = (sizeof(pathtab) / sizeof(struct keytab));
683 struct keytab rpathtab[] = {
684 { "absolute", PATH_ABS, 0 },
685 { "auto", PATH_AUTO, 0 },
686 { "none", PATH_OFF, CM_INV },
687 { "off", PATH_OFF, 0 },
688 { "on", PATH_ABS, CM_INV },
689 { "relative", PATH_REL, 0 }
691 int nrpathtab = (sizeof(rpathtab) / sizeof(struct keytab));
694 struct keytab eoftab[] = { /* EOF detection method */
697 { "noctrl-z", 0, CM_INV }
699 #endif /* CK_CTRLZ */
701 struct keytab fttab[] = { /* File types for SET FILE TYPE */
702 { "ascii", XYFT_T, CM_INV },
704 { "b", XYFT_B, CM_INV|CM_ABR },
706 { "binary", XYFT_B, 0 },
708 { "block", XYFT_I, CM_INV },
709 { "image", XYFT_I, 0 },
712 { "labeled", XYFT_L, 0 },
713 #endif /* CK_LABELED */
715 { "macbinary", XYFT_M, 0 },
717 { "text", XYFT_T, 0 }
719 int nfttyp = (sizeof(fttab) / sizeof(struct keytab));
721 static struct keytab rfttab[] = { /* File types for REMOTE SET FILE */
722 { "ascii", XYFT_T, CM_INV },
723 { "binary", XYFT_B, 0 },
725 { "labeled", XYFT_L, 0 },
728 { "labeled", XYFT_L, 0 },
731 { "text", XYFT_T, 0 }
733 static int nrfttyp = (sizeof(rfttab) / sizeof(struct keytab));
740 static struct keytab zoftab[] = {
741 { "blocking", ZOF_BLK, 0 },
742 { "buffered", ZOF_BUF, 0 },
743 { "nonblocking", ZOF_NBLK, 0 },
744 { "unbuffered", ZOF_NBUF, 0 }
746 static int nzoftab = (sizeof(zoftab) / sizeof(struct keytab));
747 #endif /* OS2ORUNIX */
749 extern int query; /* Global flag for QUERY active */
753 static struct keytab vartyp[] = { /* Variable types for REMOTE QUERY */
754 { "global", (int) 'G', CM_INV },
755 { "kermit", (int) 'K', 0 },
756 { "system", (int) 'S', 0 },
757 { "user", (int) 'G', 0 }
759 static int nvartyp = (sizeof(vartyp) / sizeof(struct keytab));
764 static struct keytab timotab[] = { /* Timer types */
768 #endif /* CK_TIMERS */
771 extern char *atxbuf, *atmbuf; /* Atom buffer */
772 extern char *cmdbuf; /* Command buffer */
773 extern char *line, *tmpbuf; /* Character buffers for anything */
774 extern int *intime; /* INPUT TIMEOUT */
776 #else /* Not DCMDBUF ... */
778 extern char atxbuf[], atmbuf[]; /* Atom buffer */
779 extern char cmdbuf[]; /* Command buffer */
780 extern char line[], tmpbuf[]; /* Character buffer for anything */
786 extern struct keytab fcstab[]; /* For SET FILE CHARACTER-SET */
787 extern struct csinfo fcsinfo[]; /* File character set info. */
788 extern struct keytab ttcstab[];
789 extern int nfilc, fcharset, tcharset, ntermc, tcsr, tcsl, dcset7, dcset8;
794 _PROTOTYP( int os2setcp, (int) );
795 _PROTOTYP( int os2getcp, (void) );
796 _PROTOTYP( void os2debugoff, (void) );
800 extern int cmdlvl; /* Overall command level */
804 extern int *inpcas; /* INPUT CASE setting on cmd stack */
812 _PROTOTYP(int tgetent,(char *, char *));
815 _PROTOTYP(int tgetent,(char *, char *));
818 #endif /* CK_CURSES */
821 #define XMITF 0 /* SET TRANSMIT values */
822 #define XMITL 1 /* (Local to this module) */
831 extern int xmitf, xmitl, xmitp, xmitx, xmits, xmitw, xmitt;
832 char xmitbuf[XMBUFL+1] = { NUL }; /* TRANSMIT eof string */
834 struct keytab xmitab[] = { /* SET TRANSMIT */
835 { "echo", XMITX, 0 },
837 { "fill", XMITF, 0 },
838 { "linefeed", XMITL, 0 },
839 { "locking-shift", XMITS, 0 },
840 { "pause", XMITW, 0 },
841 { "prompt", XMITP, 0 },
842 { "timeout", XMITT, 0 }
844 int nxmit = (sizeof(xmitab) / sizeof(struct keytab));
847 /* For SET FILE COLLISION */
848 /* Some of the following may be possible for some C-Kermit implementations */
849 /* but not others. Those that are not possible for your implementation */
850 /* should be ifdef'd out. */
852 struct keytab colxtab[] = { /* SET FILE COLLISION options */
854 { "append", XYFX_A, 0 }, /* append to old file */
857 { "ask", XYFX_Q, 0 }, /* ask what to do (not implemented) */
859 { "backup", XYFX_B, 0 }, /* rename old file */
861 /* This crashes Mac Kermit. */
862 { "discard", XYFX_D, 0 }, /* don't accept new file */
863 { "no-supersede", XYFX_D, CM_INV }, /* ditto (MSK compatibility) */
865 { "overwrite", XYFX_X, 0 }, /* overwrite the old file */
866 { "rename", XYFX_R, 0 }, /* rename the incoming file */
867 #ifndef MAC /* This crashes Mac Kermit. */
868 { "update", XYFX_U, 0 }, /* replace if newer */
872 int ncolx = (sizeof(colxtab) / sizeof(struct keytab)) - 1;
874 static struct keytab rfiltab[] = { /* for REMOTE SET FILE */
876 { "character-set", XYFILC, 0 },
878 { "collision", XYFILX, 0 },
879 { "incomplete", XYFILI, 0 },
880 { "names", XYFILN, 0 },
881 { "record-length", XYFILR, 0 },
882 { "type", XYFILT, 0 }
884 int nrfilp = (sizeof(rfiltab) / sizeof(struct keytab));
886 struct keytab eoltab[] = { /* File eof delimiters */
888 { "crlf", XYFA_2, 0 },
891 static int neoltab = (sizeof(eoltab) / sizeof(struct keytab));
893 struct keytab fntab[] = { /* File naming */
894 { "converted", XYFN_C, 0 },
895 { "literal", XYFN_L, 0 },
896 { "standard", XYFN_C, CM_INV }
898 int nfntab = (sizeof(fntab) / sizeof(struct keytab));
901 /* Terminal parameters table */
902 static struct keytab trmtab[] = {
904 { "answerback", XYTANS, 0 },
907 { "apc", XYTAPC, 0 },
910 { "arrow-keys", XYTARR, 0 },
913 { "at", XYTATTR, CM_INV|CM_ABR },
914 { "att", XYTATTR, CM_INV|CM_ABR },
915 { "attr", XYTATTR, CM_INV|CM_ABR },
916 { "attr-bug", XYTATTBUG, CM_INV },
919 { "attribute", XYTATTR, 0 },
923 { "autodownload", XYTAUTODL, 0, },
924 #endif /* CK_AUTODL */
927 { "autopage", XYTAPAGE, 0 },
928 { "autoscroll", XYTASCRL, 0 },
929 { "bell", XYTBEL, CM_INV },
931 { "bytesize", XYTBYT, 0 },
933 { "character-set", XYTCS, 0 },
936 { "code-page", XYTCPG, 0 },
937 { "color", XYTCOL, 0 },
938 { "controls", XYTCTRL, 0 },
940 { "cr-display", XYTCRD, 0 },
942 { "cursor", XYTCUR, 0 },
944 { "debug", XYTDEB, 0 },
946 { "dg-unix-mode", XYTUNX, 0 },
948 { "echo", XYTEC, 0 },
949 { "escape-character", XYTESC, 0 },
952 { "font", XYTFON, 0 },
955 { "font", XYTFON, 0 },
959 { "height", XYTHIG, 0 },
961 { "idle-action", XYTIACT, 0 },
962 { "idle-limit", XYTITMO, CM_INV },
963 { "idle-send", XYTIDLE, CM_INV },
964 { "idle-timeout", XYTITMO, 0 },
968 { "kbd-follows-gl/gr", XYTKBDGL, 0 },
970 { "key", XYTKEY, 0 },
971 { "keyboard-mode", XYTKBMOD, 0 },
972 { "keypad-mode", XYTKPD, 0 },
977 { "line-spacing", XYTLSP, CM_INV },
978 { "local-character-set", XYTLCS, 0 },
980 { "line-spacing", XYTLSP, 0 },
981 { "local-character-set", XYTLCS, CM_INV },
984 { "local-character-set", XYTLCS, CM_INV },
987 { "locking-shift", XYTSO, 0 },
989 { "margin-bell", XYTMBEL, 0 },
992 { "mouse", XYTMOU, CM_INV },
993 #endif /* OS2MOUSE */
994 { "newline-mode", XYTNL, 0 },
996 { "output-pacing", XYTPAC, 0 },
998 { "pcterm", XYTPCTERM, 0 },
1002 { "print", XYTPRN, 0 },
1003 #endif /* OS2ORUNIX */
1006 { "remote-character-set", XYTRCS, 0 },
1008 { "remote-character-set", XYTRCS, CM_INV },
1010 #endif /* NOCSETS */
1012 { "roll-mode", XYTROL, 0 },
1013 { "s", XYTUPD, CM_ABR|CM_INV },
1014 { "sc", XYTUPD, CM_ABR|CM_INV },
1015 { "scr", XYTUPD, CM_ABR|CM_INV },
1016 { "scree", XYTUPD, CM_ABR|CM_INV },
1017 { "screen", XYTUPD, CM_ABR|CM_INV },
1018 { "screen-", XYTUPD, CM_ABR|CM_INV },
1019 { "screen-mode", XYTSCNM, 0 },
1020 { "screen-optimize", XYTOPTI, 0 },
1021 { "screen-update", XYTUPD, 0 },
1022 { "scrollback", XYSCRS, 0 },
1023 { "send-data", XYTSEND, 0 },
1024 { "send-end-of-block", XYTSEOB, 0 },
1025 { "sgr-colors", XYTSGRC, 0 },
1026 { "sni-ch.code", XYTSNICC, 0 },
1027 { "sni-firmware-versions", XYTSNIFV, 0 },
1028 { "sni-language", XYTVTLNG, 0 },
1029 { "sni-pagemode", XYTSNIPM, CM_INV },
1030 { "sni-scrollmode", XYTSNISM, CM_INV },
1031 { "spacing-attribute-character", XYTSAC, CM_INV },
1032 { "statusline", XYTSTAT, 0 },
1033 { "tra", XYTCTS, CM_INV|CM_ABR },
1034 { "transmit-timeout", XYTCTS, 0 },
1038 { "transparent-print", XYTPRN, CM_INV },
1039 #endif /* OS2ORUNIX */
1042 { "trigger", XYTRIGGER,0 },
1043 #endif /* CK_TRIGGER */
1045 { "type", XYTTYP, 0 },
1047 { "type", XYTTYP, CM_INV },
1053 { "unicode", XYTUNI, CM_INV },
1055 #endif /* UNICODE */
1056 #endif /* NOCSETS */
1058 { "unix-mode", XYTUNX, CM_INV },
1059 { "url-highlight", XYTURLHI, 0 },
1061 { "video-change", XYTVCH, 0 },
1063 { "vt-language", XYTVTLNG, 0 },
1064 { "vt-nrc-mode", XYTVTNRC, 0 },
1066 { "width", XYTWID, 0 },
1068 { "wrap", XYTWRP, 0 },
1072 int ntrm = (sizeof(trmtab) / sizeof(struct keytab)) - 1;
1075 struct keytab termctrl[] = { /* SET TERM CONTROLS */
1079 int ntermctrl = (sizeof(termctrl) / sizeof(struct keytab));
1081 struct keytab curontab[] = { /* SET TERM CURSOR */
1083 { "noblink", 2, 0 },
1085 { "noblink", 2, CM_INV },
1090 int ncuron = (sizeof(curontab) / sizeof(struct keytab));
1092 struct keytab rolltab[] = { /* Set TERM Roll Options */
1093 { "insert", TTR_INSERT, 0 },
1094 { "keystrokes",TTR_KEYS, 0 },
1095 { "off", TTR_OVER, CM_INV },
1096 { "on", TTR_INSERT, CM_INV },
1097 { "overwrite", TTR_OVER, 0 }
1099 int nroll = (sizeof(rolltab) / sizeof(struct keytab));
1101 struct keytab rollkeytab[] = { /* Set TERM ROLL KEYSTROKES */
1102 { "ignore", TTRK_IGN, 0 },
1103 { "restore-and-send", TTRK_RST, 0 },
1104 { "send", TTRK_SND, 0 }
1106 int nrollkey = (sizeof(rollkeytab) / sizeof(struct keytab));
1114 struct keytab graphsettab[] = { /* DEC VT Graphic Sets */
1115 { "all", TT_GR_ALL, 0 },
1116 { "g0", TT_GR_G0, 0 },
1117 { "g1", TT_GR_G1, 0 },
1118 { "g2", TT_GR_G2, 0 },
1119 { "g3", TT_GR_G3, 0 },
1120 { "keyboard", TT_GR_KBD, 0 }
1122 int ngraphset = (sizeof(graphsettab) / sizeof(struct keytab));
1125 struct keytab adltab[] = { /* Autodownload Options */
1126 { "ask", TAD_ASK, 0 },
1127 { "error", TAD_ERR, 0 },
1129 { "kermit", TAD_K, 0 },
1131 { "off", TAD_OFF, 0 },
1132 { "on", TAD_ON, 0 },
1134 { "zmodem", TAD_Z, 0 },
1138 int nadltab = (sizeof(adltab) / sizeof(struct keytab)) - 1;
1140 struct keytab adlerrtab[] = { /* Autodownload Error Options */
1141 { "continue", 0, 0 },
1142 { "go", 0, CM_INV },
1145 int nadlerrtab = (sizeof(adlerrtab) / sizeof(struct keytab));
1148 struct keytab adlxtab[] = { /* Autodownload Options */
1149 { "c0-conflicts", TAD_X_C0, 0 },
1150 { "detection-method", TAD_X_DETECT, 0 },
1151 { "string", TAD_X_STR, 0 }
1153 int nadlxtab = (sizeof(adlxtab) / sizeof(struct keytab));
1155 struct keytab adldtab[] = { /* Auto-dl Detection Methods */
1156 { "packet", ADL_PACK, 0 },
1157 { "string", ADL_STR, 0 }
1159 int nadldtab = (sizeof(adldtab) / sizeof(struct keytab));
1161 struct keytab adlc0tab[] = { /* Auto-dl Detection Methods */
1162 { "ignored-by-emulator", 0, 0 },
1163 { "processed-by-emulator", 1, 0 }
1165 int nadlc0tab = (sizeof(adlc0tab) / sizeof(struct keytab));
1168 struct keytab vtlangtab[] = {
1169 { "belgian", VTL_BELGIAN , 0 },
1170 { "british", VTL_BRITISH , 0 },
1171 { "canadian", VTL_CANADIAN, 0 },
1172 { "czech", VTL_CZECH , 0 },
1173 { "danish", VTL_DANISH , 0 },
1174 { "dutch", VTL_DUTCH , 0 },
1175 { "finnish", VTL_FINNISH , 0 },
1176 { "french", VTL_FRENCH , 0 },
1177 { "french-canadian",VTL_FR_CAN , 0 },
1178 { "german", VTL_GERMAN , 0 },
1179 { "greek", VTL_GREEK , 0 },
1180 { "hebrew", VTL_HEBREW , 0 },
1181 { "hungarian", VTL_HUNGARIA, 0 },
1182 { "italian", VTL_ITALIAN , 0 },
1183 { "latin-american", VTL_LATIN_AM, 0 },
1184 { "north-american", VTL_NORTH_AM, 0 },
1185 { "norwegian", VTL_NORWEGIA, 0 },
1186 { "polish", VTL_POLISH , 0 },
1187 { "portugese", VTL_PORTUGES, 0 },
1188 { "romanian", VTL_ROMANIAN, 0 },
1189 { "russian", VTL_RUSSIAN , 0 },
1190 { "scs", VTL_SCS , CM_INV },
1191 { "slovak", VTL_SLOVAK , 0 },
1192 { "spanish", VTL_SPANISH , 0 },
1193 { "swedish", VTL_SWEDISH , 0 },
1194 { "swiss-french", VTL_SW_FR , 0 },
1195 { "swiss-german", VTL_SW_GR , 0 },
1196 { "turkish-f", VTL_TURK_F , CM_INV },
1197 { "turkish-q", VTL_TURK_Q , CM_INV }
1199 int nvtlangtab = (sizeof(vtlangtab) / sizeof(struct keytab));
1200 #endif /* NOCSETS */
1203 struct keytab crdtab[] = { /* Carriage-return display */
1207 extern int tt_crd; /* Carriage-return display variable */
1210 extern int apcstatus, apcactive;
1211 static struct keytab apctab[] = { /* Terminal APC parameters */
1212 { "no-input", APC_ON|APC_NOINP,0 },
1213 { "off", APC_OFF, 0 },
1214 { "on", APC_ON, 0 },
1215 { "unchecked", APC_ON|APC_UNCH, 0 },
1216 { "unchecked-no-input", APC_ON|APC_NOINP|APC_UNCH, 0 }
1218 int napctab = (sizeof(apctab) / sizeof(struct keytab));
1220 #endif /* NOLOCAL */
1222 extern int autodl, adl_err, adl_ask;
1224 struct keytab beltab[] = { /* Terminal bell mode */
1226 { "audible", XYB_AUD, 0 },
1227 { "none", XYB_NONE, 0 },
1229 { "audible", XYB_AUD, CM_INV },
1230 { "none", XYB_NONE, CM_INV },
1233 { "off", XYB_NONE, CM_INV },
1234 { "on", XYB_AUD, CM_INV },
1236 { "off", XYB_NONE, 0 },
1237 { "on", XYB_AUD, 0 },
1240 { "visible", XYB_VIS, 0 },
1244 int nbeltab = sizeof(beltab)/sizeof(struct keytab) - 1;
1246 int tt_unicode = 1; /* Use Unicode if possible */
1248 int tt_idlesnd_tmo = 0; /* Idle Send Timeout, disabled */
1249 char * tt_idlesnd_str = NULL; /* Idle Send String, none */
1250 char * tt_idlestr = NULL;
1251 extern int tt_idleact, tt_idlelimit;
1252 #endif /* CKTIDLE */
1257 OS/2 serial communication devices.
1259 struct keytab os2devtab[] = {
1260 { "1", 1, CM_INV }, /* Invisible synonyms, like */
1261 { "2", 2, CM_INV }, /* "set port 1" */
1268 { "com1", 1, 0 }, /* Real device names */
1277 { "slipcom1", 1, 0 }, /* For use with SLIP driver */
1278 { "slipcom2", 2, 0 }, /* shared access */
1279 { "slipcom3", 3, 0 },
1280 { "slipcom4", 4, 0 },
1281 { "slipcom5", 5, 0 },
1282 { "slipcom6", 6, 0 },
1283 { "slipcom7", 7, 0 },
1284 { "slipcom8", 8, 0 },
1285 { "pppcom1", 1, 0 }, /* For use with PPP driver */
1286 { "pppcom2", 2, 0 }, /* shared access */
1287 { "pppcom3", 3, 0 },
1288 { "pppcom4", 4, 0 },
1289 { "pppcom5", 5, 0 },
1290 { "pppcom6", 6, 0 },
1291 { "pppcom7", 7, 0 },
1293 #endif /* OS2ONLY */
1295 int nos2dev = (sizeof(os2devtab) / sizeof(struct keytab)) - 1;
1298 struct keytab os2ppptab[] = {
1300 { "1", 1, CM_INV }, /* Invisible synonyms, like */
1301 { "2", 2, CM_INV }, /* "set port 1" */
1310 { "ppp1", 1, 0 }, /* For use with PPP driver */
1311 { "ppp2", 2, 0 }, /* shared access */
1320 int nos2ppp = (sizeof(os2ppptab) / sizeof(struct keytab));
1321 #endif /* OS2ONLY */
1324 Terminal parameters that can be set by SET commands.
1325 Used by the ck?con.c terminal emulator code.
1326 For now, only used for #ifdef OS2. Should add these for Macintosh.
1328 int tt_arrow = TTK_NORM; /* Arrow key mode: normal (cursor) */
1329 int tt_keypad = TTK_NORM; /* Keypad mode: normal (numeric) */
1330 int tt_shift_keypad = 0; /* Keypad Shift mode: Off */
1331 int tt_wrap = 1; /* Terminal wrap, 1 = On */
1332 int tt_type = TT_VT320; /* Terminal type, initially VT320 */
1333 int tt_type_mode = TT_VT320; /* Terminal type set by host command */
1334 int tt_cursor = 0; /* Terminal cursor, 0 = Underline */
1335 int tt_cursor_usr = 0; /* Users Terminal cursor type */
1336 int tt_cursorena_usr = 1; /* Users Terminal cursor enabled */
1337 int tt_cursor_blink = 1; /* Terminal Cursor Blink */
1338 int tt_answer = 0; /* Terminal answerback (disabled) */
1339 int tt_scrsize[VNUM] = {512,512,512,1}; /* Terminal scrollback buffer size */
1340 int tt_roll[VNUM] = {1,1,1,1}; /* Terminal roll (on) */
1341 int tt_rkeys[VNUM] = {1,1,1,1}; /* Terminal roll keys (send) */
1342 int tt_pacing = 0; /* Terminal output-pacing (none) */
1343 int tt_ctstmo = 15; /* Terminal transmit-timeout */
1344 int tt_codepage = -1; /* Terminal code-page */
1345 int tt_update = 100; /* Terminal screen-update interval */
1346 int tt_updmode = TTU_FAST; /* Terminal screen-update mode FAST */
1349 int tt_status[VNUM] = {1,1,0,0}; /* Terminal status line displayed */
1350 int tt_status_usr[VNUM] = {1,1,0,0};
1352 extern CKFLOAT floatval;
1353 CKFLOAT tt_linespacing[VNUM] = {1.0,1.0,1.0,1.0};
1355 int tt_status[VNUM] = {1,1,0,0}; /* Terminal status line displayed */
1356 int tt_status_usr[VNUM] = {1,1,0,0};
1358 int tt_status[VNUM] = {0,0,0,0}; /* Terminal status line displayed */
1359 int tt_status_usr[VNUM] = {0,0,0,0};
1362 int tt_senddata = 0; /* Let host read terminal data */
1363 extern int wy_blockend; /* Terminal Send Data EOB type */
1364 int tt_hidattr = 1; /* Attributes are hidden */
1366 extern unsigned char colornormal, colorselect,
1367 colorunderline, colorstatus, colorhelp, colorborder,
1368 colorgraphic, colordebug, colorreverse, coloritalic;
1370 extern int trueblink, trueunderline, truereverse, trueitalic, truedim;
1372 extern int bgi, fgi;
1373 extern int scrninitialized[];
1375 struct keytab audibletab[] = { /* Terminal Bell Audible mode */
1376 { "beep", XYB_BEEP, 0 }, /* Values ORd with bell mode */
1377 { "system-sounds", XYB_SYS, 0 }
1379 int naudibletab = sizeof(audibletab)/sizeof(struct keytab);
1381 struct keytab akmtab[] = { /* Arrow key mode */
1382 { "application", TTK_APPL, 0 },
1383 { "cursor", TTK_NORM, 0 }
1385 struct keytab kpmtab[] = { /* Keypad mode */
1386 { "application", TTK_APPL, 0 },
1387 { "numeric", TTK_NORM, 0 }
1390 struct keytab ttcolmodetab[] = {
1391 { "current-color", 0, 0 },
1392 { "default-color", 1, 0 }
1394 int ncolmode = sizeof(ttcolmodetab)/sizeof(struct keytab);
1409 struct keytab ttycoltab[] = { /* Terminal Screen coloring */
1410 { "border", TTCOLBOR, 0 }, /* Screen border color */
1411 { "debug-terminal", TTCOLDEB, 0 }, /* Debug color */
1412 { "erase", TTCOLERA, 0 }, /* Erase mode */
1413 { "graphic", TTCOLGRP, 0 }, /* Graphic Color */
1414 { "help-text", TTCOLHLP, 0 }, /* Help screens */
1415 { "italic", TTCOLITA, 0 }, /* Italic Color */
1416 { "normal", TTCOLNOR, CM_INV }, /* Normal screen text */
1417 { "reset-on-esc[0m", TTCOLRES, 0 }, /* Reset on ESC [ 0 m */
1418 { "reverse-video", TTCOLREV, 0 }, /* Reverse video */
1419 { "status-line", TTCOLSTA, 0 }, /* Status line */
1420 { "selection", TTCOLSEL, 0 }, /* Selection color */
1421 { "terminal-screen", TTCOLNOR, 0 }, /* Better name than "normal" */
1422 { "underlined-text", TTCOLUND, 0 } /* Underlined text */
1424 int ncolors = (sizeof(ttycoltab) / sizeof(struct keytab));
1437 struct keytab ttyattrtab[] = {
1438 { "blink", TTATTBLI, 0 },
1439 { "dim", TTATTDIM, 0 },
1440 { "italic", TTATTITA, 0 },
1441 { "protected", TTATTPRO, 0 },
1442 { "reverse", TTATTREV, 0 },
1443 { "underline", TTATTUND, 0 }
1445 int nattrib = (sizeof(ttyattrtab) / sizeof(struct keytab));
1447 struct keytab ttyprotab[] = {
1448 { "blink", TTATTBLI, 0 },
1449 { "bold", TTATTBLD, 0 },
1450 { "dim", TTATTDIM, 0 },
1451 { "done", TTATTDONE, CM_INV },
1452 { "invisible", TTATTINV, 0 },
1453 { "italic", TTATTITA, 0 },
1454 { "normal", TTATTNOR, 0 },
1455 { "reverse", TTATTREV, 0 },
1456 { "underlined", TTATTUND, 0 }
1459 int nprotect = (sizeof(ttyprotab) / sizeof(struct keytab));
1461 struct keytab ttyseobtab[] = {
1462 { "crlf_etx", 1, 0 },
1466 struct keytab ttyclrtab[] = { /* Colors */
1471 { "darkgray", 8, CM_INV },
1474 { "lblue", 9, CM_INV },
1475 { "lcyan", 11, CM_INV },
1476 { "lgray", 7, CM_INV },
1477 { "lgreen", 10, CM_INV },
1478 { "lightblue", 9, 0 },
1479 { "lightcyan", 11, 0 },
1480 { "lightgray", 7, 0 },
1481 { "lightgreen", 10, 0 },
1482 { "lightmagenta", 13, 0 },
1483 { "lightred", 12, 0 },
1484 { "lmagenta", 13, CM_INV },
1485 { "lred", 12, CM_INV },
1486 { "magenta", 5, 0 },
1491 int nclrs = (sizeof (ttyclrtab) / sizeof (struct keytab));
1493 struct keytab ttycurtab[] = {
1494 { "full", TTC_BLOCK, 0 },
1495 { "half", TTC_HALF, 0 },
1496 { "underline", TTC_ULINE, 0 }
1500 struct keytab ttyptab[] = {
1501 { "aaa", TT_AAA, CM_INV }, /* AnnArbor */
1502 { "adm3a", TT_ADM3A, 0 }, /* LSI ADM-3A */
1503 { "adm5", TT_ADM5, 0 }, /* LSI ADM-5 */
1504 { "aixterm", TT_AIXTERM, 0 }, /* IBM AIXterm */
1505 { "annarbor", TT_AAA, 0 }, /* AnnArbor */
1506 { "ansi-bbs", TT_ANSI, 0 }, /* ANSI.SYS (BBS) */
1507 { "at386", TT_AT386, 0 }, /* Unixware ANSI */
1508 { "avatar/0+",TT_ANSI, 0 }, /* AVATAR/0+ */
1509 { "ba80", TT_BA80, 0 }, /* Nixdorf BA80 */
1510 { "be", TT_BEOS, CM_INV|CM_ABR },
1511 { "beos-ansi",TT_BEOS, CM_INV }, /* BeOS ANSI */
1512 { "beterm", TT_BEOS, 0 }, /* BeOS Terminal (as of PR2 ) */
1513 { "d200", TT_DG200, CM_INV|CM_ABR }, /* Data General DASHER 200 */
1514 { "d210", TT_DG210, CM_INV|CM_ABR }, /* Data General DASHER 210 */
1515 { "d217", TT_DG217, CM_INV|CM_ABR }, /* Data General DASHER 217 */
1516 { "dg200", TT_DG200, 0 }, /* Data General DASHER 200 */
1517 { "dg210", TT_DG210, 0 }, /* Data General DASHER 210 */
1518 { "dg217", TT_DG217, 0 }, /* Data General DASHER 217 */
1519 { "h1500", TT_HZL1500, CM_INV }, /* Hazeltine 1500 */
1520 { "h19", TT_H19, CM_INV }, /* Heath-19 */
1521 { "heath19", TT_H19, 0 }, /* Heath-19 */
1522 { "hft", TT_HFT, 0 }, /* IBM High Function Terminal */
1523 { "hp2621a", TT_HP2621, 0 }, /* HP 2621A */
1524 { "hpterm", TT_HPTERM, 0 }, /* HP TERM */
1525 { "hz1500", TT_HZL1500, 0 }, /* Hazeltine 1500 */
1526 { "ibm3151", TT_IBM31, 0 }, /* IBM 3101-xx,3161 */
1527 { "linux", TT_LINUX, 0 }, /* Linux */
1528 { "qansi", TT_QANSI, 0 }, /* QNX ANSI */
1529 { "qnx", TT_QNX, 0 }, /* QNX Console */
1530 { "scoansi", TT_SCOANSI, 0 }, /* SCO ANSI */
1531 { "sni-97801",TT_97801, 0 }, /* SNI 97801 */
1532 { "sun", TT_SUN, 0 }, /* SUN Console */
1534 The idea of NONE is to let the console driver handle the escape sequences,
1535 which, in theory at least, would give not only ANSI emulation, but also any
1536 other kind of emulation that might be provided by alternative console
1537 drivers, if any existed.
1539 For this to work, ckocon.c would need to be modified to make higher-level
1540 calls, like VioWrtTTY(), DosWrite(), or (simply) write(), rather than
1541 VioWrt*Cell() and similar, and it would also have to give up its rollback
1542 feature, and its status line and help screens would also have to be
1543 forgotten or else done in an ANSI way.
1545 As matters stand, we already have perfectly good ANSI emulation built in,
1546 and there are no alternative console drivers available, so there is no point
1547 in having a terminal type of NONE, so it is commented out. However, should
1548 you uncomment it, it will work like a "glass tty" -- no escape sequence
1549 interpretation at all; somewhat similar to debug mode, except without the
1550 debugging (no highlighting of control chars or escape sequences); help
1551 screens, status line, and rollback will still work.
1555 { "tek4014", TT_TEK40, 0 },
1556 #endif /* COMMENT */
1558 { "tty", TT_NONE, 0 },
1559 { "tvi910+", TT_TVI910, 0 },
1560 { "tvi925", TT_TVI925, 0 },
1561 { "tvi950", TT_TVI950, 0 },
1562 { "vc404", TT_VC4404, 0 },
1563 { "vc4404", TT_VC4404, CM_INV },
1564 { "vip7809", TT_VIP7809,0 },
1565 { "vt100", TT_VT100, 0 },
1566 { "vt102", TT_VT102, 0 },
1567 { "vt220", TT_VT220, 0 },
1568 { "vt220pc", TT_VT220PC,0 },
1569 { "vt320", TT_VT320, 0 },
1570 { "vt320pc", TT_VT320PC,0 },
1571 { "vt52", TT_VT52, 0 },
1573 { "vtnt", TT_VTNT, 0 },
1575 { "vtnt", TT_VTNT, CM_INV },
1577 { "wy160", TT_WY160, 0 },
1578 { "wy30", TT_WY30, 0 },
1579 { "wy370", TT_WY370, 0 },
1580 { "wy50", TT_WY50, 0 },
1581 { "wy60", TT_WY60, 0 },
1582 { "wyse30", TT_WY30, CM_INV },
1583 { "wyse370", TT_WY370, CM_INV },
1584 { "wyse50", TT_WY50, CM_INV },
1585 { "wyse60", TT_WY60, CM_INV }
1587 int nttyp = (sizeof(ttyptab) / sizeof(struct keytab));
1589 struct keytab ttkeytab[] = {
1590 { "aaa", TT_AAA, CM_INV }, /* AnnArbor */
1591 { "adm3a", TT_ADM3A, 0 }, /* LSI ADM-3A */
1592 { "adm5", TT_ADM5, 0 }, /* LSI ADM-5 */
1593 { "aixterm", TT_AIXTERM, 0 }, /* IBM AIXterm */
1594 { "annarbor", TT_AAA, 0 }, /* AnnArbor */
1595 { "ansi-bbs", TT_ANSI, 0 }, /* ANSI.SYS (BBS) */
1596 { "at386", TT_AT386, 0 }, /* Unixware ANSI */
1597 { "avatar/0+", TT_ANSI, 0 }, /* AVATAR/0+ */
1598 { "ba80", TT_BA80, 0 }, /* Nixdorf BA80 */
1599 { "be", TT_BEOS, CM_INV|CM_ABR },
1600 { "beos-ansi", TT_BEOS, CM_INV }, /* BeOS ANSI */
1601 { "beterm", TT_BEOS, 0 }, /* BeOS Terminal (DR2) */
1602 { "d200", TT_DG200, CM_INV|CM_ABR }, /* DG DASHER 200 */
1603 { "d210", TT_DG210, CM_INV|CM_ABR }, /* DG DASHER 210 */
1604 { "d217", TT_DG217, CM_INV|CM_ABR }, /* DG DASHER 217 */
1605 { "dg200", TT_DG200, 0 }, /* DG DASHER 200 */
1606 { "dg210", TT_DG210, 0 }, /* DG DASHER 210 */
1607 { "dg217", TT_DG217, 0 }, /* DG DASHER 217 */
1608 { "emacs", TT_KBM_EMACS, 0 }, /* Emacs mode */
1609 { "h19", TT_H19, CM_INV }, /* Heath-19 */
1610 { "heath19", TT_H19, 0 }, /* Heath-19 */
1611 { "hebrew", TT_KBM_HEBREW, 0 }, /* Hebrew mode */
1612 { "hft", TT_HFT, 0 }, /* IBM High Function Term */
1613 { "hp2621a", TT_HP2621, 0 }, /* HP 2621A */
1614 { "hpterm", TT_HPTERM, 0 }, /* HP TERM */
1615 { "hz1500", TT_HZL1500, 0 }, /* Hazeltine 1500 */
1616 { "ibm3151", TT_IBM31, 0 }, /* IBM 3101-xx,3161 */
1617 { "linux", TT_LINUX, 0 }, /* Linux */
1618 { "qansi", TT_QANSI, 0 }, /* QNX ANSI */
1619 { "qnx", TT_QNX, 0 }, /* QNX */
1620 { "russian", TT_KBM_RUSSIAN,0 }, /* Russian mode */
1621 { "scoansi", TT_SCOANSI, 0 }, /* SCO ANSI */
1622 { "sni-97801", TT_97801, 0 }, /* SNI 97801 */
1623 { "sun", TT_SUN, 0 }, /* SUN Console */
1626 { "tek4014", TT_TEK40, 0 },
1627 #endif /* COMMENT */
1629 { "tty", TT_NONE, 0 },
1630 { "tvi910+", TT_TVI910, 0 },
1631 { "tvi925", TT_TVI925, 0 },
1632 { "tvi950", TT_TVI950, 0 },
1633 { "vc404", TT_VC4404, 0 },
1634 { "vc4404", TT_VC4404, CM_INV },
1635 { "vip7809", TT_VIP7809, 0 },
1636 { "vt100", TT_VT100, 0 },
1637 { "vt102", TT_VT102, 0 },
1638 { "vt220", TT_VT220, 0 },
1639 { "vt220pc", TT_VT220PC, 0 },
1640 { "vt320", TT_VT320, 0 },
1641 { "vt320pc", TT_VT320PC, 0 },
1642 { "vt52", TT_VT52, 0 },
1643 { "vtnt", TT_VTNT, CM_INV },
1644 { "wp", TT_KBM_WP, 0 }, /* Word Perfect mode */
1645 { "wy160", TT_WY160, 0 },
1646 { "wy30", TT_WY30, 0 },
1647 { "wy370", TT_WY370, 0 },
1648 { "wy50", TT_WY50, 0 },
1649 { "wy60", TT_WY60, 0 },
1650 { "wyse30", TT_WY30, CM_INV },
1651 { "wyse370", TT_WY370, CM_INV },
1652 { "wyse50", TT_WY50, CM_INV },
1653 { "wyse60", TT_WY60, CM_INV }
1655 int nttkey = (sizeof(ttkeytab) / sizeof(struct keytab));
1658 struct keytab kbmodtab[] = {
1659 { "emacs", KBM_EM, 0 },
1660 { "english", KBM_EN, CM_INV },
1661 { "hebrew", KBM_HE, 0 },
1662 { "normal", KBM_EN, 0 },
1663 { "none", KBM_EN, CM_INV },
1664 { "russian", KBM_RU, 0 },
1667 int nkbmodtab = (sizeof(kbmodtab) / sizeof(struct keytab));
1668 #endif /* NOSETKEY */
1669 #endif /* NOLOCAL */
1671 int tt_inpacing = 0; /* input-pacing (none) */
1673 struct keytab prtytab[] = { /* OS/2 Priority Levels */
1674 { "foreground-server", XYP_SRV, 0 },
1675 { "idle", XYP_IDLE, CM_INV },
1676 { "regular", XYP_REG, 0 },
1677 { "time-critical", XYP_RTP, 0 }
1679 int nprty = (sizeof(prtytab) / sizeof(struct keytab));
1683 struct keytab win95tab[] = { /* Win95 work-arounds */
1684 { "8.3-filenames", XYW8_3, 0 },
1685 { "alt-gr", XYWAGR, 0 },
1686 { "horizontal-scan-line-substitutions", XYWHSL, 0 },
1687 { "keyboard-translation", XYWKEY, 0 },
1688 { "lucida-substitutions", XYWLUC, 0 },
1689 { "overlapped-io", XYWOIO, 0 },
1690 { "popups", XYWPOPUP, 0 },
1691 { "select-bug", XYWSELECT, 0 }
1693 int nwin95 = (sizeof(win95tab) / sizeof(struct keytab));
1697 extern int wideresult;
1698 int tt_mouse = 1; /* Terminal mouse on/off */
1700 struct keytab mousetab[] = { /* Mouse items */
1701 { "activate", XYM_ON, 0 },
1702 { "button", XYM_BUTTON, 0 },
1703 { "clear", XYM_CLEAR, 0 },
1704 { "debug", XYM_DEBUG, 0 }
1706 int nmtab = (sizeof(mousetab)/sizeof(struct keytab));
1708 struct keytab mousebuttontab[] = { /* event button */
1712 { "one", XYM_B1, CM_INV },
1713 { "three", XYM_B3, CM_INV },
1714 { "two", XYM_B2, CM_INV }
1716 int nmbtab = (sizeof(mousebuttontab) / sizeof(struct keytab));
1718 struct keytab mousemodtab[] = { /* event button key modifier */
1719 { "alt", XYM_ALT, 0 },
1720 { "alt-shift", XYM_SHIFT|XYM_ALT, 0 },
1721 { "ctrl", XYM_CTRL, 0 },
1722 { "ctrl-alt", XYM_CTRL|XYM_ALT, 0 },
1723 { "ctrl-alt-shift", XYM_CTRL|XYM_SHIFT|XYM_ALT, 0 },
1724 { "ctrl-shift", XYM_CTRL|XYM_SHIFT, 0 },
1726 { "shift", XYM_SHIFT, 0 }
1728 int nmmtab = (sizeof(mousemodtab) / sizeof(struct keytab));
1730 struct keytab mclicktab[] = { /* event button click modifier */
1731 { "click", XYM_C1, 0 },
1732 { "drag", XYM_DRAG, 0 },
1733 { "double-click", XYM_C2, 0 }
1735 int nmctab = (sizeof(mclicktab) / sizeof(struct keytab));
1739 extern struct keytab kverbs[];
1740 #endif /* NOKVERBS */
1741 #endif /* OS2MOUSE */
1744 struct keytab fbtab[] = { /* Binary record types for VMS */
1745 { "fixed", XYFT_B, 0 }, /* Fixed is normal for binary */
1746 { "undefined", XYFT_U, 0 } /* Undefined if they ask for it */
1748 int nfbtyp = (sizeof(fbtab) / sizeof(struct keytab));
1752 struct keytab lbltab[] = { /* Labeled File info */
1753 { "acl", LBL_ACL, 0 },
1754 { "backup-date", LBL_BCK, 0 },
1755 { "name", LBL_NAM, 0 },
1756 { "owner", LBL_OWN, 0 },
1757 { "path", LBL_PTH, 0 }
1759 int nlblp = (sizeof(lbltab) / sizeof(struct keytab));
1762 struct keytab lbltab[] = { /* Labeled File info */
1763 { "archive", LBL_ARC, 0 },
1764 { "extended", LBL_EXT, 0 },
1765 { "hidden", LBL_HID, 0 },
1766 { "read-only", LBL_RO, 0 },
1767 { "system", LBL_SYS, 0 }
1769 int nlblp = (sizeof(lbltab) / sizeof(struct keytab));
1775 static struct keytab fdftab[] = { /* SET FILE DISPLAY FULL options */
1776 { "thermometer", 1, 0, },
1777 { "no-thermometer", 0, 0 }
1779 extern int thermometer;
1780 #endif /* CK_PCT_BAR */
1781 #endif /* CK_CURSES */
1783 static struct keytab fdtab[] = { /* SET FILE DISPLAY options */
1784 #ifdef MAC /* Macintosh */
1785 { "fullscreen", XYFD_R, 0 }, /* Full-screen but not curses */
1786 { "none", XYFD_N, 0 },
1787 { "off", XYFD_N, CM_INV },
1788 { "on", XYFD_R, CM_INV },
1789 { "quiet", XYFD_N, CM_INV },
1791 { "brief", XYFD_B, 0 }, /* Brief */
1792 { "crt", XYFD_S, 0 }, /* CRT display */
1795 { "curses", XYFD_C, CM_INV }, /* Full-screen, curses */
1796 #endif /* COMMENT */
1797 { "fullscreen", XYFD_C, 0 }, /* Full-screen, whatever the method */
1798 #endif /* CK_CURSES */
1800 { "gui", XYFD_G, 0 }, /* GUI */
1802 { "none", XYFD_N, 0 }, /* No display */
1803 { "off", XYFD_N, CM_INV }, /* Ditto */
1804 { "on", XYFD_R, CM_INV }, /* On = Serial */
1805 { "quiet", XYFD_N, CM_INV }, /* No display */
1806 { "serial", XYFD_R, 0 }, /* Serial */
1810 int nfdtab = (sizeof(fdtab) / sizeof(struct keytab)) - 1;
1812 struct keytab rsrtab[] = { /* For REMOTE SET RECEIVE */
1813 { "packet-length", XYLEN, 0 },
1814 { "timeout", XYTIMO, 0 }
1816 int nrsrtab = (sizeof(rsrtab) / sizeof(struct keytab));
1818 /* Send/Receive Parameters */
1820 struct keytab srtab[] = {
1821 { "backup", XYBUP, 0 },
1823 { "character-set-selection", XYCSET, 0 },
1824 #endif /* NOCSETS */
1825 { "control-prefix", XYQCTL, 0 },
1827 { "double-character", XYDBL, 0 },
1828 #endif /* CKXXCHAR */
1829 { "end-of-packet", XYEOL, 0 },
1831 { "filter", XYFLTR, 0 },
1832 #endif /* PIPESEND */
1834 { "ignore-character", XYIGN, 0 },
1835 #endif /* CKXXCHAR */
1836 { "i-packets", 993, 0 },
1837 { "move-to", XYMOVE, 0 },
1838 { "negotiation-string-max-length", XYINIL, CM_INV },
1839 { "packet-length", XYLEN, 0 },
1840 { "pad-character", XYPADC, 0 },
1841 { "padding", XYNPAD, 0 },
1842 { "pathnames", XYFPATH, 0 },
1843 { "pause", XYPAUS, 0 },
1845 { "permissions", 994, 0}, /* 206 */
1846 #endif /* CK_PERMS */
1847 { "quote", XYQCTL, CM_INV }, /* = CONTROL-PREFIX */
1848 { "rename-to", XYRENAME, 0 },
1849 { "start-of-packet", XYMARK, 0 },
1850 { "timeout", XYTIMO, 0 },
1852 { "version-numbers", 887, 0 }, /* VMS version numbers */
1856 int nsrtab = (sizeof(srtab) / sizeof(struct keytab)) - 1;
1861 static struct keytab ucstab[] = {
1862 { "bom", UCS_BOM, 0 },
1863 { "byte-order", UCS_BYT, 0 },
1866 int nucstab = (sizeof(ucstab) / sizeof(struct keytab)) - 1;
1868 static struct keytab botab[] = {
1869 { "big-endian", 0, 0 },
1870 { "little-endian", 1, 0 }
1872 static int nbotab = 2;
1873 #endif /* UNICODE */
1877 struct keytab rmstab[] = {
1878 { "attributes", XYATTR, 0 },
1879 { "block-check", XYCHKT, 0 },
1880 { "file", XYFILE, 0 },
1881 { "incomplete", XYIFD, CM_INV }, /* = REMOTE SET FILE INCOMPLETE */
1882 { "match", XYMATCH,0 },
1883 { "receive", XYRECV, 0 },
1884 { "retry", XYRETR, 0 },
1885 { "server", XYSERV, 0 },
1886 { "transfer", XYXFER, 0 },
1887 { "window", XYWIND, 0 },
1888 { "xfer", XYXFER, CM_INV }
1890 int nrms = (sizeof(rmstab) / sizeof(struct keytab));
1892 struct keytab attrtab[] = {
1894 { "account", AT_ACCT, 0 },
1895 #endif /* STRATUS */
1896 { "all", AT_XALL, 0 },
1898 { "blocksize", AT_BLKS, 0 }, /* (not used) */
1899 #endif /* COMMENT */
1901 { "character-set", AT_ENCO, 0 },
1902 #endif /* NOCSETS */
1904 { "creator", AT_CREA, 0 },
1905 #endif /* STRATUS */
1906 { "date", AT_DATE, 0 },
1907 { "disposition", AT_DISP, 0 },
1908 { "encoding", AT_ENCO, CM_INV },
1909 { "format", AT_RECF, CM_INV },
1910 { "length", AT_LENK, 0 },
1911 { "off", AT_ALLN, 0 },
1912 { "on", AT_ALLY, 0 },
1914 { "os-specific", AT_SYSP, 0 }, /* (not used by UNIX or VMS) */
1915 #endif /* COMMENT */
1917 { "protection", AT_LPRO, 0 },
1918 { "permissions", AT_LPRO, CM_INV },
1919 #endif /* CK_PERMS */
1920 { "record-format", AT_RECF, 0 },
1921 { "system-id", AT_SYSI, 0 },
1922 { "type", AT_FTYP, 0 }
1924 int natr = (sizeof(attrtab) / sizeof(struct keytab)); /* how many attributes */
1927 struct keytab idlacts[] = {
1928 { "exit", IDLE_EXIT, 0 },
1929 { "hangup", IDLE_HANG, 0 },
1930 { "output", IDLE_OUT, 0 },
1931 { "return", IDLE_RET, 0 },
1933 { "telnet-nop", IDLE_TNOP, 0 },
1934 { "telnet-ayt", IDLE_TAYT, 0 },
1938 int nidlacts = (sizeof(idlacts) / sizeof(struct keytab)) - 1;
1939 #endif /* CKTIDLE */
1942 extern int indef, inecho, insilence, inbufsize, inautodl, inintr;
1944 extern CKFLOAT inscale;
1945 #endif /* CKFLOAT */
1946 extern char * inpbuf, * inpbp;
1950 struct keytab inptab[] = { /* SET INPUT parameters */
1952 { "autodownload", IN_ADL, 0 },
1953 #endif /* CK_AUTODL */
1954 { "buffer-length", IN_BUF, 0 },
1955 { "cancellation", IN_CAN, 0 },
1956 { "case", IN_CAS, 0 },
1957 { "default-timeout", IN_DEF, CM_INV }, /* There is no default timeout */
1958 { "echo", IN_ECH, 0 },
1960 { "pacing", IN_PAC, CM_INV },
1962 { "scale-factor", IN_SCA, 0 },
1963 { "silence", IN_SIL, 0 },
1965 { "terminal", IN_TRM, 0 },
1967 { "timeout-action", IN_TIM, 0 }
1969 int ninp = (sizeof(inptab) / sizeof(struct keytab));
1971 struct keytab intimt[] = { /* SET INPUT TIMEOUT parameters */
1972 { "proceed", 0, 0 }, /* 0 = proceed */
1973 { "quit", 1, 0 } /* 1 = quit */
1976 struct keytab incast[] = { /* SET INPUT CASE parameters */
1977 { "ignore", 0, 0 }, /* 0 = ignore */
1978 { "observe", 1, 0 } /* 1 = observe */
1982 struct keytab nabltab[] = { /* For any command that needs */
1983 { "disabled", 0, 0 },
1984 { "enabled", 1, 0 },
1985 { "off", 0, CM_INV }, /* these keywords... */
1988 int nnabltab = sizeof(nabltab) / sizeof(struct keytab);
1991 struct keytab tvctab[] = { /* SET TERM VIDEO-CHANGE */
1992 { "disabled", TVC_DIS, 0 },
1993 { "enabled", TVC_ENA, 0 },
1995 { "win95-safe", TVC_W95, 0 },
1999 int ntvctab = (sizeof(tvctab) / sizeof(struct keytab)) - 1;
2001 struct keytab msktab[] = { /* SET MS-DOS KERMIT compatibilities */
2003 { "color", MSK_COLOR, 0 },
2004 #endif /* COMMENT */
2005 { "keycodes", MSK_KEYS, 0 }
2007 int nmsk = (sizeof(msktab) / sizeof(struct keytab));
2009 struct keytab scrnupd[] = { /* SET TERMINAL SCREEN-UPDATE */
2010 { "fast", TTU_FAST, 0 },
2011 { "smooth", TTU_SMOOTH, 0 }
2013 int nscrnupd = (sizeof(scrnupd) / sizeof(struct keytab));
2016 /* This definition of the term_font[] table is only for */
2017 /* the OS/2 Full Screen Session and is not used on Windows */
2018 struct keytab term_font[] = { /* SET TERMINAL FONT */
2020 { "cp111", TTF_111, 0 },
2021 { "cp112", TTF_112, 0 },
2022 { "cp113", TTF_113, 0 },
2023 #endif /* COMMENT */
2024 { "cp437", TTF_437, 0 },
2025 { "cp850", TTF_850, 0 },
2027 { "cp851", TTF_851, 0 },
2028 #endif /* COMMENT */
2029 { "cp852", TTF_852, 0 },
2031 { "cp853", TTF_853, 0 },
2032 { "cp860", TTF_860, 0 },
2033 { "cp861", TTF_861, 0 },
2034 #endif /* COMMENT */
2035 { "cp862", TTF_862, 0 },
2037 { "cp863", TTF_863, 0 },
2038 { "cp864", TTF_864, 0 },
2039 { "cp865", TTF_865, 0 },
2040 #endif /* COMMENT */
2041 { "cp866", TTF_866, 0 },
2043 { "cp880", TTF_880, 0 },
2044 { "cp881", TTF_881, 0 },
2045 { "cp882", TTF_882, 0 },
2046 { "cp883", TTF_883, 0 },
2047 { "cp884", TTF_884, 0 },
2048 { "cp885", TTF_885, 0 },
2049 #endif /* COMMENT */
2050 { "default",TTF_ROM,0 }
2052 int ntermfont = (sizeof(term_font) / sizeof(struct keytab));
2053 int tt_font = TTF_ROM; /* Terminal screen font */
2057 struct keytab * term_font = NULL;
2058 struct keytab * _term_font = NULL;
2059 char * tt_facename = NULL;
2062 int tt_font_size = 0;
2065 #endif /* PCFONTS */
2067 struct keytab anbktab[] = { /* For any command that needs */
2068 { "message", 2, 0 }, /* these keywords... */
2071 { "unsafe-messag0", 99, CM_INV },
2072 { "unsafe-message", 3, CM_INV }
2074 int nansbk = (sizeof(anbktab) / sizeof(struct keytab));
2076 int win95_popup = 1;
2079 int win95lucida = 0;
2082 int win95lucida = 1;
2086 int win95lucida = 0;
2091 extern int win95selectbug;
2092 extern int win95_8_3;
2095 extern CHAR (*xlr[MAXTCSETS+1][MAXFCSETS+1])(CHAR);
2096 extern struct keytab tcstab[];
2098 #endif /* COMMENT */
2099 extern int maxow, maxow_usr; owwait; /* Overlapped I/O variables */
2104 /* The following routines broken out of doprm() to give compilers a break. */
2106 /* S E T O N -- Parse on/off (default on), set parameter to result */
2109 seton(prm) int *prm; {
2111 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
2112 if ((x = cmcfm()) < 0) return(x);
2117 /* S E T O N A U T O -- Parse on/off/auto (default auto) & set result */
2119 struct keytab onoffaut[] = {
2120 { "auto", SET_AUTO, 0 }, /* 2 */
2121 { "off", SET_OFF, 0 }, /* 0 */
2122 { "on", SET_ON, 0 } /* 1 */
2126 setonaut(prm) int *prm; {
2128 if ((y = cmkey(onoffaut,3,"","auto",xxstring)) < 0) return(y);
2129 if ((x = cmcfm()) < 0) return(x);
2134 /* S E T N U M -- Set parameter to result of cmnum() parse. */
2136 Call with pointer to integer variable to be set,
2137 x = number from cnum parse, y = return code from cmnum,
2138 max = maximum value to accept, -1 if no maximum.
2139 Returns -9 on failure, after printing a message, or 1 on success.
2142 setnum(prm,x,y,max) int x, y, *prm, max; {
2143 debug(F101,"setnum","",y);
2145 printf("\n?Value required\n");
2149 printf("%s?Not a number: %s\n",cmflgs == 1 ? "" : "\n", atxbuf);
2152 if (y < 0) return(y);
2153 if (max > -1 && x > max) {
2154 printf("?Sorry, %d is the maximum\n",max);
2157 if ((y = cmcfm()) < 0) return(y);
2162 /* S E T C C -- Set parameter var to an ASCII control character value. */
2164 Parses a number, or a literal control character, or a caret (^) followed
2165 by an ASCII character whose value is 63-95 or 97-122, then gets confirmation,
2166 then sets the parameter to the code value of the character given. If there
2167 are any parse errors, they are returned, otherwise on success 1 is returned.
2170 setcc(dflt,var) char *dflt; int *var; {
2173 char *hlpmsg = "Control character,\n\
2174 numeric ASCII value,\n\
2175 or in ^X notation,\n\
2176 or preceded by a backslash and entered literally";
2178 /* This is a hack to turn off complaints from expression evaluator. */
2180 y = cmnum(hlpmsg, dflt, 10, &x, xxstring); /* Parse a number */
2181 x_ifnum = 0; /* Allow complaints again */
2182 if (y < 0) { /* Parse failed */
2183 if (y != -2) /* Reparse needed or somesuch */
2184 return(y); /* Pass failure back up the chain */
2186 /* Real control character or literal 8-bit character... */
2188 for (c = strlen(atmbuf) - 1; c > 0; c--) /* Trim */
2189 if (atmbuf[c] == SP) atmbuf[c] = NUL;
2191 if (y < 0) { /* It was not a number */
2192 if (((c = atmbuf[0])) && !atmbuf[1]) { /* Literal character? */
2194 if (((c > 31) && (c < 127)) || (c > 255)) {
2195 printf("\n?%d: Out of range - must be 0-31 or 127-255\n",c);
2198 if ((y = cmcfm()) < 0) /* Confirm */
2200 *var = c; /* Set the variable */
2203 } else if (atmbuf[0] == '^' && !atmbuf[2]) { /* Or ^X notation? */
2205 if (islower((char) c)) /* Uppercase lowercase letters */
2207 if (c > 62 && c < 96) { /* Check range */
2208 if ((y = cmcfm()) < 0)
2210 *var = ctl(c); /* OK */
2213 printf("?Not a control character - %s\n", atmbuf);
2216 } else { /* Something illegal was typed */
2217 printf("?Invalid - %s\n", atmbuf);
2221 if (((x > 31) && (x < 127)) || (x > 255)) { /* They typed a number */
2222 printf("\n?%d: Out of range - must be 0-31 or 127-255\n",x);
2225 if ((y = cmcfm()) < 0) /* In range, confirm */
2227 *var = x; /* Set variable */
2231 #ifndef NOSPL /* The SORT command... */
2233 static struct keytab srtswtab[] = { /* SORT command switches */
2234 { "/case", SRT_CAS, CM_ARG },
2235 { "/key", SRT_KEY, CM_ARG },
2236 { "/numeric", SRT_NUM, 0 },
2237 { "/range", SRT_RNG, CM_ARG },
2238 { "/reverse", SRT_REV, 0 }
2240 static int nsrtswtab = sizeof(srtswtab)/sizeof(struct keytab);
2242 extern char **a_ptr[]; /* Array pointers */
2243 extern int a_dim[]; /* Array dimensions */
2246 dosort() { /* Do the SORT command */
2247 char c, *p = NULL, ** ap, ** xp = NULL;
2248 struct FDB sw, fl, cm;
2250 int xn = 0, xr = -1, xk = -1, xc = -1, xs = 0;
2251 int getval = 0, range[2], confirmed = 0;
2253 cmfdbi(&sw, /* First FDB - command switches */
2255 "Array name or switch",
2257 "", /* addtl string data */
2258 nsrtswtab, /* addtl numeric data 1: tbl size */
2259 4, /* addtl numeric data 2: 4 = cmswi */
2260 NULL, /* Processing function */
2261 srtswtab, /* Keyword table */
2262 &fl /* Pointer to next FDB */
2264 cmfdbi(&fl, /* Anything that doesn't match */
2266 "Array name", /* hlpmsg */
2268 "", /* addtl string data */
2269 0, /* addtl numeric data 1 */
2270 0, /* addtl numeric data 2 */
2275 cmfdbi(&cm, /* Or premature confirmation */
2279 "", /* addtl string data */
2280 0, /* addtl numeric data 1 */
2281 0, /* addtl numeric data 2 */
2290 while (1) { /* Parse 0 or more switches */
2294 if (cmresult.fcode != _CMKEY) /* Break out if not a switch */
2297 getval = (c == ':' || c == '=');
2298 if (getval && !(cmresult.kflags & CM_ARG)) {
2299 printf("?This switch does not take arguments\n");
2302 switch (cmresult.nresult) {
2308 if ((y = cmnum("Column for comparison (1-based)",
2309 "1",10,&x,xxstring)) < 0)
2317 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0)
2323 case SRT_RNG: /* /RANGE */
2329 if ((y = cmfld("low:high element","1",&s,NULL)) < 0)
2332 ckstrncpy(buf,s,32);
2334 for (i = 0; *p && i < 2; i++) { /* Get low and high */
2335 q = p; /* Start of this piece */
2336 while (*p) { /* Find end of this piece */
2344 y = 15; /* Evaluate this piece */
2348 if (s) if (*s) ckstrncpy(buf2,s,16);
2349 if (!rdigits(buf2)) {
2350 printf("?Not numeric: %s\n",buf2);
2353 range[i] = atoi(buf2);
2357 case SRT_NUM: /* /NUMERIC */
2364 switch (cmresult.fcode) {
2369 ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Safe copy of name */
2373 printf("?Unexpected function code: %d\n",cmresult.fcode);
2377 printf("?Array name required\n");
2380 ckmakmsg(tmpbuf,TMPBUFSIZ,
2381 "Second array to sort according to ",s,NULL,NULL);
2382 if ((x = cmfld(tmpbuf,"",&p,NULL)) < 0)
2386 ckstrncpy(tmpbuf,p,TMPBUFSIZ);
2388 if ((x = cmcfm()) < 0) /* Get confirmation */
2391 x = arraybounds(s,&lo,&hi); /* Get array index & bounds */
2392 if (x < 0) { /* Check */
2393 printf("?Bad array name: %s\n",s);
2396 if (lo > -1) range[0] = lo; /* Set range */
2397 if (hi > -1) range[1] = hi;
2398 ap = a_ptr[x]; /* Get pointer to array element list */
2399 if (!ap) { /* Check */
2400 printf("?Array not declared: %s\n", s);
2403 if (range[0] < 0) /* Starting element */
2405 if (range[1] < 0) /* Final element */
2406 range[1] = a_dim[x];
2407 if (range[1] > a_dim[x]) {
2408 printf("?range %d:%d exceeds array dimension %d\n",
2409 range[0],range[1],a_dim[x]
2414 xs = range[1] - range[0] + 1; /* Number of elements to sort */
2415 if (xs < 1) { /* Check */
2416 printf("?Bad range: %d:%d\n",range[0],range[1]);
2419 if (xk < 0) xk = 0; /* Key position */
2420 if (xr < 0) xr = 0; /* Reverse flag */
2421 if (xn) /* Numeric flag */
2423 else if (xc < 0) /* Not numeric */
2424 xc = inpcas[cmdlvl]; /* so alpha case option */
2426 if (*p) { /* Parallel array given? */
2427 y = xarray(p); /* Yes, get its index. */
2429 printf("?Bad array name: %s\n", p);
2432 if (y != x) { /* If the 2 arrays are different */
2433 xp = a_ptr[y]; /* Pointer to 2nd array element list */
2435 printf("?Array not declared: %s\n", p);
2438 if (a_dim[y] < range[1]) {
2439 printf("?Array %s smaller than %s\n", p, s);
2442 xp += range[0]; /* Set base to same as 1st array */
2445 sh_sort(ap,xp,xs,xk,xr,xc); /* Sort the array(s) */
2446 return(success = 1); /* Always succeeds */
2450 static struct keytab purgtab[] = { /* PURGE command switches */
2451 { "/after", PU_AFT, CM_ARG },
2452 { "/ask", PU_ASK, 0 },
2453 { "/before", PU_BEF, CM_ARG },
2454 { "/delete", PU_DELE, CM_INV },
2456 { "/dotfiles", PU_DOT, 0 },
2457 #endif /* UNIXOROSK */
2458 { "/except", PU_EXC, CM_ARG },
2459 { "/heading", PU_HDG, 0 },
2460 { "/keep", PU_KEEP, CM_ARG },
2461 { "/larger-than", PU_LAR, CM_ARG },
2462 { "/list", PU_LIST, 0 },
2463 { "/log", PU_LIST, CM_INV },
2464 { "/noask", PU_NASK, 0 },
2465 { "/nodelete", PU_NODE, CM_INV },
2467 { "/nodotfiles", PU_NODOT,0 },
2468 #endif /* UNIXOROSK */
2469 { "/noheading", PU_NOH, 0 },
2470 { "/nol", PU_NOLI, CM_INV|CM_ABR },
2471 { "/nolist", PU_NOLI, 0 },
2472 { "/nolog", PU_NOLI, CM_INV },
2474 { "/nopage", PU_NOPA, 0 },
2475 #endif /* CK_TTGWSIZ */
2476 { "/not-after", PU_NAF, CM_ARG },
2477 { "/not-before", PU_NBF, CM_ARG },
2478 { "/not-since", PU_NAF, CM_INV|CM_ARG },
2480 { "/page", PU_PAGE, 0 },
2481 #endif /* CK_TTGWSIZ */
2482 { "/quiet", PU_QUIE, CM_INV },
2484 { "/recursive", PU_RECU, 0 },
2485 #endif /* RECURSIVE */
2486 { "/since", PU_AFT, CM_ARG|CM_INV },
2487 { "/simulate", PU_NODE, 0 },
2488 { "/smaller-than", PU_SMA, CM_ARG },
2489 { "/verbose", PU_VERB, CM_INV }
2491 static int npurgtab = sizeof(purgtab)/sizeof(struct keytab);
2498 bkupnum(s,i) char * s; int *i; {
2500 char * p = NULL, *q;
2505 if ((k = strlen(s)) < 5)
2512 while (q >= s && isdigit(*q)) {
2520 if (*q != '~' || *(q-1) != '.')
2524 debug(F111,"bkupnum",s+pos,pos);
2529 /* Presently only for UNIX because we need direct access to the file array. */
2530 /* Not needed for VMS anyway, because we don't make backup files there. */
2532 #define MAXKEEP 32 /* Biggest /KEEP: value */
2535 pu_keep = 0, pu_list = 0, pu_dot = 0, pu_ask = 0, pu_hdg = 0;
2538 static int pu_page = -1;
2540 static int pu_page = 0;
2541 #endif /* CK_TTGWSIZ */
2545 showpurgopts() { /* SHOW PURGE command options */
2547 extern int optlines;
2548 prtopt(&optlines,"PURGE");
2551 prtopt(&optlines, pu_ask ? "/ASK" : "/NOASK");
2556 prtopt(&optlines, pu_dot ? "/DOTFILES" : "/NODOTFILES");
2558 #endif /* UNIXOROSK */
2561 ckmakmsg(tmpbuf,TMPBUFSIZ,"/KEEP:",ckitoa(pu_keep),NULL,NULL);
2562 prtopt(&optlines,tmpbuf);
2566 prtopt(&optlines, pu_list ? "/LIST" : "/NOLIST");
2570 prtopt(&optlines, pu_hdg ? "/HEADING" : "/NOHEADING");
2575 prtopt(&optlines, pu_page ? "/PAGE" : "/NOPAGE");
2577 #endif /* CK_TTGWSIZ */
2578 if (!x) prtopt(&optlines,"(no options set)");
2579 prtopt(&optlines,"");
2584 setpurgopts() { /* Set PURGE command options */
2585 int c, z, getval = 0;
2587 x_keep = -1, x_list = -1, x_page = -1,
2588 x_hdg = -1, x_ask = -1, x_dot = -1;
2591 if ((y = cmswi(purgtab,npurgtab,"Switch","",xxstring)) < 0) {
2598 if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
2599 printf("?This switch does not take an argument\n");
2602 if (!getval && (cmgkwflgs() & CM_ARG)) {
2603 printf("?This switch requires an argument\n");
2609 if (c == ':' || c == '=')
2610 if ((y = cmnum("How many backup files to keep",
2611 "1",10,&z,xxstring)) < 0)
2613 if (z < 0 || z > MAXKEEP) {
2614 printf("?Please specify a number between 0 and %d\n",
2636 #endif /* CK_TTGWSIZ */
2656 #endif /* UNIXOROSK */
2658 printf("?This option can not be set\n");
2662 if ((x = cmcfm()) < 0) /* Get confirmation */
2664 if (x_keep > -1) /* Set PURGE defaults. */
2671 #endif /* CK_TTGWSIZ */
2678 return(success = 1);
2682 dopurge() { /* Do the PURGE command */
2683 extern char ** mtchs;
2684 extern int xaskmore, cmd_rows, recursive;
2685 int simulate = 0, asking = 0;
2686 int listing = 0, paging = -1, lines = 0, deleting = 1, errors = 0;
2687 struct FDB sw, sf, cm;
2688 int g, i, j, k, m = 0, n, x, y, z, done = 0, count = 0, flags = 0;
2689 int tokeep = 0, getval = 0, havename = 0, confirmed = 0;
2690 int xx[MAXKEEP+1]; /* Array of numbers to keep */
2692 int x_hdg = 0, fs = 0, rc = 0;
2693 long minsize = -1L, maxsize = -1L;
2694 char namebuf[CKMAXPATH+4];
2695 char basebuf[CKMAXPATH+4];
2702 char * pxlist[8]; /* Exception list */
2704 if (pu_keep > -1) /* Set PURGE defaults. */
2711 #endif /* CK_TTGWSIZ */
2713 for (i = 0; i <= MAXKEEP; i++) /* Clear this number buffer */
2715 for (i = 0; i < 8; i++) /* Initialize these... */
2718 g_matchdot = matchdot; /* Save these... */
2720 cmfdbi(&sw, /* 1st FDB - PURGE switches */
2722 "Filename or switch", /* hlpmsg */
2724 "", /* addtl string data */
2725 npurgtab, /* addtl numeric data 1: tbl size */
2726 4, /* addtl numeric data 2: 4 = cmswi */
2727 xxstring, /* Processing function */
2728 purgtab, /* Keyword table */
2729 &sf /* Pointer to next FDB */
2731 cmfdbi(&sf, /* 2nd FDB - filespec to purge */
2735 "", /* addtl string data */
2736 0, /* addtl numeric data 1 */
2737 0, /* addtl numeric data 2 */
2742 cmfdbi(&cm, /* Or premature confirmation */
2746 "", /* addtl string data */
2747 0, /* addtl numeric data 1 */
2748 0, /* addtl numeric data 2 */
2754 while (!havename && !confirmed) {
2755 x = cmfdb(&sw); /* Parse something */
2756 if (x < 0) { /* Error */
2759 } else if (cmresult.fcode == _CMKEY) {
2762 if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
2763 printf("?This switch does not take an argument\n");
2767 if (!getval && (cmgkwflgs() & CM_ARG)) {
2768 printf("?This switch requires an argument\n");
2772 switch (k = cmresult.nresult) {
2775 if (c == ':' || c == '=') {
2776 if ((y = cmnum("How many backup files to keep",
2777 "1",10,&z,xxstring)) < 0) {
2782 if (z < 0 || z > MAXKEEP) {
2783 printf("?Please specify a number between 0 and %d\n",
2804 #endif /* CK_TTGWSIZ */
2823 if ((x = cmdate("File-time","",&s,0,xxstring)) < 0) {
2825 printf("?Date-time required\n");
2833 case PU_AFT: makestr(&pu_aft,s); break;
2834 case PU_BEF: makestr(&pu_bef,s); break;
2835 case PU_NAF: makestr(&pu_naf,s); break;
2836 case PU_NBF: makestr(&pu_nbf,s); break;
2841 if ((x = cmnum("File size in bytes","0",10,&y,xxstring)) < 0) {
2846 switch (cmresult.nresult) {
2847 case PU_SMA: minsize = y; break;
2848 case PU_LAR: maxsize = y; break;
2858 if ((x = cmfld("Pattern","",&s,xxstring)) < 0) {
2860 printf("?Pattern required\n");
2873 case PU_RECU: /* /RECURSIVE */
2876 #endif /* RECURSIVE */
2878 printf("?Not implemented yet - \"%s\"\n",atmbuf);
2882 } else if (cmresult.fcode == _CMIFI) {
2884 } else if (cmresult.fcode == _CMCFM) {
2893 ckmakmsg(line,LINBUFSIZ,cmresult.sresult,".~[1-9]*~",NULL,NULL);
2895 ckmakmsg(line,LINBUFSIZ,cmresult.sresult,".~*~",NULL,NULL);
2896 #endif /* CKREGEX */
2899 ckstrncpy(line,"*.~[1-9]*~",LINBUFSIZ);
2901 ckstrncpy(line,"*.~*~",LINBUFSIZ);
2902 #endif /* CKREGEX */
2905 if ((x = cmcfm()) < 0) {
2910 /* Parse finished - now action */
2914 printf("?File deletion by guests not permitted.\n");
2918 #endif /* CK_LOGIN */
2921 if (paging < 0) /* /[NO]PAGE not given */
2922 paging = xaskmore; /* so use prevailing */
2923 #endif /* CK_TTGWSIZ */
2927 printf("Purging %s, keeping %d...%s\n",
2930 simulate ? " (SIMULATION)" : "");
2934 if (recursive) flags |= ZX_RECURSE;
2935 n = nzxpand(line,flags); /* Get list of backup files */
2936 if (tokeep < 1) { /* Deleting all of them... */
2937 for (i = 0; i < n; i++) {
2938 if (fs) if (fileselect(mtchs[i],
2939 pu_aft,pu_bef,pu_naf,pu_nbf,
2940 minsize,maxsize,0,8,pxlist) < 1) {
2942 printf(" %s (SKIPPED)\n",mtchs[i]);
2945 if (++lines > cmd_rows - 3) {
2946 if (!askmore()) goto xpurge; else lines = 0;
2948 #endif /* CK_TTGWSIZ */
2954 ckmakmsg(tmpbuf,TMPBUFSIZ," Delete ",mtchs[i],"?",NULL);
2955 x = getyesno(tmpbuf,1);
2959 case 2: goto xpurge;
2962 x = deleting ? zdelet(mtchs[i]) : 0;
2965 printf(" %s (%s)\n", mtchs[i],deleting ? "OK" : "SELECTED");
2970 printf(" %s (FAILED)\n", mtchs[i]);
2973 if (listing && paging)
2974 if (++lines > cmd_rows - 3) {
2975 if (!askmore()) goto xpurge; else lines = 0;
2977 #endif /* CK_TTGWSIZ */
2981 if (n < tokeep) { /* Not deleting any */
2984 printf(" Matches = %d: Not enough to purge.\n");
2988 /* General case - delete some but not others */
2990 sh_sort(mtchs,NULL,n,0,0,filecase); /* Alphabetize the list (ESSENTIAL) */
2992 g = 0; /* Start of current group */
2993 for (i = 0; i < n; i++) { /* Go thru sorted file list */
2994 x = znext(namebuf); /* Get next file */
2995 if (x < 1 || !namebuf[0] || i == n - 1) /* No more? */
2996 done = 1; /* NOTE: 'done' must be 0 or 1 only */
2997 if (fs) if (fileselect(namebuf,
2998 pu_aft,pu_bef,pu_naf,pu_nbf,
2999 minsize,maxsize,0,8,pxlist) < 1) {
3001 printf(" %s (SKIPPED)\n",namebuf);
3002 if (++lines > cmd_rows - 3)
3003 if (!askmore()) goto xpurge; else lines = 0;
3008 if ((m = bkupnum(namebuf,&z)) < 0) /* This file's backup number. */
3010 for (j = 0; j < tokeep; j++) { /* Insert in list. */
3012 for (k = tokeep - 1; k > j; k--)
3019 if (done || (i > 0 && ckstrcmp(namebuf,basebuf,z,1))) {
3020 if (i + done - g > tokeep) { /* Do we have enough to purge? */
3021 min = xx[tokeep-1]; /* Yes, lowest backup number to keep */
3022 debug(F111,"dopurge group",basebuf,min);
3023 for (j = g; j < i + done; j++) { /* Go through this group */
3024 x = bkupnum(mtchs[j],&z); /* Get file backup number */
3025 if (x > 0 && x < min) { /* Below minimum? */
3026 x = deleting ? zdelet(mtchs[j]) : 0;
3027 if (x < 0) errors++;
3029 printf(" %s (%s)\n",
3031 ((x < 0) ? "ERROR" :
3032 (deleting ? "DELETED" : "SELECTED"))
3035 } else if (listing) /* Not below minimum - keep this one */
3036 printf(" %s (KEPT)\n",mtchs[j]);
3038 if (listing && paging)
3039 if (++lines > cmd_rows - 3) {
3040 if (!askmore()) goto xpurge; else lines = 0;
3042 #endif /* CK_TTGWSIZ */
3044 } else if (listing && paging) { /* Not enough to purge */
3045 printf(" %s.~*~ (KEPT)\n",basebuf);
3047 if (++lines > cmd_rows - 3) {
3048 if (!askmore()) goto xpurge; else lines = 0;
3050 #endif /* CK_TTGWSIZ */
3052 for (j = 0; j < tokeep; j++) /* Clear the backup number list */
3054 g = i; /* Reset the group pointer */
3056 if (done) /* No more files, done. */
3058 strncpy(basebuf,namebuf,z); /* Set basename of this file */
3061 xpurge: /* Common exit point */
3062 if (g_matchdot > -1) {
3063 matchdot = g_matchdot; /* Restore these... */
3066 if (rc < 0) return(rc); /* Parse error */
3068 printf("Files purged: %d%s\n",
3070 deleting ? "" : " (not really)"
3072 return(success = count > 0 ? 1 : (errors > 0) ? 0 : 1);
3074 #endif /* CKPURGE */
3079 doxdis(which) int which; { /* 1 = Kermit, 2 = FTP */
3088 #endif /* COMMENT */
3090 if ((x = cmkey(fdtab,nfdtab,"file transfer display style","",
3094 if ((y = cmkey(fdftab,2,"","thermometer",xxstring)) < 0)
3096 #endif /* CK_PCT_BAR */
3097 if ((z = cmcfm()) < 0) return(z);
3099 if (x == XYFD_C) { /* FULLSCREEN */
3102 extern char * trmbuf; /* Real curses */
3104 #endif /* MYCURSES */
3105 #endif /* COMMENT */
3107 if (nolocal) /* Nothing to do in this case */
3108 return(success = 1);
3114 debug(F110,"doxdis TERM",s,0);
3117 if (*s && trmbuf) { /* Don't call tgetent */
3118 z = tgetent(trmbuf,s); /* if trmbuf not allocated */
3119 debug(F111,"doxdis tgetent",s,z);
3122 debug(F110,"doxdis tgetent skipped",s,0);
3125 printf("Sorry, terminal type unknown: \"%s\"\n",s);
3126 return(success = 0);
3129 #endif /* MYCURSES */
3132 #endif /* COMMENT */
3136 #endif /* CK_PCT_BAR */
3138 line[0] = '\0'; /* (What's this for?) */
3140 #endif /* CK_CURSES */
3141 if (which == 1) /* It's OK. */
3147 return(success = 1);
3149 #endif /* NOLOCAL */
3153 setfil(rmsflg) int rmsflg; {
3156 #endif /* COMMENT */
3159 if ((y = cmkey(rfiltab,nrfilp,"Remote file parameter","",
3162 printf("?Remote file parameter required\n");
3168 if ((y = cmkey(filtab,nfilp,"File parameter","",xxstring)) < 0)
3174 #ifdef COMMENT /* Not needed */
3175 case XYFILB: /* Blocksize */
3176 if ((y = cmnum("file block size",ckitoa(DBLKSIZ),10,&z,xxstring)) < 0)
3178 if ((x = cmcfm()) < 0) return(x);
3180 sstate = setgen('S', "311", ckitoa(z), "");
3181 return((int) sstate);
3184 return(success = 1);
3186 #endif /* COMMENT */
3189 case XYFILS: /* Byte size */
3190 if ((y = cmnum("file byte size (7 or 8)","8",10,&z,xxstring)) < 0)
3192 if (z != 7 && z != 8) {
3193 printf("\n?The choices are 7 and 8\n");
3196 if ((y = cmcfm()) < 0) return(y);
3197 if (z == 7) fmask = 0177;
3198 else if (z == 8) fmask = 0377;
3199 return(success = 1);
3202 case XYFILC: { /* Character set */
3203 char * csetname = NULL;
3205 r_cset, s_cset, afcset[]; /* SEND CHARACTER-SET AUTO or MANUAL */
3208 cmfdbi(&kw, /* First FDB - command switches */
3210 rmsflg ? "server character-set name" : "", /* help */
3212 "", /* addtl string data */
3213 nfilc, /* addtl numeric data 1: tbl size */
3214 0, /* addtl numeric data 2: 0 = keyword */
3215 xxstring, /* Processing function */
3216 fcstab, /* Keyword table */
3217 rmsflg ? &fl : NULL /* Pointer to next FDB */
3219 cmfdbi(&fl, /* Anything that doesn't match */
3223 "", /* addtl string data */
3224 0, /* addtl numeric data 1 */
3225 0, /* addtl numeric data 2 */
3230 if ((x = cmfdb(&kw)) < 0)
3232 if (cmresult.fcode == _CMKEY) {
3233 x = cmresult.nresult;
3234 csetname = fcsinfo[x].keyword;
3236 ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
3239 if ((z = cmcfm()) < 0) return(z);
3241 sstate = setgen('S', "320", csetname, "");
3242 return((int) sstate);
3245 if (s_cset == XMODE_A) /* If SEND CHARACTER-SET is AUTO */
3246 if (x > -1 && x <= MAXFCSETS)
3247 if (afcset[x] > -1 && afcset[x] <= MAXTCSETS)
3248 tcharset = afcset[x]; /* Pick corresponding xfer charset */
3249 setxlatype(tcharset,fcharset); /* Translation type */
3250 /* If I say SET FILE CHARACTER-SET blah, I want to be blah! */
3251 r_cset = XMODE_M; /* Don't switch incoming set! */
3252 x = fcsinfo[fcharset].size; /* Also set default x-bit charset */
3253 if (x == 128) /* 7-bit... */
3255 else if (x == 256) /* 8-bit... */
3257 return(success = 1);
3259 #endif /* NOCSETS */
3262 case XYFILD: /* Display */
3263 return(doxdis(1)); /* 1 == kermit */
3264 #endif /* NOLOCAL */
3267 case XYFILA: /* End-of-line */
3272 else if (NLCHAR == 012)
3274 if ((x = cmkey(eoltab, neoltab,
3275 "local text-file line terminator",s,xxstring)) < 0)
3278 if ((x = cmkey(eoltab, neoltab,
3279 "local text-file line terminator","crlf",xxstring)) < 0)
3282 if ((z = cmcfm()) < 0) return(z);
3284 return(success = 1);
3287 case XYFILN: /* Names */
3288 if ((x = cmkey(fntab,nfntab,"how to handle filenames","converted",
3291 if ((z = cmcfm()) < 0) return(z);
3293 sstate = setgen('S', "301", ckitoa(1 - x), "");
3294 return((int) sstate);
3296 ptab[protocol].fncn = x; /* Set structure */
3297 fncnv = x; /* Set variable */
3298 f_save = x; /* And set "permanent" variable */
3299 return(success = 1);
3302 case XYFILR: /* Record length */
3303 if ((y = cmnum("file record length",
3304 ckitoa(DLRECL),10,&z,xxstring)) < 0)
3306 if ((x = cmcfm()) < 0) return(x);
3308 sstate = setgen('S', "312", ckitoa(z), "");
3309 return((int) sstate);
3312 return(success = 1);
3316 case XYFILO: /* Organization */
3317 if ((x = cmkey(forgtab,nforg,"file organization","sequential",
3320 if ((y = cmcfm()) < 0) return(y);
3322 sstate = setgen('S', "314", ckitoa(x), "");
3323 return((int) sstate);
3326 return(success = 1);
3328 #endif /* COMMENT */
3330 #ifdef COMMENT /* Not needed */
3331 case XYFILF: /* Format */
3332 if ((x = cmkey(frectab,nfrec,"file record format","stream",
3335 if ((y = cmcfm()) < 0) return(y);
3337 sstate = setgen('S', "313", ckitoa(x), "");
3338 return((int) sstate);
3341 return(success = 1);
3343 #endif /* COMMENT */
3346 case XYFILP: /* Printer carriage control */
3347 if ((x = cmkey(fcctab,nfcc,"file carriage control","newline",
3350 if ((y = cmcfm()) < 0) return(y);
3352 sstate = setgen('S', "315", ckitoa(x), "");
3353 return((int) sstate);
3356 return(success = 1);
3358 #endif /* COMMENT */
3361 case XYFILT: /* Type */
3362 if ((x = cmkey(rmsflg ? rfttab : fttab,
3363 rmsflg ? nrfttyp : nfttyp,
3364 "type of file transfer","text",xxstring)) < 0)
3368 /* Allow VMS users to choose record format for binary files */
3369 if ((x == XYFT_B) && (rmsflg == 0)) {
3370 if ((x = cmkey(fbtab,nfbtyp,"VMS record format","fixed",
3375 if ((y = cmcfm()) < 0) return(y);
3379 (void) mac_setfildflg(binary);
3383 /* Allow for LABELED in VMS & OS/2 */
3384 sstate = setgen('S', "300", ckitoa(x), "");
3385 return((int) sstate);
3388 return(success = 1);
3394 case XYFILX: /* Collision Action */
3395 if ((x = cmkey(colxtab,ncolx,"Filename collision action","backup",
3398 if ((y = cmcfm()) < 0) return(y);
3401 /* Don't let guests change existing files */
3402 printf("?This command not valid for guests\n");
3405 #endif /* CK_LOGIN */
3407 /* Not appropriate - DISABLE DELETE only refers to server */
3408 if ((x == XYFX_X || x == XYFX_B || x == XYFX_U || x == XYFX_A) &&
3409 (!ENABLED(en_del))) {
3410 printf("?Sorry, file deletion is disabled.\n");
3413 #endif /* COMMENT */
3415 ptab[protocol].fnca = x;
3417 sstate = setgen('S', "302", ckitoa(fncact), "");
3418 return((int) sstate);
3420 if (fncact == XYFX_R) ckwarn = 1; /* FILE WARNING implications */
3421 if (fncact == XYFX_X) ckwarn = 0; /* ... */
3422 return(success = 1);
3425 case XYFILW: /* Warning/Write-Protect */
3426 if ((x = seton(&ckwarn)) < 0) return(x);
3431 return(success = 1);
3434 case XYFILL: /* LABELED FILE parameters */
3435 if ((x = cmkey(lbltab,nlblp,"Labeled file feature","",
3438 if ((success = seton(&y)) < 0)
3440 if (y) /* Set or reset the selected bit */
3441 lf_opts |= x; /* in the options bitmask. */
3445 #endif /* CK_LABELED */
3447 case XYFILI: { /* INCOMPLETE */
3448 extern struct keytab ifdatab[];
3450 if ((y = cmkey(ifdatab,3,"","auto",xxstring)) < 0) return(y);
3451 if ((x = cmcfm()) < 0) return(x);
3453 sstate = setgen('S',
3455 y == 0 ? "0" : (y == 1 ? "1" : "2"),
3458 return((int) sstate);
3461 return(success = 1);
3466 case XYFILG: { /* Download directory */
3477 if ((x = cmdir("Name of local directory, or carriage return",
3485 if ((x = cmdir("Name of PC disk and/or directory,\n\
3486 or press the Enter key to use current directory",
3487 "",&s,xxstring)) < 0 ) {
3493 x = ckstrncpy(temp,zhome(),32);
3494 if (x > 0) if (temp[x-1] != ':') { temp[x] = ':'; temp[x+1] = NUL; }
3495 if ((x = cmtxt("Name of Macintosh volume and/or folder,\n\
3496 or press the Return key for the desktop on the boot disk",
3497 temp,&s, xxstring)) < 0 )
3500 if ((x = cmdir("Name of local directory, or carriage return",
3501 "", &s, xxstring)) < 0 ) {
3508 debug(F110,"download dir",s,0);
3512 printf("?Wildcards not allowed in directory name\n");
3518 if ((fnp = zfnqfp(s,TMPBUFSIZ - 1,tmpbuf))) {
3520 if ((int) strlen(fnp->fpath) > 0)
3523 debug(F110,"download zfnqfp",s,0);
3526 ckstrncpy(line,s,LINBUFSIZ); /* Make a safe copy */
3528 if ((x = cmcfm()) < 0) /* Get confirmation */
3534 /* Don't let guests change existing files */
3535 printf("?This command not valid for guests\n");
3538 #endif /* CK_LOGIN */
3542 #ifdef datageneral /* AOS/VS */
3543 if (s[x-1] == ':') /* homdir ends in colon, */
3544 s[x-1] = NUL; /* and "dir" doesn't like that... */
3546 #ifdef OS2ORUNIX /* Unix or K-95... */
3547 if ((x < (LINBUFSIZ - 2)) && /* Add trailing dirsep */
3548 (s[x-1] != '/')) { /* if none present. */
3549 s[x] = '/'; /* Note that Windows path has */
3550 s[x+1] = NUL; /* been canonicalized to forward */
3551 } /* slashes at this point. */
3552 #endif /* OS2ORUNIX */
3553 #endif /* datageneral */
3556 makestr(&dldir,NULL); /* dldir is NULL when not assigned */
3558 return(success = 1);
3560 #endif /* CK_TMPDIR */
3566 case XYFILV: { /* EOF */
3567 extern int eofmethod;
3568 if ((x = cmkey(eoftab,3,"end-of-file detection method","",
3571 if ((y = cmcfm()) < 0)
3574 return(success = 1);
3576 #endif /* CK_CTRLZ */
3580 case XYFILH: { /* OUTPUT */
3581 extern int zofbuffer, zobufsize, zofblock;
3583 extern char * zoutbuffer;
3584 #endif /* DYNAMIC */
3586 if ((x = cmkey(zoftab,nzoftab,"output file writing method","",
3589 if (x == ZOF_BUF || x == ZOF_NBUF) {
3590 if ((y = cmnum("output buffer size","32768",10,&z,xxstring)) < 0)
3593 printf("?Bad size - %d\n", z);
3597 if ((y = cmcfm()) < 0) return(y);
3601 zofbuffer = (x == ZOF_BUF);
3606 zofblock = (x == ZOF_BLK);
3610 if (zoutbuffer) free(zoutbuffer);
3611 if (!(zoutbuffer = (char *)malloc(z))) {
3612 printf("MEMORY ALLOCATION ERROR - FATAL\n");
3613 doexit(BAD_EXIT,-1);
3617 if (z <= OBUFSIZE) {
3620 printf("?Sorry, %d is too big - %d is the maximum\n",z,OBUFSIZE);
3623 #endif /* DYNAMIC */
3624 return(success = 1);
3629 case XYFIBP: /* BINARY-PATTERN */
3630 case XYFITP: { /* TEXT-PATTERN */
3631 char * tmp[FTPATTERNS];
3633 while (n < FTPATTERNS) {
3635 if ((x = cmfld("Pattern","",&s,xxstring)) < 0)
3637 ckstrncpy(line,s,LINBUFSIZ);
3639 makestr(&(tmp[n++]),s);
3641 if (x == -3) x = cmcfm();
3642 for (i = 0; i <= n; i++) {
3645 makestr(&(binpatterns[i]),tmp[i]);
3647 makestr(&(txtpatterns[i]),tmp[i]);
3651 if (y == XYFIBP) /* Null-terminate the list */
3652 makestr(&(binpatterns[i]),NULL);
3654 makestr(&(txtpatterns[i]),NULL);
3658 case XYFIPA: /* PATTERNS */
3659 if ((x = setonaut(&patterns)) < 0)
3661 return(success = 1);
3662 #endif /* PATTERNS */
3666 case XYFILU: { /* UCS */
3667 extern int ucsorder, ucsbom, byteorder;
3668 if ((x = cmkey(ucstab,nucstab,"","",xxstring)) < 0)
3672 if ((y = cmkey(botab,nbotab,
3674 byteorder ? "little-endian" : "big-endian",
3679 if ((x = cmcfm()) < 0)
3682 return(success = 1);
3684 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0)
3686 if ((x = cmcfm()) < 0)
3689 return(success = 1);
3694 #endif /* UNICODE */
3697 case XYF_INSP: { /* SCAN (INSPECTION) */
3698 extern int filepeek, nscanfile;
3699 if ((x = cmkey(onoff,2,"","on",xxstring)) < 0)
3702 if ((y = cmnum("How much to scan",ckitoa(SCANFILEBUF),
3703 10,&z,xxstring)) < 0)
3706 if ((y = cmcfm()) < 0)
3711 return(success = 0);
3715 return(success = 1);
3718 #endif /* datageneral */
3723 if ((y = cmkey(fdfltab,nfdflt,"","",xxstring)) < 0)
3725 if (y == 7 || y == 8) {
3727 s = fcsinfo[dcset7].keyword;
3729 s = fcsinfo[dcset8].keyword;
3730 if ((x = cmkey(fcstab,nfilc,"character-set",s,xxstring)) < 0)
3733 ckstrncpy(line,fcsinfo[x].keyword,LINBUFSIZ);
3735 #endif /* NOCSETS */
3736 if ((z = cmcfm()) < 0)
3741 if (fcsinfo[x].size != 128) {
3742 printf("%s - Not a 7-bit set\n",s);
3748 if (fcsinfo[x].size != 256) {
3749 printf("%s - Not an 8-bit set\n",s);
3754 #endif /* NOCSETS */
3758 return(success = 1);
3761 case 9997: /* FASTLOOKUPS */
3762 return(success = seton(&stathack));
3767 case XYF_LSIZ: { /* LISTSIZE */
3769 y = cmnum("Maximum number of filenames","",10,&x,xxstring);
3770 if ((x = setnum(&zz,x,y,-1)) < 0)
3772 if (zsetfil(zz,3) < 0) {
3773 printf("?Memory allocation failure\n");
3776 return(success = 1);
3778 case XYF_SSPA: { /* STRINGSPACE */
3780 y = cmnum("Number of characters for filename list",
3782 if ((x = setnum(&zz,x,y,-1)) < 0)
3784 if (zsetfil(zz,1) < 0) {
3785 printf("?Memory allocation failure\n");
3788 return(success = 1);
3791 #endif /* DYNAMIC */
3795 printf("?unexpected file parameter\n");
3802 /* MS-DOS KERMIT compatibility modes */
3805 if ((y = cmkey(msktab,nmsk,"MS-DOS Kermit compatibility mode",
3806 "keycodes",xxstring)) < 0) return(y);
3811 return(seton(&mskcolors));
3812 #endif /* COMMENT */
3814 return(seton(&mskkeys));
3815 default: /* Shouldn't get here. */
3825 extern int ttnum; /* Last Telnet Terminal Type sent */
3826 extern int ttnumend; /* Has end of list been found */
3828 if ((x = cmkey(ttyptab,nttyp,"","vt320",xxstring)) < 0)
3830 if ((y = cmcfm()) < 0)
3834 /* So we send the correct terminal name to the host if it asks for it */
3835 ttnum = -1; /* Last Telnet Terminal Type sent */
3836 ttnumend = 0; /* end of list not found */
3838 return(success = 1);
3841 "\n Sorry, this version of C-Kermit does not support the SET TERMINAL TYPE\n");
3843 " command. Type \"help set terminal\" for further information.\n");
3845 return(success = 0);
3849 static char iactbuf[132];
3853 switch (tt_idleact) {
3854 case IDLE_RET: return("return");
3855 case IDLE_EXIT: return("exit");
3856 case IDLE_HANG: return("hangup");
3858 case IDLE_TNOP: return("Telnet NOP");
3859 case IDLE_TAYT: return("Telnet AYT");
3865 k = ckstrncpy(iactbuf,"output ",132);
3870 if (!*p) return("output (nothing)");
3871 while ((c = *p++) && n < 131) {
3879 } else if ((c > 31 && c < 127) || c > 159) {
3886 sprintf(q,"\\{%d}",c);
3907 default: return("unknown");
3910 #endif /* CKTIDLE */
3914 setlclcharset(x) int x; {
3916 tcsl = y; /* Local character set */
3918 for (i = 0; i < 4; i++) {
3920 x = G[i].designation;
3921 G[i].c1 = (x != tcsl) && cs_is_std(x);
3922 x = G[i].def_designation;
3923 G[i].def_c1 = (x != tcsl) && cs_is_std(x);
3929 setremcharset(x, z) int x, z; {
3933 KuiSetProperty( KUI_TERM_REMCHARSET, (long) x, (long) z ) ;
3939 #endif /* UNICODE */
3940 { /* TRANSPARENT? */
3942 tcsr = tcsl; /* Make both sets the same */
3945 tt_utf8 = 0; /* Turn off UTF8 flag */
3946 tcsr = tcsl = dec_kbd = TX_TRANSP; /* No translation */
3949 if (!cs_is_nrc(tcsl)) {
3950 G[0].def_designation = G[0].designation = TX_ASCII;
3952 G[0].def_c1 = G[0].c1 = FALSE;
3954 G[0].national = FALSE;
3956 for (i = cs_is_nrc(tcsl) ? 0 : 1; i < 4; i++) {
3957 G[i].def_designation = G[i].designation = tcsl;
3959 G[i].def_c1 = G[i].c1 = FALSE;
3960 switch (cs_size(G[i].designation)) { /* 94, 96, or 128 */
3963 G[i].size = G[i].def_size = cs96;
3966 G[i].size = G[i].def_size = cs94;
3969 G[i].size = G[i].def_size = csmb;
3972 G[i].national = cs_is_nrc(x);
3975 tcsr = tcsl; /* Make both sets the same */
3976 for (i = 0; i < 4; i++) {
3977 G[i].def_designation = G[i].designation = FC_TRANSP;
3979 G[i].size = G[i].def_size = cs96;
3980 G[i].c1 = G[i].def_c1 = FALSE;
3985 G[i].national = FALSE;
3993 else if (x == TX_UTF8) {
3995 tt_utf8 = 1; /* Turn it on if we are UTF8 */
4001 tcsr = x; /* Remote character set */
4003 tt_utf8 = 0; /* Turn off UTF8 flag */
4006 if (z == TT_GR_ALL) {
4010 #endif /* UNICODE */
4011 for (i = 0; i < 4; i++) {
4013 if ( i == 0 && !cs_is_nrc(x) ) {
4014 G[0].designation = G[0].def_designation = FC_USASCII;
4015 G[0].size = G[0].def_size = cs94;
4018 G[i].def_designation = G[i].designation = x;
4019 switch (cs_size(x)) { /* 94, 96, or 128 */
4022 G[i].size = G[i].def_size = cs96;
4025 G[i].size = G[i].def_size = cs94;
4028 G[i].size = G[i].def_size = csmb;
4031 G[i].national = cs_is_nrc(x);
4033 G[i].c1 = G[i].def_c1 = x != tcsl && cs_is_std(x);
4036 } else if (z == TT_GR_KBD) { /* Keyboard only */
4038 #endif /* UNICODE */
4039 } else { /* Specific Gn */
4040 G[z].def_designation = G[z].designation = x;
4042 switch (cs_size(x)) { /* 94, 96, or 128 */
4045 G[z].size = G[z].def_size = cs96;
4048 G[z].size = G[z].def_size = cs94;
4051 G[z].size = G[z].def_size = csmb;
4054 G[z].c1 = G[z].def_c1 = x != tcsl && cs_is_std(x);
4055 G[z].national = cs_is_nrc(x);
4059 tcsr = x; /* Remote character set */
4062 #endif /* NOCSETS */
4065 setcmask(x) int x; {
4068 } else if (x == 8) {
4073 KuiSetProperty(KUI_TERM_CMASK,x,0);
4079 setautodl(x,y) int x,y; {
4083 KuiSetProperty(KUI_TERM_AUTODOWNLOAD,x?(y?2:1):0,0);
4086 #endif /* CK_AUTODL */
4093 KuiSetProperty(KUI_TERM_URL_HIGHLIGHT,x,0);
4102 KuiSetProperty(KUI_TERM_PRINTERCOPY,x,0);
4111 extern int colorreset, user_erasemode;
4113 if ((y = cmkey(trmtab,ntrm,"", "",xxstring)) < 0) return(y);
4115 printf("\n?Sorry, not implemented yet. Please use the Settings menu.\n");
4120 if ((y = cmcfm()) < 0) return(y);
4121 printf("?Sorry, command disabled.\r\n");
4122 return(success = 0);
4127 case XYTBYT: /* SET TERMINAL BYTESIZE */
4128 if ((y = cmnum("bytesize for terminal connection","8",10,&x,
4131 if (x != 7 && x != 8) {
4132 printf("\n?The choices are 7 and 8\n");
4133 return(success = 0);
4135 if ((y = cmcfm()) < 0) return(y);
4138 if (IS97801(tt_type_mode))
4141 return(success = 1);
4143 case XYTSO: /* SET TERMINAL LOCKING-SHIFT */
4144 return(seton(&sosi));
4146 case XYTNL: /* SET TERMINAL NEWLINE-MODE */
4147 return(seton(&tnlm));
4151 if ((x = cmkey(ttycoltab,ncolors,"","terminal",xxstring)) < 0)
4153 else if (x == TTCOLRES) {
4154 if ((y = cmkey(ttcolmodetab,ncolmode,
4155 "","default-color",xxstring)) < 0)
4157 if ((z = cmcfm()) < 0)
4160 return(success = 1);
4161 } else if (x == TTCOLERA) {
4162 if ((y = cmkey(ttcolmodetab,ncolmode,"",
4163 "current-color",xxstring)) < 0)
4165 if ((z = cmcfm()) < 0)
4169 } else { /* No parse error */
4171 fg = cmkey(ttyclrtab, nclrs,
4173 "color for screen border" :
4174 "foreground color and then background color"),
4178 if (x != TTCOLBOR) {
4179 if ((bg = cmkey(ttyclrtab,nclrs,
4180 "background color","blue",xxstring)) < 0)
4183 if ((y = cmcfm()) < 0)
4187 colornormal = fg | bg << 4;
4192 colorreverse = fg | bg << 4;
4195 coloritalic = fg | bg << 4;
4198 colorunderline = fg | bg << 4;
4201 colorgraphic = fg | bg << 4;
4204 colordebug = fg | bg << 4;
4207 colorstatus = fg | bg << 4;
4210 colorhelp = fg | bg << 4;
4216 colorselect = fg | bg << 4;
4219 printf("%s - invalid\n",cmdbuf);
4223 scrninitialized[VTERM] = 0;
4226 return(success = 1);
4228 case XYTCUR: { /* SET TERMINAL CURSOR */
4229 extern int cursorena[];
4230 extern int cursoron[] ; /* Cursor state on/off */
4231 if ((x = cmkey(ttycurtab,ncursors,"","underline",xxstring)) < 0)
4233 if ((z = cmkey(curontab,ncuron,"","on",xxstring)) < 0)
4235 if ((y = cmcfm()) < 0) return(y);
4236 tt_cursor = tt_cursor_usr = x;
4238 cursorena[VTERM] = tt_cursorena_usr = 1;
4239 tt_cursor_blink = 0;
4241 cursorena[VTERM] = tt_cursorena_usr = z;/* turn cursor on/off */
4242 tt_cursor_blink = 1;
4244 cursoron[VTERM] = FALSE; /* Force newcursor to restore the cursor */
4245 return(success = 1);
4249 case XYTTYP: /* SET TERMINAL TYPE */
4250 return(settrmtyp());
4253 case XYTARR: /* SET TERMINAL ARROW-KEYS */
4254 if ((x = cmkey(akmtab,2,"","",xxstring)) < 0) return(x);
4255 if ((y = cmcfm()) < 0) return(y);
4256 tt_arrow = x; /* TTK_NORM / TTK_APPL; see ckuusr.h */
4257 return(success = 1);
4259 case XYTKPD: /* SET TERMINAL KEYPAD-MODE */
4260 if ((x = cmkey(kpmtab,2,"","",xxstring)) < 0) return(x);
4261 if ((y = cmcfm()) < 0) return(y);
4262 tt_keypad = x; /* TTK_NORM / TTK_APPL; see ckuusr.h */
4263 return(success = 1);
4265 case XYTUNX: { /* SET TERM UNIX-MODE (DG) */
4266 extern int dgunix,dgunix_usr;
4268 dgunix_usr = dgunix;
4271 case XYTKBMOD: { /* SET TERM KEYBOARD MODE */
4272 extern int tt_kb_mode;
4273 if ((x = cmkey(kbmodtab,
4276 "special keyboard mode for terminal emulation",
4280 if ((y = cmcfm()) < 0) return(y);
4282 return(success = 1);
4285 case XYTWRP: /* SET TERMINAL WRAP */
4286 return(seton(&tt_wrap));
4289 if ((y = cmnum("CONNECT scrollback buffer size, lines","2000",10,&x,
4292 /* The max number of lines is the RAM */
4293 /* we can actually dedicate to a */
4294 /* scrollback buffer given the maximum */
4295 /* process memory space of 512MB */
4296 if (x < 256 || x > 2000000L) {
4297 printf("\n?The size must be between 256 and 2,000,000.\n");
4298 return(success = 0);
4300 if ((y = cmcfm()) < 0) return(y);
4301 tt_scrsize[VTERM] = x;
4303 return(success = 1);
4307 case XYTCS: { /* SET TERMINAL CHARACTER-SET */
4309 /* set terminal character-set <remote> <local> */
4316 "remote terminal character-set","",xxstring)) < 0)
4325 if ((y = cmcfm()) < 0) /* Confirm the command */
4328 if ( isunicode() && x == TX_TRANSP ) {
4329 /* If we are in unicode display mode then transparent
4330 * only affects the output direction. We need to know
4331 * the actual remote character set in order to perform
4332 * the tcsr -> ucs2 translation for display.
4340 if (x == FC_TRANSP) {
4341 if ((y = cmcfm()) < 0) /* Confirm the command */
4345 #endif /* UNICODE */
4347 /* Not transparent or UTF8, so get local set to translate it into */
4350 y = os2getcp(); /* Default is current code page */
4352 case 437: s = "cp437"; break;
4353 case 850: s = "cp850"; break;
4354 case 852: s = "cp852"; break;
4355 case 857: s = "cp857"; break;
4356 case 858: s = "cp858"; break;
4357 case 862: s = "cp862"; break;
4358 case 866: s = "cp866"; break;
4359 case 869: s = "cp869"; break;
4360 case 1250: s = "cp1250"; break;
4361 case 1251: s = "cp1251"; break;
4362 case 1252: s = "cp1252"; break;
4363 case 1253: s = "cp1253"; break;
4364 case 1254: s = "cp1254"; break;
4365 case 1255: s = "cp1255"; break;
4366 case 1256: s = "cp1256"; break;
4367 case 1257: s = "cp1257"; break;
4368 case 1258: s = "cp1258"; break;
4372 If the user has loaded a font with SET TERMINAL FONT then we want
4373 to change the default code page to the font that was loaded.
4375 if (tt_font != TTF_ROM) {
4376 for (y = 0; y < ntermfont; y++ ) {
4377 if (term_font[y].kwval == tt_font) {
4378 s = term_font[y].kwd;
4383 #endif /* PCFONTS */
4384 #else /* Not K95... */
4385 s = fcsinfo[fcharset].keyword;
4394 "local character-set",s,xxstring)) < 0)
4399 printf("?UTF8 may not be used as a local character set.\r\n");
4402 #endif /* UNICODE */
4404 if ((z = cmkey(graphsettab,ngraphset,
4405 "DEC VT intermediate graphic set","all",xxstring)) < 0)
4408 if ((eol = cmcfm()) < 0)
4409 return(eol); /* Confirm the command */
4411 /* End of command parsing - actions begin */
4414 return(success = 1);
4416 #endif /* NOCSETS */
4419 case XYTLCS: /* SET TERMINAL LOCAL-CHARACTER-SET */
4420 /* set terminal character-set <local> */
4421 s = getdcset(); /* Get display character-set name */
4428 "local character-set",s,xxstring)) < 0)
4433 printf("?UTF8 may not be used as a local character set.\r\n");
4436 #endif /* UNICODE */
4437 if ((z = cmcfm()) < 0) return(z); /* Confirm the command */
4439 /* End of command parsing - action begins */
4442 return(success = 1);
4443 #endif /* NOCSETS */
4447 case XYTUNI: /* SET TERMINAL UNICODE */
4448 return(seton(&tt_unicode));
4449 #endif /* UNICODE */
4451 case XYTRCS: /* SET TERMINAL REMOTE-CHARACTER-SET */
4452 /* set terminal character-set <remote> <Graphic-set> */
4459 "remote terminal character-set","",xxstring)) < 0)
4468 if ((y = cmcfm()) < 0) /* Confirm the command */
4471 if ( isunicode() && x == TX_TRANSP ) {
4472 /* If we are in unicode display mode then transparent
4473 * only affects the output direction. We need to know
4474 * the actual remote character set in order to perform
4475 * the tcsr -> ucs2 translation for display.
4482 if (x == FC_TRANSP) {
4483 if ((y = cmcfm()) < 0) /* Confirm the command */
4486 #endif /* UNICODE */
4489 if ((z = cmkey(graphsettab,ngraphset,
4490 "DEC VT intermediate graphic set","all",xxstring)) < 0)
4493 if ((y = cmcfm()) < 0) /* Confirm the command */
4496 /* Command parsing ends here */
4499 return(success = 1);
4500 #endif /* NOCSETS */
4502 case XYTEC: /* SET TERMINAL ECHO */
4503 if ((x = cmkey(rltab,nrlt,"which side echos during CONNECT",
4504 "remote", xxstring)) < 0) return(x);
4505 if ((y = cmcfm()) < 0) return(y);
4508 #endif /* NETCONN */
4510 return(success = 1);
4512 case XYTESC: /* SET TERM ESC */
4513 if ((x = cmkey(nabltab,nnabltab,"","enabled",xxstring)) < 0)
4515 if ((y = cmcfm()) < 0) return(y);
4519 case XYTCRD: /* SET TERMINAL CR-DISPLAY */
4520 if ((x = cmkey(crdtab,2,"", "normal", xxstring)) < 0) return(x);
4521 if ((y = cmcfm()) < 0) return(y);
4523 return(success = 1);
4526 case XYTANS: { /* SET TERMINAL ANSWERBACK */
4528 NOTE: We let them enable and disable the answerback sequence, but we
4529 do NOT let them change it, and we definitely do not let the host set it.
4530 This is a security feature.
4532 As of 1.1.8 we allow the SET TERM ANSWERBACK MESSAGE <string> to be
4533 used just as MS-DOS Kermit does. C0 and C1 controls as well as DEL
4534 are not allowed to be used as characters. They are translated to
4535 underscore. This may not be set by APC.
4537 if ((x = cmkey(anbktab,nansbk,"", "off", xxstring)) < 0)
4540 if ((y = cmcfm()) < 0)
4543 return(success = 1);
4544 } else if ( x == 2 || x == 3) {
4546 extern int safeanswerbk;
4547 extern char useranswerbk[];
4548 if ((y = cmtxt("Answerback extension","",&s,xxstring)) < 0)
4550 if (apcactive == APC_LOCAL ||
4551 (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH)))
4552 return(success = 0);
4555 /* Safe Answerback's don't have C0/C1 chars */
4556 for (z = 0; z < len; z++) {
4557 if ((s[z] & 0x7F) <= SP || (s[z] & 0x7F) == DEL)
4558 useranswerbk[z] = '_';
4560 useranswerbk[z] = s[z];
4562 useranswerbk[z] = '\0';
4563 safeanswerbk = 1 ; /* TRUE */
4565 ckstrncpy(useranswerbk,s,60); /* (see ckocon.c) */
4566 safeanswerbk = 0; /* FALSE */
4569 return(success = 1);
4571 return(success = 0);
4577 if ((y = cmkey(apctab,napctab,
4578 "application program command execution","",
4581 if ((x = cmcfm()) < 0)
4583 if (apcactive == APC_LOCAL ||
4584 (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH)))
4585 return(success = 0);
4587 return(success = 1);
4590 case XYTAUTODL: /* AUTODOWNLOAD */
4591 if ((y = cmkey(adltab,nadltab,"Auto-download options","",
4597 if ((x = cmcfm()) < 0)
4602 if ((x = cmcfm()) < 0)
4604 setautodl(TAD_ON,1);
4607 if ((y = cmkey(adlerrtab,nadlerrtab,"","", xxstring)) < 0)
4609 if ((x = cmcfm()) < 0)
4615 if ((y = cmkey(adlxtab,nadlxtab,"","", xxstring)) < 0)
4619 if ((y = cmkey(adlc0tab,nadlc0tab,"",
4620 "processed-by-emulator",xxstring)) < 0)
4622 if ((x = cmcfm()) < 0)
4627 if ((y = cmkey(adldtab,nadldtab,"","packet",xxstring)) < 0)
4629 if ((x = cmcfm()) < 0)
4634 if ((y = cmtxt("Kermit start string","KERMIT READY TO SEND...",
4638 adl_kstr = strdup(s);
4644 if ((y = cmkey(adlxtab,nadlxtab,"","",xxstring)) < 0)
4648 if ((y = cmkey(adlc0tab,nadlc0tab,"",
4649 "processed-by-emulator",xxstring)) < 0)
4651 if ((x = cmcfm()) < 0)
4656 if ((y = cmkey(adldtab,nadldtab,"","packet",xxstring)) < 0)
4658 if ((x = cmcfm()) < 0)
4663 if ((y = cmtxt("","rz\\{13}",&s,xxstring)) < 0)
4666 adl_zstr = strdup(s);
4672 return(success = 1);
4674 #endif /* CK_AUTODL */
4679 return(success = setbell());
4681 case XYTMBEL: /* MARGIN-BELL */
4682 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
4684 if ((z = cmnum("Column at which to set margin bell",
4685 "72",10,&x,xxstring)) < 0)
4688 if ((z = cmcfm()) < 0) return(z);
4691 return(success = 1);
4695 case XYTIDLE: /* IDLE-SEND */
4696 case XYTITMO: /* IDLE-TIMEOUT */
4697 if ((z = cmnum("seconds of idle time to wait, or 0 to disable",
4698 "0",10,&x,xxstring)) < 0)
4701 if ((y = cmtxt("string to send, may contain kverbs and variables",
4702 "\\v(newline)",&s,xxstring)) < 0)
4704 tt_idlesnd_tmo = x; /* (old) */
4705 tt_idlelimit = x; /* (new) */
4706 makestr(&tt_idlestr,brstrip(s)); /* (new) */
4707 tt_idlesnd_str = tt_idlestr; /* (old) */
4708 tt_idleact = IDLE_OUT; /* (new) */
4710 if ((y = cmcfm()) < 0)
4717 return(success = 1);
4719 case XYTIACT: { /* SET TERM IDLE-ACTION */
4720 if ((y = cmkey(idlacts,nidlacts,"","",xxstring)) < 0)
4722 if (y == IDLE_OUT) {
4723 if ((x = cmtxt("string to send, may contain kverbs and variables"
4724 , "\\v(newline)",&s,xxstring)) < 0)
4726 makestr(&tt_idlestr,brstrip(s)); /* (new) */
4727 tt_idlesnd_str = tt_idlestr; /* (old) */
4729 if ((x = cmcfm()) < 0)
4733 return(success = 1);
4735 #endif /* CKTIDLE */
4737 case XYTDEB: /* TERMINAL DEBUG */
4738 y = seton(&x); /* Go parse ON or OFF */
4739 if (y > 0) /* Command succeeded? */
4744 case XYTASCRL: /* SET TERMINAL AUTOSCROLL */
4745 y = seton(&autoscroll);
4748 case XYTAPAGE: /* SET TERMINAL AUTOPAGE */
4749 y = seton(&wy_autopage);
4752 case XYTROL: /* SET TERMINAL ROLL */
4753 if ((y = cmkey(rolltab,nroll,"scrollback mode","insert",xxstring))<0)
4755 if (y == TTR_KEYS) {
4756 if ((x = cmkey(rollkeytab,nrollkey,"","send",xxstring))<0)
4758 if ((z = cmcfm()) < 0) return(z);
4759 tt_rkeys[VTERM] = x;
4761 if ((x = cmcfm()) < 0) return(x);
4764 return(success = 1);
4766 case XYTCTS: /* SET TERMINAL TRANSMIT-TIMEOUT */
4767 y = cmnum("Maximum seconds to allow CTS off during CONNECT",
4768 "5",10,&x,xxstring);
4769 return(setnum(&tt_ctstmo,x,y,10000));
4771 case XYTCPG: { /* SET TERMINAL CODE-PAGE */
4774 y = cmnum("PC code page to use during terminal emulation",
4775 ckitoa(os2getcp()),10,&x,xxstring);
4776 if ((x = setnum(&cp,x,y,11000)) < 0) return(x);
4777 if (os2setcp(cp) != 1) {
4781 "Sorry, Windows 95 does not support code page switching\n");
4785 "Sorry, %d is not a valid code page for this system.\n",cp);
4788 /* Force the terminal character-sets conversions to be updated */
4789 for ( i = 0; i < 4; i++ )
4794 case XYTPAC: /* SET TERMINAL OUTPUT-PACING */
4796 "Pause between sending each character during CONNECT, milliseconds",
4797 "-1",10,&x,xxstring);
4798 return(setnum(&tt_pacing,x,y,10000));
4801 case XYTMOU: { /* SET TERMINAL MOUSE */
4802 int old_mou = tt_mouse;
4803 if ((x = seton(&tt_mouse)) < 0)
4805 if (tt_mouse != old_mou)
4812 #endif /* OS2MOUSE */
4818 "number of columns in display window during CONNECT",
4820 "number of columns on your screen",
4822 "80",10,&x,xxstring)) < 0)
4824 if ((y = cmcfm()) < 0) return(y);
4826 return(success = os2_settermwidth(x));
4827 #else /* Not OS/2 */
4829 return(success = 1);
4836 "number of rows in display window during CONNECT, not including status line",
4837 tt_status[VTERM]?"24":"25",
4839 "24","number of rows on your screen",
4841 10,&x,xxstring)) < 0)
4843 if ((y = cmcfm()) < 0) return(y);
4846 return (success = os2_settermheight(x));
4847 #else /* Not OS/2 */
4849 return(success = 1);
4853 case XYTPRN: { /* Print Mode */
4854 extern bool xprint, aprint, cprint, uprint;
4855 if ((y = cmkey(prnmtab,nprnmtab,"","off", xxstring)) < 0) return(y);
4856 if ((x = cmcfm()) < 0) return(x);
4859 if (cprint || uprint || aprint || xprint)
4861 cprint = xprint = uprint = 0;
4865 if (!(cprint || uprint || aprint || xprint))
4868 cprint = xprint = uprint = 0;
4871 if (!(cprint || uprint || aprint || xprint))
4875 xprint = uprint = 0;
4878 if (!(cprint || uprint || aprint || xprint))
4882 xprint = cprint = 0;
4890 extern int tt_print;
4891 if ((x = seton(&tt_print)) < 0)
4893 return(success = 1);
4900 extern int decscnm, decscnm_usr;
4901 if ((y = cmkey(normrev,4,"",
4902 decscnm_usr?"reverse":"normal",
4906 if ((x = cmcfm()) < 0) return(x);
4908 if (decscnm != decscnm_usr)
4913 if ((y = cmkey(onoff,2,"",tt_diff_upd?"on":"off",
4914 xxstring)) < 0) return(y);
4915 if ((x = cmcfm()) < 0) return(x);
4920 if ((mode = cmkey(scrnupd,nscrnupd,"","fast",xxstring)) < 0) {
4924 "Pause between FAST screen updates in CONNECT mode, milliseconds",
4925 "100",10,&x,xxstring
4927 if (x < 0 || x > 1000 ) {
4929 "\n?The update rate must be between 0 and 1000 milliseconds.\n"
4931 return(success = 0);
4933 if ((y = cmcfm()) < 0) return(y);
4935 updmode = tt_updmode = mode;
4936 return(setnum(&tt_update,x,y,10000));
4940 if ((x = cmkey(termctrl,ntermctrl,"","7",xxstring)) < 0) {
4943 if ((y = cmcfm()) < 0)
4947 send_c1 = send_c1_usr = TRUE;
4951 send_c1 = send_c1_usr = FALSE;
4955 return(success = TRUE);
4960 if ( !IsOS2FullScreen() ) {
4962 "\n?SET TERMINAL FONT is only supported in Full Screen sessions.\n");
4963 return(success = FALSE);
4966 if ((x = cmkey(term_font,ntermfont,"","default",xxstring)) < 0) {
4969 if ((y = cmcfm()) < 0) return(y);
4970 if ( !os2LoadPCFonts() ) {
4972 return(success = TRUE);
4975 "\n?PCFONTS.DLL is not available in CKERMIT executable directory.\n");
4976 return(success = FALSE);
4984 return(setguifont()); /* ckuus3.c */
4987 #endif /* PCFONTS */
4990 extern int pheight, marginbot, cmd_rows, cmd_cols;
4991 if ((x = cmkey(tvctab,ntvctab,"",isWin95()?"win95-safe":"enabled",
4994 if ((y = cmcfm()) < 0) return(y);
4996 if (x != tt_modechg) {
4999 /* When disabled the heights of all of the virtual screens */
5000 /* must be equal to the physical height of the console */
5001 /* window and may not be changed. */
5002 /* The width of the window may not be altered. */
5003 tt_modechg = TVC_ENA; /* Temporary */
5004 if (marginbot > pheight-(tt_status[VTERM]?1:0))
5005 marginbot = pheight-(tt_status[VTERM]?1:0);
5006 tt_szchng[VCMD] = 1 ;
5007 tt_rows[VCMD] = pheight;
5012 tt_szchng[VTERM] = 2 ;
5013 tt_rows[VTERM] = pheight - (tt_status[VTERM]?1:0);
5019 /* When enabled the physical height of the console windows */
5020 /* should be adjusted to the height of the virtual screen */
5021 /* The width may be set to anything. */
5026 /* Win95-safe mode allows the physical height to change */
5027 /* but restricts it to a width of 80 and a height equal to */
5028 /* 25, 43, or 50. Must be adjusted now. */
5029 /* The virtual heights must be equal to the above. */
5030 if (pheight != 25 && pheight != 43 && pheight != 50) {
5033 else if (pheight < 43)
5040 tt_modechg = TVC_ENA; /* Temporary */
5042 tt_szchng[VCMD] = 1;
5050 marginbot = y-(tt_status[VTERM]?1:0);
5051 tt_szchng[VTERM] = 2;
5052 tt_rows[VTERM] = y - (tt_status[VTERM]?1:0);
5053 tt_cols[VTERM] = 80;
5059 return(success = 1);
5061 return(success = 0);
5065 extern int marginbot;
5066 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5067 if ((x = cmcfm()) < 0) return(x);
5068 if (y != tt_status[VTERM] || y != tt_status_usr[VTERM]) {
5069 /* Might need to fixup the margins */
5070 if ( marginbot == VscrnGetHeight(VTERM)-(tt_status[VTERM]?1:0) )
5076 tt_status_usr[VTERM] = tt_status[VTERM] = y;
5078 tt_szchng[VTERM] = 2;
5080 VscrnInit(VTERM); /* Height set here */
5082 if (TELOPT_ME(TELOPT_NAWS))
5086 if (TELOPT_ME(TELOPT_NAWS))
5088 #endif /* RLOGCODE */
5090 if (TELOPT_ME(TELOPT_NAWS))
5092 #endif /* SSHBUILTIN */
5094 tt_szchng[VTERM] = 1;
5096 VscrnInit(VTERM); /* Height set here */
5098 if (TELOPT_ME(TELOPT_NAWS))
5102 if (TELOPT_ME(TELOPT_NAWS))
5104 #endif /* RLOGCODE */
5106 if (TELOPT_ME(TELOPT_NAWS))
5108 #endif /* SSHBUILTIN */
5117 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5118 if ((x = cmcfm()) < 0) return(x);
5125 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5126 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(ttyseobtab,2,"","us_cr",xxstring)) < 0) return(y);
5138 if ((x = cmcfm()) < 0) return(x);
5143 int done = 0, attr = VT_CHAR_ATTR_NORMAL;
5145 if ((x = cmkey(onoff,2,"","on",xxstring)) < 0)
5150 if ((y = cmkey(ttyprotab,nprotect,"",
5151 z?"done":"reverse",xxstring)) < 0)
5158 attr |= VT_CHAR_ATTR_BLINK;
5161 attr |= VT_CHAR_ATTR_REVERSE;
5164 attr |= VT_CHAR_ATTR_ITALIC;
5167 attr |= VT_CHAR_ATTR_UNDERLINE;
5170 attr |= VT_CHAR_ATTR_BOLD;
5173 attr |= VT_CHAR_ATTR_DIM;
5176 attr |= VT_CHAR_ATTR_INVISIBLE;
5181 z = 1; /* One attribute has been chosen */
5184 if ((z = cmcfm()) < 0) return(z);
5187 tt_url_hilite_attr = attr;
5191 if ((x = cmkey(ttyattrtab,nattrib,"","underline",xxstring)) < 0)
5195 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5196 if ((x = cmcfm()) < 0) return(x);
5199 if ( !trueblink && trueunderline ) {
5201 printf("Warning: Underline being simulated by color.\n");
5208 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5209 if ((x = cmcfm()) < 0) return(x);
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);
5224 if (!trueblink && trueunderline) {
5226 printf("Warning: True blink mode is active.\n");
5232 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5233 if ((x = cmcfm()) < 0) return(x);
5237 case TTATTPRO: { /* Set default Protected Character attribute */
5238 extern vtattrib WPattrib; /* current WP Mode Attrib */
5239 extern vtattrib defWPattrib; /* default WP Mode Attrib */
5240 vtattrib wpa = {0,0,0,0,0,1,0,0,0,0,0}; /* Protected */
5245 if ((y = cmkey(ttyprotab,nprotect,"",
5246 x?"done":"dim",xxstring)) < 0)
5251 case TTATTBLI: /* Blinking doesn't work */
5252 wpa.blinking = TRUE;
5255 wpa.reversed = TRUE;
5261 wpa.underlined = TRUE;
5270 wpa.invisible = TRUE ;
5276 x = 1; /* One attribute has been chosen */
5278 if ((x = cmcfm()) < 0) return(x);
5279 WPattrib = defWPattrib = wpa;
5285 case XYTKEY: { /* SET TERMINAL KEY */
5287 int clear = 0, deflt = 0;
5290 int kc = -1; /* Key code */
5291 int litstr = 0; /* Literal String? */
5292 char *s = NULL; /* Key binding */
5294 char *p = NULL; /* Worker */
5295 #endif /* NOKVERBS */
5300 struct FDB kw,sw,nu,cm;
5302 defevt.type = error;
5304 if ((t = cmkey(ttkeytab,nttkey,"","",xxstring)) < 0)
5306 cmfdbi(&nu, /* First FDB - command switches */
5308 "/literal, keycode, or action",
5310 "", /* addtl string data */
5311 10, /* addtl numeric data 1: radix */
5312 0, /* addtl numeric data 2: 0 */
5313 xxstring, /* Processing function */
5314 NULL, /* Keyword table */
5315 &sw /* Pointer to next FDB */
5317 cmfdbi(&sw, /* Second FDB - switches */
5321 "", /* addtl string data */
5322 nstrmswitab, /* addtl numeric data 1: tbl size */
5323 4, /* addtl numeric data 2: 4 = cmswi */
5324 xxstring, /* Processing function */
5325 strmswitab, /* Keyword table */
5326 &kw /* Pointer to next FDB */
5328 cmfdbi(&kw, /* Third FDB - command switches */
5330 "/literal, keycode, or action",
5332 "", /* addtl string data */
5333 nstrmkeytab, /* addtl numeric data 1: tbl size */
5334 0, /* addtl numeric data 2 */
5335 xxstring, /* Processing function */
5336 strmkeytab, /* Keyword table */
5337 &cm /* Pointer to next FDB */
5339 cmfdbi(&cm, /* Final FDB - Confirmation */
5343 "", /* addtl string data */
5344 0, /* addtl numeric data 1: tbl size */
5345 0, /* addtl numeric data 2: 4 = cmswi */
5346 xxstring, /* Processing function */
5347 NULL, /* Keyword table */
5348 NULL /* Pointer to next FDB */
5351 x = cmfdb(&nu); /* Parse something */
5355 switch (cmresult.fcode) {
5357 printf(" Press key to be defined: ");
5358 conbin((char)escape); /* Put terminal in binary mode */
5359 os2gks = 0; /* Turn off Kverb preprocessing */
5360 kc = congks(0); /* Get character or scan code */
5361 os2gks = 1; /* Turn on Kverb preprocessing */
5362 concb((char)escape); /* Restore terminal to cbreak mode */
5363 if (kc < 0) { /* Check for error */
5364 printf("?Error reading key\n");
5367 shokeycode(kc,t); /* Show current definition */
5368 flag = 1; /* Remember it's a multiline command */
5371 kc = cmresult.nresult;
5374 if (cmresult.fdbaddr == &sw) { /* Switch */
5375 if (cmresult.nresult == 0)
5377 } else if (cmresult.fdbaddr == &kw) { /* Keyword */
5378 if (cmresult.nresult == 0)
5382 if ((x = cmcfm()) < 0)
5394 /* Normal SET TERMINAL KEY <terminal> <scancode> <value> command... */
5399 if (kc < 0 || kc >= KMSIZE) {
5400 printf("?key code must be between 0 and %d\n", KMSIZE - 1);
5404 printf("Sorry, %d is the CONNECT-mode escape character\n",kc);
5409 cmsavp(psave,PROMPTL);
5410 cmsetp(" Enter new definition: ");
5414 if (flag) prompt(NULL);
5415 if ((y = cmtxt("key definition,\n\
5416 or Ctrl-C to cancel this command,\n\
5417 or Enter to restore default definition",
5419 if (flag) /* Handle parse errors */
5426 p = s; /* Save this place */
5427 #endif /* NOKVERBS */
5429 If the definition included any \Kverbs, quote the backslash so the \Kverb
5430 will still be in the definition when the key is pressed. We don't do this
5431 in zzstring(), because \Kverbs are valid only in this context and nowhere
5434 We use this code active for all versions that support SET KEY, even if they
5435 don't support \Kverbs, because otherwise \K would behave differently for
5438 for (x = 0, y = 0; s[x]; x++, y++) { /* Convert \K to \\K */
5440 (s[x] == 'K' || s[x] == 'k')
5443 if ((x == 1 && s[x-1] == CMDQ) ||
5444 (x > 1 && s[x-1] == CMDQ && s[x-2] != CMDQ)) {
5445 line[y++] = CMDQ; /* Make it \\K */
5447 if (x > 1 && s[x-1] == '{' && s[x-2] == CMDQ) {
5448 line[y-1] = CMDQ; /* Have \{K */
5449 line[y++] = '{'; /* Make it \\{K */
5454 line[y++] = NUL; /* Terminate */
5455 s = line + y + 1; /* Point to after it */
5456 x = LINBUFSIZ - (int) strlen(line) - 1; /* Get remaining space */
5457 if ((x < (LINBUFSIZ / 2)) ||
5458 (zzstring(line, &s, &x) < 0)) { /* Expand variables, etc. */
5459 printf("?Key definition too long\n");
5460 if (flag) cmsetp(psave);
5463 s = line + y + 1; /* Point to result. */
5467 Special case: see if the definition starts with a \Kverb.
5468 If it does, point to it with p, otherwise set p to NULL.
5473 p = (*p == 'k' || *p == 'K') ? p + 1 : NULL;
5475 #endif /* NOKVERBS */
5477 switch (strlen(s)) { /* Action depends on length */
5478 case 0: /* Clear individual key def */
5483 defevt.type = key; /* Single character */
5484 defevt.key.scancode = *s;
5487 default: /* Character string */
5490 y = xlookup(kverbs,p,nkverbs,&x); /* Look it up */
5491 /* Need exact match */
5492 debug(F101,"set key kverb lookup",0,y);
5494 defevt.type = kverb;
5495 defevt.kverb.id = y;
5499 #endif /* NOKVERBS */
5501 defevt.type = literal;
5502 defevt.literal.string = (char *) malloc(strlen(s)+1);
5503 if (defevt.literal.string)
5504 strcpy(defevt.literal.string, s); /* safe */
5506 defevt.type = macro;
5507 defevt.macro.string = (char *) malloc(strlen(s)+1);
5508 if (defevt.macro.string)
5509 strcpy(defevt.macro.string, s); /* safe */
5513 insertkeymap(t, kc, defevt);
5516 initvik = 1; /* Update VIK table */
5521 case XYTPCTERM: /* PCTERM Keyboard Mode */
5522 if ((x = seton(&tt_pcterm)) < 0) return(x);
5523 return(success = 1);
5529 if ((y = cmtxt("String to trigger automatic return to command mode",
5530 "",&s,xxstring)) < 0)
5532 makelist(s,tt_trigger,TRIGGERS);
5534 #endif /* CK_TRIGGER */
5538 if ((y = cmnum("ASCII value to use for spacing attributes",
5539 "32",10,&x,xxstring)) < 0)
5541 if ((y = cmcfm()) < 0) return(y);
5543 return(success = 1);
5545 case XYTKBDGL: { /* SET TERM KBD-FOLLOWS-GL/GR */
5546 extern int tt_kb_glgr; /* from ckoco3.c */
5547 if ((x = seton(&tt_kb_glgr)) < 0)
5549 return(success = 1);
5552 case XYTVTLNG: /* SET TERM DEC-LANGUAGE */
5553 if ((y = cmkey(vtlangtab,nvtlangtab,"VT language",
5554 IS97801(tt_type_mode)?"german":"north-american",
5557 if ((x = cmcfm()) < 0) return(x);
5559 /* A real VT terminal would use the language to set the */
5560 /* default keyboard language for both 8-bit multinational */
5561 /* and 7-bit national modes. For 8-bit mode it would */
5562 /* set the terminal character-set to the ISO set if it */
5563 /* is not already set. */
5564 /* Latin-1 can be replaced by DEC Multinational */
5566 case VTL_NORTH_AM: /* North American */
5567 /* Multinational: Latin-1 */
5568 /* National: US_ASCII */
5571 dec_kbd = TX_8859_1;
5574 /* Multinational: Latin-1 */
5575 /* National: UK_ASCII */
5577 dec_nrc = TX_BRITISH;
5578 dec_kbd = TX_8859_1;
5583 /* Multinational: Latin-1 */
5584 /* National: FR_ASCII */
5586 dec_nrc = TX_FRENCH;
5587 dec_kbd = TX_8859_1;
5590 /* Multinational: Latin-1 */
5591 /* National: FC_ASCII */
5593 dec_nrc = TX_CN_FRENCH;
5594 dec_kbd = TX_8859_1;
5598 /* Multinational: Latin-1 */
5599 /* National: NO_ASCII */
5601 dec_nrc = TX_NORWEGIAN;
5602 dec_kbd = TX_8859_1;
5605 /* Multinational: Latin-1 */
5606 /* National: FI_ASCII */
5608 dec_nrc = TX_FINNISH;
5609 dec_kbd = TX_8859_1;
5612 /* Multinational: Latin-1 */
5613 /* National: GR_ASCII */
5615 dec_nrc = TX_GERMAN;
5616 dec_kbd = TX_8859_1;
5619 /* Multinational: Latin-1 */
5620 /* National: DU_ASCII */
5623 dec_kbd = TX_8859_1;
5626 /* Multinational: Latin-1 */
5627 /* National: IT_ASCII */
5629 dec_nrc = TX_ITALIAN;
5630 dec_kbd = TX_8859_1;
5634 /* Multinational: Latin-1 */
5635 /* National: CH_ASCII */
5638 dec_kbd = TX_8859_1;
5641 /* Multinational: Latin-1 */
5642 /* National: SW_ASCII */
5644 dec_nrc = TX_SWEDISH;
5645 dec_kbd = TX_8859_1;
5648 /* Multinational: Latin-1 */
5649 /* National: SP_ASCII */
5651 dec_nrc = TX_SPANISH;
5652 dec_kbd = TX_8859_1;
5655 /* Multinational: Latin-1 */
5656 /* National: Portugese ASCII */
5658 dec_nrc = TX_PORTUGUESE;
5659 dec_kbd = TX_8859_1;
5662 /* Multinational: Latin-Hebrew / DEC-Hebrew */
5663 /* National: DEC 7-bit Hebrew */
5666 dec_kbd = TX_8859_8;
5669 /* Multinational: Latin-Greek / DEC-Greek */
5670 /* National: DEC Greek NRC */
5671 /* is ELOT927 equivalent to DEC Greek???? */
5673 dec_nrc = TX_ELOT927;
5674 dec_kbd = TX_8859_7;
5679 /* Multinational: Latin-Turkish / DEC-Turkish */
5680 /* National: DEC 7-bit Turkish */
5682 #endif /* COMMENT */
5684 /* Multinational: Latin-2 */
5685 /* National: no national mode */
5687 dec_nrc = TX_HUNGARIAN;
5688 dec_kbd = TX_8859_2;
5694 /* Multinational: Latin-2 */
5695 /* National: no national mode */
5698 dec_kbd = TX_8859_2;
5701 /* Multinational: Latin-Cyrillic / KOI-8 */
5702 /* National: DEC Russian NRC */
5705 dec_kbd = TX_8859_5;
5708 /* Multinational: not listed in table */
5709 /* National: not listed in table */
5712 dec_kbd = TX_8859_1;
5716 /* Multinational: Latin-2 */
5717 /* National: SCS NRC */
5719 #endif /* COMMENT */
5721 return(success = 0);
5723 if (IS97801(tt_type_mode)) {
5724 SNI_bitmode(cmask == 0377 ? 8 : 7);
5726 return(success = 1);
5727 #endif /* NOCSETS */
5729 case XYTVTNRC: { /* SET TERM DEC-NRC-MODE */
5730 extern int decnrcm_usr, decnrcm; /* from ckoco3.c */
5731 if ((x = seton(&decnrcm_usr)) < 0)
5733 decnrcm = decnrcm_usr;
5734 return(success = 1);
5736 case XYTSNIPM: { /* SET TERM SNI-PAGEMODE */
5737 extern int sni_pagemode, sni_pagemode_usr;
5738 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5739 if ((x = cmcfm()) < 0) return(x);
5740 sni_pagemode_usr = sni_pagemode = y;
5741 return(success = 1);
5743 case XYTSNISM: { /* SET TERM SNI-SCROLLMODE */
5744 extern int sni_scroll_mode, sni_scroll_mode_usr;
5745 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5746 if ((x = cmcfm()) < 0) return(x);
5747 sni_scroll_mode_usr = sni_scroll_mode = y;
5748 return(success = 1);
5750 case XYTSNICC: { /* SET TERM SNI-CH.CODE */
5751 extern int sni_chcode_usr;
5752 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
5753 if ((x = cmcfm()) < 0) return(x);
5756 return(success = 1);
5758 case XYTSNIFV: { /* SET TERM SNI-FIRMWARE-VERSIONS */
5759 extern CHAR sni_kbd_firmware[], sni_term_firmware[];
5760 CHAR kbd[7],term[7];
5762 if ((x = cmfld("Keyboard Firmware Version",sni_kbd_firmware,
5765 if ((int)strlen(s) != 6) {
5766 printf("?Sorry - the firmware version must be 6 digits long\n");
5769 for (i = 0; i < 6; i++) {
5770 if (!isdigit(s[i])) {
5771 printf("?Sorry - the firmware version can only contain digits [0-9]\n");
5777 if ((x = cmfld("Terminal Firmware Version",sni_term_firmware,
5780 if ((int)strlen(s) != 6) {
5781 printf("?Sorry - the firmware version must be 6 digits long\n");
5784 for (i = 0; i < 6; i++) {
5785 if (!isdigit(s[i])) {
5786 printf("?Sorry - the firmware version can only contain digits [0-9]\n");
5790 ckstrncpy(term,s,7);
5791 if ((x = cmcfm()) < 0) return(x);
5793 ckstrncpy(sni_kbd_firmware,kbd,7);
5794 ckstrncpy(sni_term_firmware,term,7);
5795 return(success = 1);
5798 case XYTLSP: { /* SET TERM LINE-SPACING */
5799 if ((x = cmfld("Line Spacing","1",&s, xxstring)) < 0)
5801 if (isfloat(s,0) < 1) { /* (sets floatval) */
5802 printf("?Integer or floating-point number required\n");
5805 if (floatval < 1.0 || floatval > 3.0) {
5806 printf("?Value must within the range 1.0 and 3.0 (inclusive)\n");
5809 if ((x = cmcfm()) < 0) return(x);
5811 tt_linespacing[VCMD] = tt_linespacing[VTERM] = floatval;
5812 return(success = 1);
5814 printf("?Sorry, Line-spacing is only supported in K95G.EXE.\n");
5815 return(success = 0);
5820 default: /* Shouldn't get here. */
5826 This was supposed to shut up picky compilers but instead it makes
5827 most compilers complain about "statement not reached".
5830 #endif /* COMMENT */
5839 extern char usertitle[];
5840 if ((y = cmtxt("title text","",&s,xxstring)) < 0)
5844 printf("?Sorry, command disabled.\r\n");
5845 return(success = 0);
5849 ckstrncpy(usertitle,s,64);
5854 static struct keytab dialertab[] = { /* K95 Dialer types */
5858 static int ndialer = 2;
5863 int clear = 0, deflt = 0;
5864 int kc; /* Key code */
5865 char *s = NULL; /* Key binding */
5867 char *p = NULL; /* Worker */
5868 #endif /* NOKVERBS */
5874 defevt.type = error;
5876 if (( x = cmkey(dialertab, ndialer,
5877 "Kermit-95 dialer work-arounds",
5878 "", xxstring)) < 0 )
5881 case 0: /* Backspace */
5888 printf("Illegal value in setdialer()\n");
5891 if ((y = cmtxt("Key definition","",&s,xxstring)) < 0)
5896 printf("?Sorry, command disabled.\r\n");
5897 return(success = 0);
5902 p = s; /* Save this place */
5903 #endif /* NOKVERBS */
5905 If the definition included any \Kverbs, quote the backslash so the \Kverb
5906 will still be in the definition when the key is pressed. We don't do this
5907 in zzstring(), because \Kverbs are valid only in this context and nowhere
5910 We use this code active for all versions that support SET KEY, even if they
5911 don't support \Kverbs, because otherwise \K would behave differently for
5914 for (x = 0, y = 0; s[x]; x++, y++) { /* Convert \K to \\K */
5916 (s[x] == 'K' || s[x] == 'k')
5919 if ((x == 1 && s[x-1] == CMDQ) ||
5920 (x > 1 && s[x-1] == CMDQ && s[x-2] != CMDQ)) {
5921 line[y++] = CMDQ; /* Make it \\K */
5923 if (x > 1 && s[x-1] == '{' && s[x-2] == CMDQ) {
5924 line[y-1] = CMDQ; /* Have \{K */
5925 line[y++] = '{'; /* Make it \\{K */
5930 line[y++] = NUL; /* Terminate */
5931 s = line + y + 1; /* Point to after it */
5932 x = LINBUFSIZ - (int) strlen(line) - 1; /* Calculate remaining space */
5933 if ((x < (LINBUFSIZ / 2)) ||
5934 (zzstring(line, &s, &x) < 0)) { /* Expand variables, etc. */
5935 printf("?Key definition too long\n");
5938 s = line + y + 1; /* Point to result. */
5942 Special case: see if the definition starts with a \Kverb.
5943 If it does, point to it with p, otherwise set p to NULL.
5948 p = (*p == 'k' || *p == 'K') ? p + 1 : NULL;
5950 #endif /* NOKVERBS */
5952 /* Clear the definition for SET KEY */
5953 if (macrotab[kc]) { /* Possibly free old macro from key. */
5954 free((char *)macrotab[kc]);
5955 macrotab[kc] = NULL;
5957 keymap[kc] = (KEY) kc;
5959 /* Now reprogram the default value for all terminal types */
5960 /* remember to treat Wyse and Televideo terminals special */
5961 /* because of their use of Kverbs for Backspace and Enter */
5962 for (t = 0; t <= TT_MAX; t++) {
5963 if ( ISDG200(t) && kc == 264) {
5964 extern char * udkfkeys[] ;
5965 if (kc == 264) { /* \Kdgbs */
5968 udkfkeys[83] = strdup(s);
5970 } else if (ISWYSE(t) || ISTVI(t)) {
5971 extern char * udkfkeys[] ;
5972 if (kc == 264) { /* \Kwybs or \Ktvibs */
5975 udkfkeys[32] = strdup(s);
5977 if (kc == 269) { /* \Kwyenter and \Kwyreturn */
5978 if (udkfkeys[39]) /* \Ktvienter and \Ktvireturn */
5980 udkfkeys[39] = strdup(s);
5983 udkfkeys[49] = strdup(s);
5986 switch (strlen(s)) { /* Action depends on length */
5987 case 0: /* Clear individual key def */
5991 defevt.type = key; /* Single character */
5992 defevt.key.scancode = *s;
5994 default: /* Character string */
5997 y = xlookup(kverbs,p,nkverbs,&x); /* Look it up */
5998 /* Exact match req'd */
5999 debug(F101,"set key kverb lookup",0,y);
6001 defevt.type = kverb;
6002 defevt.kverb.id = y;
6006 #endif /* NOKVERBS */
6007 defevt.type = macro;
6008 defevt.macro.string = (char *) malloc(strlen(s)+1);
6009 if (defevt.macro.string)
6010 strcpy(defevt.macro.string, s); /* safe */
6013 insertkeymap( t, kc, defevt ) ;
6014 initvik = 1; /* Update VIK table */
6026 if (( y = cmkey(win95tab, nwin95,
6027 "Windows 95 specific work-arounds",
6028 "keyboard-translation",
6033 if ((y = cmkey(onoff,2,"popups are used to prompt the user for data",
6034 "on",xxstring)) < 0)
6036 if ((x = cmcfm()) < 0) return(x);
6041 if ((y = cmkey(onoff,2,"8.3 FAT file names","off",xxstring)) < 0)
6043 if ((x = cmcfm()) < 0) return(x);
6048 if ((y = cmkey(onoff,2,"\"select()\" fails on write","off",
6051 if ((x = cmcfm()) < 0) return(x);
6056 if ((y = cmkey(onoff,2,"Right-Alt is Alt-Gr","off",xxstring)) < 0)
6058 if ((x = cmcfm()) < 0) return(x);
6063 if ((y = cmkey(onoff,2,"Use Overlapped I/O","on",xxstring)) < 0)
6066 if ((x = cmnum("Maximum number of outstanding I/O requests",
6067 "10",10,&z,xxstring)) < 0)
6069 if (z < 1 || z > 7) {
6071 "?Maximum outstanding I/O requests must be between 1 and 7.\n");
6076 if ((x = cmcfm()) < 0) return(x);
6078 maxow = maxow_usr = z;
6083 printf("\n?\"Keyboard-Translation\" is no longer required.\n");
6086 if (( z = cmkey(tcstab, ntcs,
6087 "Keyboard Character Set",
6091 if ((x = cmcfm()) < 0)
6095 win95kl2 = (win95kcsi == TC_2LATIN);
6097 if (win95kcsi == TC_TRANSP) {
6101 win95kcs = xlr[win95kcsi][tx2fc(tcsl)];
6103 win95kcs = xlr[win95kcsi][tcsl];
6104 #endif /* UNICODE */
6107 #endif /* COMMENT */
6110 if ((y = cmkey(onoff,2,"Unicode-to-Lucida-Console substitutions",
6111 "on",xxstring)) < 0)
6113 if ((x = cmcfm()) < 0) return(x);
6118 if ((y = cmkey(onoff,2,"Horizontal Scan Line substitutions",
6119 "on",xxstring)) < 0)
6121 if ((x = cmcfm()) < 0) return(x);
6126 printf("Illegal value in setwin95()\n");
6137 #endif /* CK_ANSIC */
6141 if (( y = cmkey(prtytab, nprty,
6142 "priority level of terminal and communication threads",
6143 "foreground-server",
6147 if ((x = cmcfm()) < 0)
6155 #endif /* IKSDCONF */
6157 if ((y = cmcfm()) < 0) return(y);
6158 printf("?Sorry, command disabled.\r\n");
6159 return(success = 0);
6174 if ((y = cmkey(beltab,nbeltab,
6176 "how console and terminal bells should\nbe generated", "audible",
6178 "Whether Kermit should ring the terminal bell (beep)", "on",
6185 if ((y = cmcfm()) < 0) return(y);
6186 printf("?Sorry, command disabled.\r\n");
6187 return(success = 0);
6191 switch (y) { /* SET BELL */
6196 if ((x = cmcfm()) < 0)
6207 if ((x = cmkey(audibletab, naudibletab,
6208 "how audible console and terminal\nbells should be generated",
6209 "beep",xxstring))<0)
6211 if ((z = cmcfm()) < 0)
6215 /* This lets C-Kermit accept but ignore trailing K95 keywords */
6216 if ((x = cmtxt("Confirm with carriage return","",&s,xxstring)) < 0)
6230 #endif /* CK_ANSIC */
6233 int button = 0, event = 0;
6236 if ((y = cmkey(mousetab,nmtab,"","",xxstring)) < 0)
6241 if ((y = cmcfm()) < 0) return(y);
6242 printf("?Sorry, command disabled.\r\n");
6243 return(success = 0);
6247 if (y == XYM_ON) { /* MOUSE ACTIVATION */
6248 int old_mou = tt_mouse;
6249 if ((x = seton(&tt_mouse)) < 0)
6251 if (tt_mouse != old_mou)
6259 if (y == XYM_DEBUG) { /* MOUSE DEBUG */
6260 extern int MouseDebug;
6261 if ((x = seton(&MouseDebug)) < 0)
6266 if (y == XYM_CLEAR) { /* Reset Mouse Defaults */
6267 if ((x = cmcfm()) < 0) return(x);
6268 mousemapinit(-1,-1);
6269 initvik = 1; /* Update VIK Table */
6272 if (y != XYM_BUTTON) { /* Shouldn't happen. */
6273 printf("Internal parsing error\n");
6277 /* MOUSE EVENT ... */
6279 if ((button = cmkey(mousebuttontab,nmbtab,
6280 "Button number","1",
6284 if ((y = cmkey(mousemodtab,nmmtab,
6285 "Keyboard modifier","none",
6289 event |= y; /* OR in the bits */
6291 if ((y = cmkey(mclicktab,nmctab,"","click",xxstring)) < 0)
6294 /* Two bits are assigned, if neither are set then it is button one */
6296 event |= y; /* OR in the bit */
6300 if ((y = cmtxt("definition,\n\
6301 or Ctrl-C to cancel this command,\n\
6302 or Enter to restore default definition",
6307 p = s; /* Save this place */
6309 If the definition included any \Kverbs, quote the backslash so the \Kverb
6310 will still be in the definition when the key is pressed. We don't do this
6311 in zzstring(), because \Kverbs are valid only in this context and nowhere
6312 else. This code copied from SET KEY, q.v. for addt'l commentary.
6314 for (x = 0, y = 0; s[x]; x++, y++) { /* Convert \K to \\K */
6316 (s[x] == 'K' || s[x] == 'k')
6319 if ((x == 1 && s[x-1] == CMDQ) ||
6320 (x > 1 && s[x-1] == CMDQ && s[x-2] != CMDQ)) {
6321 line[y++] = CMDQ; /* Make it \\K */
6323 if (x > 1 && s[x-1] == '{' && s[x-2] == CMDQ) {
6324 line[y-1] = CMDQ; /* Have \{K */
6325 line[y++] = '{'; /* Make it \\{K */
6330 line[y++] = NUL; /* Terminate */
6331 s = line + y + 1; /* Point to after it */
6332 x = LINBUFSIZ - (int) strlen(line) - 1; /* Calculate remaining space */
6333 if ((x < (LINBUFSIZ / 2)) ||
6334 (zzstring(line, &s, &x) < 0)) { /* Expand variables, etc. */
6335 printf("?Key definition too long\n");
6338 s = line + y + 1; /* Point to result. */
6342 Special case: see if the definition starts with a \Kverb.
6343 If it does, point to it with p, otherwise set p to NULL.
6348 p = (*p == 'k' || *p == 'K') ? p + 1 : NULL;
6352 #endif /* NOKVERBS */
6354 /* free the old definition if necessary */
6355 if (mousemap[button][event].type == macro) {
6356 free( mousemap[button][event].macro.string);
6357 mousemap[button][event].macro.string = NULL;
6359 switch (strlen(s)) { /* Action depends on length */
6360 case 0: /* Reset to default binding */
6361 mousemapinit( button, event );
6363 case 1: /* Single character */
6364 mousemap[button][event].type = key;
6365 mousemap[button][event].key.scancode = *s;
6367 default: /* Character string */
6370 y = xlookup(kverbs,p,nkverbs,&x); /* Look it up */
6371 debug(F101,"set mouse kverb lookup",0,y); /* need exact match */
6373 /* Assign the kverb to the event */
6374 mousemap[button][event].type = kverb;
6375 mousemap[button][event].kverb.id = F_KVERB | y;
6379 #endif /* NOKVERBS */
6381 /* Otherwise, it's a macro, so assign the macro to the event */
6382 mousemap[button][event].type = macro;
6383 mousemap[button][event].macro.string = (MACRO) malloc(strlen(s)+1);
6384 if (mousemap[button][event].macro.string)
6385 strcpy((char *) mousemap[button][event].macro.string, s); /* safe */
6388 initvik = 1; /* Update VIK Table */
6389 if ( (button == XYM_B3) && (mousebuttoncount() < 3) && !quiet )
6391 printf("?Warning: this machine does not have a three button mouse.\n");
6396 #endif /* OS2MOUSE */
6397 #endif /* NOLOCAL */
6400 int /* SET SEND/RECEIVE */
6401 setsr(xx, rmsflg) int xx; int rmsflg; {
6403 ckstrncpy(line,"Parameter for inbound packets",LINBUFSIZ);
6405 ckstrncpy(line,"Parameter for outbound packets",LINBUFSIZ);
6408 if ((y = cmkey(rsrtab,nrsrtab,line,"",xxstring)) < 0) {
6410 printf("?Remote receive parameter required\n");
6415 if ((y = cmkey(srtab,nsrtab,line,"",xxstring)) < 0) return(y);
6418 case XYQCTL: /* CONTROL-PREFIX */
6419 if ((x = cmnum("ASCII value of control prefix","",10,&y,xxstring)) < 0)
6421 if ((x = cmcfm()) < 0) return(x);
6422 if ((y > 32 && y < 63) || (y > 95 && y < 127)) {
6424 ctlq = (CHAR) y; /* RECEIVE prefix, use with caution! */
6426 myctlq = (CHAR) y; /* SEND prefix, OK to change */
6427 return(success = 1);
6429 printf("?Illegal value for prefix character\n");
6434 if ((y = setcc("13",&z)) < 0)
6437 printf("Sorry, the legal values are 0-31\n");
6444 return(success = y);
6447 y = cmnum("Maximum number of characters in a packet","90",10,&x,
6449 if (xx == XYRECV) { /* Receive... */
6450 if ((y = setnum(&z,x,y,maxrps)) < 0)
6452 if (protocol != PROTO_K) {
6453 printf("?Sorry, this command does not apply to %s protocol.\n",
6454 ptab[protocol].p_name
6456 printf("Use SET SEND PACKET-LENGTH for XYZMODEM\n");
6460 printf("Sorry, 10 is the minimum\n");
6464 sstate = setgen('S', "401", ckitoa(z), "");
6465 return((int) sstate);
6467 if (protocol == PROTO_K) {
6468 if (z > MAXRP) z = MAXRP;
6469 y = adjpkl(z,wslotr,bigrbsiz);
6474 " Adjusting receive packet-length to %d for %d window slots\n",
6478 ptab[protocol].rpktlen = urpsiz;
6479 rpsiz = (y > 94) ? 94 : y;
6482 if ((protocol == PROTO_X || protocol == PROTO_XC) &&
6483 z != 128 && z != 1024) {
6484 printf("Sorry, bad packet length for XMODEM.\n");
6485 printf("Please use 128 or 1024.\n");
6492 } else { /* Send... */
6493 if ((y = setnum(&z,x,y,maxsps)) < 0)
6496 printf("Sorry, 10 is the minimum\n");
6499 if (protocol == PROTO_K) {
6500 if (z > MAXSP) z = MAXSP;
6501 spsiz = z; /* Set it */
6502 y = adjpkl(spsiz,wslotr,bigsbsiz);
6503 if (y != spsiz && !xcmdsrc)
6505 printf("Adjusting packet size to %d for %d window slots\n",
6510 if ((protocol == PROTO_X || protocol == PROTO_XC) &&
6511 z != 128 && z != 1024) {
6512 printf("Sorry, bad packet length for XMODEM.\n");
6513 printf("Please use 128 or 1024.\n");
6517 spsiz = spmax = spsizr = y; /* Set it and flag that it was set */
6518 spsizf = 1; /* to allow overriding Send-Init. */
6519 ptab[protocol].spktflg = spsizf;
6520 ptab[protocol].spktlen = spsiz;
6522 if (pflag && protocol == PROTO_K && !xcmdsrc) {
6523 if (z > 94 && !reliable && msgflg) {
6524 /* printf("Extended-length packets requested.\n"); */
6525 if (bctr < 2 && z > 200) printf("\
6526 Remember to SET BLOCK 2 or 3 for long packets.\n");
6528 if (speed <= 0L) speed = ttgspd();
6531 Kermit does this now itself.
6533 if (speed <= 0L && z > 200 && msgflg) {
6535 Make sure your timeout interval is long enough for %d-byte packets.\n",z);
6537 #endif /* COMMENT */
6539 return(success = y);
6544 Printable start-of-packet works for UNIX and VMS only!
6547 y = cmnum("Code for packet-start character","1",10,&x,xxstring);
6549 if ((y = setnum(&z,x,y,126)) < 0) return(y);
6551 if ((y = setcc("1",&z)) < 0)
6553 #endif /* DOOMSDAY */
6559 /* If IKS negotiation in use */
6560 if (TELOPT_U(TELOPT_KERMIT) || TELOPT_ME(TELOPT_KERMIT))
6561 tn_siks(KERMIT_SOP); /* Report change to other side */
6562 #endif /* IKS_OPTION */
6564 return(success = y);
6566 case XYNPAD: /* PADDING */
6567 y = cmnum("How many padding characters for inbound packets","0",10,&x,
6569 if ((y = setnum(&z,x,y,94)) < 0) return(y);
6574 return(success = y);
6576 case XYPADC: /* PAD-CHARACTER */
6577 if ((y = setcc("0",&z)) < 0) return(y);
6578 if (xx == XYRECV) mypadc = z; else padch = z;
6579 return(success = y);
6581 case XYTIMO: /* TIMEOUT */
6583 y = cmnum("Packet timeout interval",ckitoa(URTIME),10,&x,xxstring);
6584 if ((y = setnum(&z,x,y,94)) < 0) return(y);
6586 if (rmsflg) { /* REMOTE SET RECEIVE TIMEOUT */
6587 sstate = setgen('S', "402", ckitoa(z), "");
6588 return((int) sstate);
6589 } else { /* SET RECEIVE TIMEOUT */
6590 pkttim = z; /* Value to put in my negotiation */
6591 } /* packet for other Kermit to use */
6593 } else { /* SET SEND TIMEOUT */
6595 extern int rttflg, mintime, maxtime;
6596 int tmin = 0, tmax = 0;
6597 #endif /* CK_TIMERS */
6598 y = cmnum("Packet timeout interval",ckitoa(DMYTIM),10,&x,xxstring);
6599 if (y == -3) { /* They cancelled a previous */
6600 x = DMYTIM; /* SET SEND command, so restore */
6601 timef = 0; /* and turn off the override flag */
6605 if (y < 0) return(y);
6607 printf("?Out of range - %d\n",x);
6610 if ((z = cmkey(timotab,2,"","dynamic",xxstring)) < 0) return(z);
6612 if ((y = cmnum("Minimum timeout to allow",
6613 "1",10,&tmin,xxstring)) < 0)
6616 printf("?Out of range - %d\n",tmin);
6619 if ((y = cmnum("Maximum timeout to allow",
6620 "0",10,&tmax,xxstring)) < 0)
6622 /* 0 means let Kermit choose, < 0 means no maximum */
6624 if ((y = cmcfm()) < 0)
6626 rttflg = z; /* Round-trip timer flag */
6629 if ((y = setnum(&z,x,y,94)) < 0)
6631 #endif /* CK_TIMERS */
6632 timef = 1; /* Turn on the override flag */
6633 timint = rtimo = z; /* Override value for me to use */
6635 if (rttflg) { /* Lower and upper bounds */
6639 #endif /* CK_TIMERS */
6641 return(success = 1);
6643 case XYFPATH: /* PATHNAMES */
6645 y = cmkey(rpathtab,nrpathtab,"","auto",xxstring);
6647 y = cmkey(pathtab,npathtab,"","off",xxstring);
6649 if (y < 0) return(y);
6651 if ((x = cmcfm()) < 0) return(x);
6652 if (xx == XYRECV) { /* SET RECEIVE PATHNAMES */
6654 ptab[protocol].fnrp = fnrpath;
6655 } else { /* SET SEND PATHNAMES */
6657 ptab[protocol].fnsp = fnspath;
6659 return(success = 1); /* Note: 0 = ON, 1 = OFF */
6660 /* In other words, ON = leave pathnames ON, OFF = take them off. */
6662 case XYPAUS: /* SET SEND/RECEIVE PAUSE */
6663 y = cmnum("Milliseconds to pause between packets","0",10,&x,xxstring);
6664 if ((y = setnum(&z,x,y,15000)) < 0)
6667 return(success = 1);
6669 #ifdef CKXXCHAR /* SET SEND/RECEIVE IGNORE/DOUBLE */
6674 extern short dblt[];
6675 extern int dblflag, ignflag;
6677 /* Make space for a temporary copy of the ignore/double table */
6681 if (zz == XYIGN && xx == XYSEND) {
6684 if (zz == XYDBL && xx == XYRECV) {
6687 #endif /* COMMENT */
6688 p = (short *)malloc(256 * sizeof(short));
6690 printf("?Internal error - malloc failure\n");
6693 for (i = 0; i < 256; i++) p[i] = dblt[i]; /* Copy current table */
6695 while (1) { /* Collect a list of numbers */
6697 x_ifnum = 1; /* Turn off complaints from eval() */
6699 if ((x = cmnum(zz == XYDBL ?
6700 "Character to double" :
6701 "Character to ignore",
6707 if (x == -3) /* Done */
6710 if (p) { free(p); p = NULL; }
6711 debug(F110,"SET S/R DOUBLE/IGNORE atmbuf",atmbuf,0);
6712 if (!ckstrcmp(atmbuf,"none",4,0) ||
6713 !ckstrcmp(atmbuf,"non",3,0) ||
6714 !ckstrcmp(atmbuf,"no",2,0) ||
6715 !ckstrcmp(atmbuf,"n",1,0)) {
6716 if ((x = cmcfm()) < 0) /* Get confirmation */
6718 for (y = 0; y < 256; y++)
6719 dblt[y] &= (zz == XYDBL) ? 1 : 2;
6720 if (zz == XYDBL) dblflag = 0;
6721 if (zz == XYIGN) ignflag = 0;
6722 return(success = 1);
6725 "?Please specify a number or the word NONE\n");
6737 if (y < 0 || y > 255) {
6738 printf("?Please enter a character code in range 0-255\n");
6743 p[y] |= (zz == XYDBL) ? 2 : 1;
6744 if (zz == XYDBL) dblflag = 1;
6745 if (zz == XYIGN) ignflag = 1;
6746 } /* End of while loop */
6748 if ((x = cmcfm()) < 0) return(x);
6750 Get here only if they have made no mistakes. Copy temporary table back to
6751 permanent one, then free temporary table and return successfully.
6754 for (i = 0; i < 256; i++) dblt[i] = p[i];
6758 return(success = 1);
6760 #endif /* CKXXCHAR */
6763 case XYFLTR: { /* SET { SEND, RECEIVE } FILTER */
6764 if ((y = cmtxt((xx == XYSEND) ?
6765 "Filter program for sending files -\n\
6766 use \\v(filename) to substitute filename" :
6767 "Filter program for receiving files -\n\
6768 use \\v(filename) to substitute filename",
6771 if (!*s) { /* Removing a filter... */
6772 if (xx == XYSEND && sndfilter) {
6773 makestr(&g_sfilter,NULL);
6774 makestr(&sndfilter,NULL);
6775 } else if (rcvfilter) {
6776 makestr(&g_rfilter,NULL);
6777 makestr(&rcvfilter,NULL);
6779 return(success = 1);
6780 } /* Adding a filter... */
6781 s = brstrip(s); /* Strip any braces */
6783 if (xx == XYSEND) { /* For SEND filter... */
6784 for (x = 0; x < y; x++) { /* make sure they included "\v(...)" */
6785 if (s[x] != '\\') continue;
6786 if (s[x+1] == 'v') break;
6790 "?Filter must contain a replacement variable for filename.\n"
6796 makestr(&sndfilter,s);
6797 makestr(&g_sfilter,s);
6799 makestr(&rcvfilter,s);
6800 makestr(&g_rfilter,s);
6802 return(success = 1);
6804 #endif /* PIPESEND */
6807 y = cmnum("Max length for protocol init string","-1",10,&x,xxstring);
6808 if ((y = setnum(&z,x,y,-1)) < 0)
6814 return(success = 1);
6817 extern int sendipkts;
6819 if ((x = seton(&sendipkts)) < 0)
6828 if ((x = seton(&atlpro)) < 0) return(x);
6832 if ((x = seton(&atlpri)) < 0) return(x);
6838 #endif /* CK_PERMS */
6841 case XYCSET: { /* CHARACTER-SET-SELECTION */
6842 extern struct keytab xfrmtab[];
6843 extern int r_cset, s_cset;
6844 if ((y = cmkey(xfrmtab,2,"","automatic",xxstring)) < 0)
6846 if ((x = cmcfm()) < 0)
6852 return(success = 1);
6854 #endif /* NOCSETS */
6857 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0)
6859 if ((x = cmcfm()) < 0) return(x);
6862 skipbup = (y == 0) ? 1 : 0;
6863 return(success = 1);
6866 "?Please use SET FILE COLLISION to choose the desired action\n");
6872 y = cmdir("Directory to move file(s) to after successful transfer",
6875 y = cmtxt("Directory to move file(s) to after successful transfer",
6877 #endif /* COMMENT */
6879 if (y < 0 && y != -3)
6881 ckstrncpy(line,s,LINBUFSIZ);
6885 /* Only needed for cmdir() */
6886 if ((x = cmcfm()) < 0)
6888 #endif /* COMMENT */
6890 /* Check directory existence if absolute */
6891 /* THIS MEANS IT CAN'T INCLUDE ANY DEFERRED VARIABLES! */
6893 if (isabsolute(s) && !isdir(s)) {
6894 printf("?Directory does not exist - %s\n",s);
6901 /* Allow it to be relative */
6902 zfnqfp(s,LINBUFSIZ,line);
6903 #endif /* COMMENT */
6904 makestr(&snd_move,line);
6905 makestr(&g_snd_move,line);
6907 makestr(&snd_move,NULL);
6908 makestr(&g_snd_move,NULL);
6913 /* Allow it to be relative */
6914 zfnqfp(s,LINBUFSIZ,line);
6915 #endif /* COMMENT */
6916 makestr(&rcv_move,line);
6917 makestr(&g_rcv_move,line);
6919 makestr(&rcv_move,NULL);
6920 makestr(&g_rcv_move,NULL);
6923 return(success = 1);
6926 y = cmtxt("Template to rename file(s) to after successful transfer",
6927 "",&s,NULL); /* NOTE: no xxstring */
6928 if (y < 0 && y != -3) /* Evaluation is deferred */
6930 ckstrncpy(line,s,LINBUFSIZ);
6932 if ((x = cmcfm()) < 0)
6936 makestr(&snd_rename,s);
6937 makestr(&g_snd_rename,s);
6939 makestr(&snd_rename,NULL);
6940 makestr(&g_snd_rename,NULL);
6944 makestr(&rcv_rename,s);
6945 makestr(&g_rcv_rename,s);
6947 makestr(&rcv_rename,NULL);
6948 makestr(&g_rcv_rename,NULL);
6951 return(success = 1);
6954 case 887: /* VERSION-NUMBERS */
6956 extern int vmssversions;
6957 return(seton(&vmssversions));
6959 extern int vmsrversions;
6960 return(seton(&vmsrversions));
6966 } /* End of SET SEND/RECEIVE... */
6973 if ((y = cmkey(xmitab,nxmit,"","",xxstring)) < 0) return(y);
6975 case XMITE: /* EOF */
6976 y = cmtxt("Characters to send at end of file,\n\
6977 Use backslash codes for control characters","",&s,xxstring);
6978 if (y < 0) return(y);
6979 if ((int)strlen(s) > XMBUFL) {
6980 printf("?Too many characters, %d maximum\n",XMBUFL);
6983 ckstrncpy(xmitbuf,s,XMBUFL);
6984 return(success = 1);
6986 case XMITF: /* Fill */
6987 y = cmnum("Numeric code for blank-line fill character","0",10,&x,
6989 if ((y = setnum(&z,x,y,127)) < 0) return(y);
6991 return(success = 1);
6992 case XMITL: /* Linefeed */
6993 return(seton(&xmitl));
6994 case XMITS: /* Locking-Shift */
6995 return(seton(&xmits));
6996 case XMITP: /* Prompt */
6997 y = cmnum("Numeric code for host's prompt character, 0 for none",
6998 "10",10,&x,xxstring);
6999 if ((y = setnum(&z,x,y,127)) < 0) return(y);
7001 return(success = 1);
7002 case XMITX: /* Echo */
7003 return(seton(&xmitx));
7004 case XMITW: /* Pause */
7005 y = cmnum("Number of milliseconds to pause between binary characters\n\
7006 or text lines during transmission","0",10,&x,xxstring);
7007 if ((y = setnum(&z,x,y,1000)) < 0) return(y);
7009 return(success = 1);
7010 case XMITT: /* Timeout */
7011 y = cmnum("Seconds to wait for each character to echo",
7012 "1",10,&x,xxstring);
7013 if ((y = setnum(&z,x,y,1000)) < 0) return(y);
7015 return(success = 1);
7023 /* D O R M T -- Do a remote command */
7027 if (pflag && !quiet && fdispla != XYFD_N)
7030 " Type your escape character, %s, followed by X or E to cancel.\n",
7033 " Press the X or E key to cancel.\n"
7034 #endif /* CK_NEED_SIG */
7038 static int xzcmd = 0; /* Global copy of REMOTE cmd index */
7040 /* R E M C F M -- Confirm a REMOTE command */
7042 Like cmcfm(), but allows for a redirection indicator on the end,
7043 like "> filename" or "| command". Returns what cmcfm() would have
7044 returned: -1 if reparse needed, etc etc blah blah. On success,
7047 char * remdest containing the name of the file or command.
7048 int remfile set to 1 if there is to be any redirection.
7049 int remappd set to 1 if output file is to be appended to.
7050 int rempipe set to 1 if remdest is a command, 0 if it is a file.
7063 "> filename, | command,\n\
7064 or type carriage return to confirm the command",
7065 "",&s,xxstring)) < 0)
7071 debug(F101,"remcfm local","",local);
7072 debug(F110,"remcfm s",s,0);
7073 debug(F101,"remcfm cmd","",xzcmd);
7075 if (!*s) { /* No redirection indicator */
7077 (xzcmd == XZDIR || xzcmd == XZTYP ||
7078 xzcmd == XZXIT || xzcmd == XZSPA ||
7079 xzcmd == XZHLP || xzcmd == XZPWD ||
7080 xzcmd == XZLGI || xzcmd == XZLGO ||
7081 xzcmd == XZWHO || xzcmd == XZHOS)) {
7082 printf("?\"%s\" has no effect in remote mode\n",cmdbuf);
7087 c = *s; /* We have something */
7088 if (c != '>' && c != '|') { /* Is it > or | ? */
7089 printf("?Not confirmed\n"); /* No */
7092 s++; /* See what follows */
7093 if (c == '>' && *s == '>') { /* Allow for ">>" too */
7095 remappd = 1; /* Append to output file */
7097 while (*s == SP || *s == HT) s++; /* Strip intervening whitespace */
7099 printf("?%s missing\n", c == '>' ? "Filename" : "Command");
7102 if (c == '>' && zchko(s) < 0) { /* Check accessibility */
7103 printf("?Access denied - %s\n", s);
7106 remfile = 1; /* Set global results */
7107 rempipe = (c == '|');
7113 printf("?Sorry, access to external commands is disabled.\n");
7116 makestr(&remdest,s);
7119 debug(F101,"remcfm remfile","",remfile);
7120 debug(F101,"remcfm remappd","",remappd);
7121 debug(F101,"remcfm rempipe","",rempipe);
7122 debug(F110,"remcfm remdest",remdest, 0);
7124 #endif /* NODEBUG */
7128 /* R E M T X T -- Like remcfm()... */
7130 ... but for REMOTE commands that end with cmtxt().
7131 Here we must decipher braces to discover whether the trailing
7132 redirection indicator is intended for local use, or to be sent out
7133 to the server, as in:
7135 remote host blah blah > file This end
7136 remote host { blah blah } > file This end
7137 remote host { blah blah > file } That end
7138 remote host { blah blah > file } > file Both ends
7142 remote host blah blah | cmd This end
7143 remote host { blah blah } | cmd This end
7144 remote host { blah blah | cmd } That end
7145 remote host { blah blah | cmd } | cmd Both ends
7149 remote host blah blah | cmd > file This end, etc etc...
7151 Note: this really only makes sense for REMOTE HOST, but why be picky?
7152 Call after calling cmtxt(), with pointer to string that cmtxt() parsed,
7153 as in "remtxt(&s);".
7156 1 on success with braces & redirection things removed & pointer updated,
7157 -9 on failure (bad indirection), after printing error message.
7160 remtxt(p) char ** p; {
7161 int i, x, bpos, ppos;
7164 remfile = 0; /* Initialize global results */
7172 if (!s) /* No redirection indicator */
7174 if (!*s) { /* Ditto */
7176 (xzcmd == XZDIR || xzcmd == XZTYP ||
7177 xzcmd == XZXIT || xzcmd == XZSPA ||
7178 xzcmd == XZHLP || xzcmd == XZPWD ||
7179 xzcmd == XZLGI || xzcmd == XZLGO ||
7180 xzcmd == XZWHO || xzcmd == XZHOS)) {
7181 printf("?\"%s\" has no effect in remote mode\n",cmdbuf);
7183 printf("Hint: Try again with an output redirector.\n");
7189 bpos = -1; /* Position of > (bracket) */
7190 ppos = -1; /* Position of | (pipe) */
7191 x = strlen(s); /* Length of cmtxt() string */
7193 for (i = x-1; i >= 0; i--) { /* Search right to left. */
7195 if (c == '}') /* Break on first right brace */
7196 break; /* Don't look at contents of braces */
7197 else if (c == '>') /* Record position of > */
7199 else if (c == '|') /* and of | */
7202 if (bpos < 0 && ppos < 0) { /* No redirectors. */
7204 (xzcmd == XZDIR || xzcmd == XZTYP ||
7205 xzcmd == XZXIT || xzcmd == XZSPA ||
7206 xzcmd == XZHLP || xzcmd == XZPWD ||
7207 xzcmd == XZLGI || xzcmd == XZLGO ||
7208 xzcmd == XZWHO || xzcmd == XZHOS)) {
7209 printf("?\"%s\" has no effect in remote mode\n",cmdbuf);
7211 printf("Hint: Try again with an output redirector.\n");
7215 s = brstrip(s); /* Remove outer braces if any. */
7216 *p = s; /* Point to result */
7217 return(1); /* and return. */
7219 remfile = 1; /* It's | or > */
7220 i = -1; /* Get leftmost symbol */
7221 if (bpos > -1) /* Bracket */
7223 if (ppos > -1 && (ppos < bpos || bpos < 0)) { /* or pipe */
7232 printf("?Sorry, access to external commands is disabled.\n");
7235 c = s[i]; /* Copy of symbol */
7237 if (c == '>' && s[i+1] == '>') /* ">>" for append? */
7238 remappd = 1; /* It's not just a flag it's a number */
7240 q = s + i + 1 + remappd; /* Point past symbol in string */
7241 while (*q == SP || *q == HT) q++; /* and any intervening whitespace */
7243 printf("?%s missing\n", c == '>' ? "Filename" : "Command");
7246 if (c == '>' && zchko(q) < 0) { /* (Doesn't work for | cmd > file) */
7247 printf("?Access denied - %s\n", q);
7250 makestr(&remdest,q); /* Create the destination string */
7251 q = s + i - 1; /* Point before symbol */
7252 while (q > s && (*q == SP || *q == HT)) /* Strip trailing whitespace */
7254 *(q+1) = NUL; /* Terminate the string. */
7255 s = brstrip(s); /* Remove any braces */
7256 *p = s; /* Set return value */
7260 debug(F101,"remtxt remfile","",remfile);
7261 debug(F101,"remtxt remappd","",remappd);
7262 debug(F101,"remtxt rempipe","",rempipe);
7263 debug(F110,"remtxt remdest",remdest, 0);
7264 debug(F110,"remtxt command",s,0);
7266 #endif /* NODEBUG */
7272 plogin(xx) int xx; {
7273 char *p1 = NULL, *p2 = NULL, *p3 = NULL;
7274 int psaved = 0, rc = 0;
7276 extern int on_recall; /* around Password prompting */
7277 #endif /* CK_RECALL */
7278 debug(F101,"plogin local","",local);
7280 if (!local || (network && ttchk() < 0)) {
7281 printf("?No connection\n");
7284 if ((x = cmfld("User ID","",&s,xxstring)) < 0) { /* Get User ID */
7285 if (x != -3) return(x);
7289 if ((p1 = malloc(y + 1)) == NULL) {
7290 printf("?Internal error: malloc\n");
7294 strcpy(p1,s); /* safe */
7295 if ((rc = cmfld("Password","",&s,xxstring)) < 0)
7296 if (rc != -3) goto XZXLGI;
7299 if ((p2 = malloc(y + 1)) == NULL) {
7300 printf("?Internal error: malloc\n");
7304 strcpy(p2,s); /* safe */
7305 if ((rc = cmfld("Account","",&s,xxstring)) < 0)
7306 if (rc != -3) goto XZXLGI;
7309 if ((p3 = malloc(y + 1)) == NULL) {
7310 printf("?Internal error: malloc\n");
7314 strcpy(p3,s); /* safe */
7318 if ((rc = remtxt(&s)) < 0) /* Confirm & handle redirectors */
7321 if (!p1) { /* No Userid specified... */
7322 debok = 0; /* Don't log this */
7323 /* Prompt for username, password, and account */
7326 #endif /* CK_RECALL */
7327 cmsavp(psave,PROMPTL); /* Save old prompt */
7329 debug(F110,"REMOTE LOGIN saved",psave,0);
7331 cmsetp("Username: "); /* Make new prompt */
7332 concb((char)escape); /* Put console in cbreak mode */
7336 for (x = -1; x < 0; ) { /* Prompt till they answer */
7337 cmres(); /* Reset the parser */
7338 x = cmtxt("","",&s,NULL); /* Get a literal line of text */
7342 printf("?Canceled\n");
7345 if ((p1 = malloc(y + 1)) == NULL) {
7346 printf("?Internal error: malloc\n");
7349 strcpy(p1,s); /* safe */
7351 cmsetp("Password: "); /* Make new prompt */
7352 concb((char)escape); /* Put console in cbreak mode */
7353 cmini(0); /* No echo */
7356 for (x = -1; x < 0 && x != -3; ) { /* Get answer */
7357 cmres(); /* Reset the parser */
7358 x = cmtxt("","",&s,NULL); /* Get literal line of text */
7360 if ((p2 = malloc((int)strlen(s) + 1)) == NULL) {
7361 printf("?Internal error: malloc\n");
7364 strcpy(p2,s); /* safe */
7366 if ((rc = cmcfm()) < 0)
7369 sstate = setgen('I',p1,p2,p3); /* Get here with at least user ID */
7372 XZXLGI: /* Common exit point */
7374 cmsetp(psave); /* Restore original prompt */
7375 if (p3) { free(p3); p3 = NULL; } /* Free malloc'd storage */
7376 if (p2) { free(p2); p2 = NULL; }
7377 if (p1) { free(p1); p1 = NULL; }
7379 if (local && rc > -1) /* If local, flush tty input buffer */
7391 int term_io_sav = term_io;
7393 extern int ftpget, ftpisopen();
7394 if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
7395 return(doftprmt(xx,0));
7399 term_io = term_io_sav;
7409 #endif /* NOLOCAL */
7414 { /* REMOTE commands */
7416 char *s, sbuf[50], *s2;
7419 extern int ftpget, ftpisopen();
7420 if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
7421 return(doftprmt(xx,0));
7424 remfile = 0; /* Clear these */
7428 if (xx < 0) return(xx); /* REMOTE what? */
7430 xzcmd = xx; /* Make global copy of arg */
7432 if (xx == XZSET) { /* REMOTE SET */
7433 if ((y = cmkey(rmstab,nrms,"","",xxstring)) < 0) {
7435 printf("?Parameter name required\n");
7442 switch (xx) { /* Others... */
7445 if ((x = cmcfm()) < 0) return(x);
7446 printf("?Sorry, REMOTE CDUP not supported yet\n");
7449 case XZCWD: /* CWD (CD) */
7450 if ((x = cmtxt("Remote directory name","",&s,xxstring)) < 0)
7452 if ((x = remtxt(&s)) < 0)
7454 debug(F111,"XZCWD: ",s,x);
7458 The following is commented out because since the disappearance of the
7459 DECSYSTEM-20 from the planet, no known computer requires a password for
7463 if (*s != NUL) { /* If directory name given, */
7464 /* get password on separate line. */
7465 if (tlevel > -1) { /* From take file... */
7467 if (fgets(sbuf,50,tfile[tlevel]) == NULL)
7468 fatal("take file ends prematurely in 'remote cwd'");
7469 debug(F110," pswd from take file",s2,0);
7470 for (x = (int)strlen(sbuf);
7471 x > 0 && (sbuf[x-1] == NL || sbuf[x-1] == CR);
7475 } else { /* From terminal... */
7477 printf(" Password: "); /* get a password */
7479 if (!local && inserver) {
7484 x = is_a_tty(0) ? coninc(0) : /* with no echo ... */
7489 while ((x != NL) && (x != CR)) {
7490 if ((x &= 0177) == '?') {
7491 printf("? Password of remote directory\n Password: ");
7494 } else if (x == ESC) /* Mini command line editor... */
7496 else if (x == BS || x == 0177)
7498 else if (x == 025) { /* Ctrl-U */
7504 /* Get the next character */
7506 if (!local && inserver) {
7511 x = is_a_tty(0) ? coninc(0) : /* with no echo ... */
7522 #endif /* DIRPWDPR */
7524 debug(F110," password",s2,0);
7526 sstate = setgen('C',s,s2,"");
7530 case XZDEL: /* Delete */
7531 if ((x = cmtxt("Name of remote file(s) to delete",
7532 "",&s,xxstring)) < 0) {
7534 printf("?Name of remote file(s) required\n");
7538 if ((x = remtxt(&s)) < 0)
7540 if (local) ttflui(); /* If local, flush tty input buffer */
7541 retcode = sstate = rfilop(s,'E');
7544 case XZDIR: /* Directory */
7545 if ((x = cmtxt("Remote directory or file specification","",&s,
7548 if ((x = remtxt(&s)) < 0)
7550 if (local) ttflui(); /* If local, flush tty input buffer */
7552 retcode = sstate = setgen('D',s,"","");
7555 case XZHLP: /* Help */
7556 if ((x = remcfm()) < 0) return(x);
7557 sstate = setgen('H',"","","");
7561 case XZHOS: /* Host */
7562 if ((x = cmtxt("Command for remote system","",&s,xxstring)) < 0)
7564 if ((x = remtxt(&s)) < 0)
7566 if ((y = (int)strlen(s)) < 1)
7568 ckstrncpy(line,s,LINBUFSIZ);
7571 retcode = sstate = 'c';
7576 if ((x = cmtxt("Command for remote Kermit","",&s,xxstring)) < 0)
7578 if ((x = remtxt(&s)) < 0)
7580 if ((int)strlen(s) < 1) {
7582 printf("?Remote Kermit command required\n");
7586 ckstrncpy(line,s,LINBUFSIZ);
7588 retcode = sstate = 'k';
7592 case XZLGI: /* Login */
7593 rcdactive = 1; /* Suppress "Logged in" msg if quiet */
7594 return(plogin(XXREM));
7596 case XZLGO: { /* Logout */
7597 extern int bye_active;
7598 if ((x = remcfm()) < 0) return(x);
7599 sstate = setgen('I',"","","");
7601 bye_active = 1; /* Close connection when done */
7605 case XZPRI: /* Print */
7606 if (!atdiso || !atcapr) { /* Disposition attribute off? */
7607 printf("?Disposition Attribute is Off\n");
7612 if ((x = cmifi("Local file(s) to print on remote printer","",&s,&y,
7615 printf("?Name of local file(s) required\n");
7620 ckstrncpy(line,s,LINBUFSIZ); /* Make a safe copy of filename */
7621 *optbuf = NUL; /* Wipe out any old options */
7622 if ((x = cmtxt("Options for remote print command","",&s,xxstring)) < 0)
7624 if ((x = remtxt(&s)) < 0)
7626 if ((int)strlen(optbuf) > 94) { /* Make sure this is legal */
7627 printf("?Option string too long\n");
7630 ckstrncpy(optbuf,s,OPTBUFLEN); /* Make a safe copy of options */
7631 nfils = -1; /* Expand file list internally */
7632 cmarg = line; /* Point to file list. */
7633 rprintf = 1; /* REMOTE PRINT modifier for SEND */
7634 sstate = 's'; /* Set start state to SEND */
7635 if (local) displa = 1;
7638 #endif /* NOFRILLS */
7640 case XZSPA: /* Space */
7641 if ((x = cmtxt("Confirm, or remote directory name",
7642 "",&s,xxstring)) < 0)
7644 if ((x = remtxt(&s)) < 0)
7646 retcode = sstate = setgen('U',s,"","");
7650 case XZTYP: /* Type */
7651 if ((x = cmtxt("Remote file specification","",&s,xxstring)) < 0)
7653 if ((int)strlen(s) < 1) {
7654 printf("?Remote filename required\n");
7657 if ((x = remtxt(&s)) < 0)
7660 retcode = sstate = rfilop(s,'T');
7662 #endif /* NOFRILLS */
7666 if ((x = cmtxt("Remote user name, or carriage return",
7667 "",&s,xxstring)) < 0)
7669 if ((x = remtxt(&s)) < 0)
7671 retcode = sstate = setgen('W',s,"","");
7673 #endif /* NOFRILLS */
7675 case XZPWD: /* PWD */
7676 if ((x = remcfm()) < 0) return(x);
7677 sstate = setgen('A',"","","");
7682 case XZQUE: { /* Query */
7684 extern char querybuf[], * qbufp;
7686 if ((y = cmkey(vartyp,nvartyp,"","",xxstring)) < 0)
7688 if ((x = cmtxt(y == 'F' ? "Remote function invocation" :
7689 ('K' ? "Remote variable name or function":
7690 "Remote variable name"),
7693 (y == 'K') ? xxstring : NULL
7694 )) < 0) /* Don't evaluate */
7696 if ((x = remtxt(&s)) < 0)
7698 query = 1; /* QUERY is active */
7699 qbufp = querybuf; /* Initialize query response buffer */
7702 buf[0] = (char) (y & 127);
7704 retcode = sstate = setgen('V',"Q",(char *)buf,s);
7708 case XZASG: { /* Assign */
7710 if ((y = cmfld("Remote variable name","",&s,NULL)) < 0) /* No eval */
7712 if ((int)strlen(s) >= VNAML) {
7713 printf("?Too long\n");
7716 ckstrncpy(buf,s,VNAML);
7717 if ((x = cmtxt("Assignment for remote variable",
7718 "",&s,xxstring)) < 0) /* Evaluate this one */
7720 if ((x = remtxt(&s)) < 0)
7724 Server commands can't be long packets. In principle there's no reason
7725 why they shouldn't be, except that we don't know at this point if the
7726 server is capable of accepting long packets because we haven't started
7727 the protocol yet. In practice, allowing a long packet here breaks a lot
7728 of assumptions, causes buffer overruns and crashes, etc. To be fixed
7729 later. (But since this is commented out, evidently I fixed it later...)
7731 if ((int)strlen(s) > 85) { /* Allow for encoding expansion */
7732 printf("?Sorry, value is too long - 85 characters max\n");
7735 #endif /* COMMENT */
7736 retcode = sstate = setgen('V',"S",(char *)buf,s);
7741 case XZCPY: { /* COPY */
7742 char buf[TMPBUFSIZ];
7743 buf[TMPBUFSIZ-1] = '\0';
7744 if ((x = cmfld("Name of remote file to copy","",&s,xxstring)) < 0) {
7746 printf("?Name of remote file required\n");
7752 ckstrncpy(buf,s,TMPBUFSIZ);
7753 if ((x = cmfld("Name of remote destination file or directory",
7754 "",&s, xxstring)) < 0) {
7756 printf("?Name of remote file or directory required\n");
7760 ckstrncpy(tmpbuf,s,TMPBUFSIZ);
7761 if ((x = remcfm()) < 0)
7763 if (local) ttflui(); /* If local, flush tty input buffer */
7764 retcode = sstate = setgen('K',buf,tmpbuf,"");
7767 case XZREN: { /* Rename */
7768 char buf[TMPBUFSIZ];
7769 buf[TMPBUFSIZ-1] = '\0';
7770 if ((x = cmfld("Name of remote file to rename",
7771 "",&s,xxstring)) < 0) {
7773 printf("?Name of remote file required\n");
7777 ckstrncpy(buf,s,TMPBUFSIZ);
7778 if ((x = cmfld("New name of remote file","",&s, xxstring)) < 0) {
7780 printf("?Name of remote file required\n");
7784 ckstrncpy(tmpbuf,s,TMPBUFSIZ);
7785 if ((x = remcfm()) < 0)
7787 if (local) ttflui(); /* If local, flush device buffer */
7788 retcode = sstate = setgen('R',buf,tmpbuf,"");
7791 case XZMKD: /* mkdir */
7792 case XZRMD: /* rmdir */
7793 if ((x = cmtxt((xx == XZMKD) ?
7794 "Name of remote directory to create" :
7795 "Name of remote directory to delete",
7801 printf("?Name required\n");
7805 if ((x = remtxt(&s)) < 0)
7807 if (local) ttflui(); /* If local, flush tty input buffer */
7808 retcode = sstate = rfilop(s, (char)(xx == XZMKD ? 'm' : 'd'));
7811 case XZXIT: /* Exit */
7812 if ((x = remcfm()) < 0) return(x);
7813 sstate = setgen('X',"","","");
7818 if ((x = remcfm()) < 0) return(x);
7819 printf("?Not implemented - %s\n",cmdbuf);
7822 if (local && retcode > -1) /* If local, flush tty input buffer */
7828 /* R F I L O P -- Remote File Operation */
7832 rfilop(char * s, char t)
7834 rfilop(s,t) char *s, t;
7835 #endif /* CK_ANSIC */
7838 printf("?File specification required\n");
7841 debug(F111,"rfilop",s,t);
7842 return(setgen(t,s,"",""));
7849 if ((y = cmkey(x25tab,nx25,"X.25 call options","",xxstring)) < 0)
7853 if ((z = cmkey(onoff,2,"X.25 call user data","",xxstring))
7856 if ((z = cmcfm()) < 0) return(z);
7857 cudata = 0; /* disable call user data */
7858 return (success = 1);
7860 if ((x = cmtxt("X.25 call user data string","",&s,xxstring)) < 0)
7862 if ((int)strlen(s) == 0) {
7864 } else if ((int)strlen(s) > MAXCUDATA) {
7865 printf("?The length must be > 0 and <= %d\n",MAXCUDATA);
7868 if ((y = cmcfm()) < 0) return(y);
7869 ckstrncpy(udata,s,MAXCUDATA);
7870 cudata = 1; /* X.25 call user data specified */
7871 return (success = 1);
7873 if ((z = cmkey(onoff,2,"X.25 closed user group call","",xxstring))
7876 if ((z = cmcfm()) < 0) return(z);
7877 closgr = -1; /* disable closed user group */
7878 return (success = 1);
7880 if ((y = cmnum("0 <= cug index >= 99","",10,&x,xxstring)) < 0)
7882 if (x < 0 || x > 99) {
7883 printf("?The choices are 0 <= cug index >= 99\n");
7886 if ((y = cmcfm()) < 0) return(y);
7887 closgr = x; /* closed user group selected */
7888 return (success = 1);
7891 if((z = cmkey(onoff,2,"X.25 reverse charge call","",xxstring)) < 0)
7893 if ((x = cmcfm()) < 0) return(x);
7895 return (success = 1);
7902 if ((y = cmkey(padx3tab,npadx3,"PAD X.3 parameter name","",xxstring)) < 0)
7906 case PAD_BREAK_CHARACTER:
7907 if ((y = cmnum("PAD break character value","",10,&z,xxstring)) < 0)
7909 if ((y = cmcfm()) < 0) return(y);
7912 if ((y = cmnum("PAD escape","",10,&z,xxstring)) < 0) return(y);
7913 if (z != 0 && z != 1) {
7914 printf("?The choices are 0 or 1\n");
7917 if ((y = cmcfm()) < 0) return(y);
7920 if ((y = cmnum("PAD echo","",10,&z,xxstring)) < 0) return(y);
7921 if (z != 0 && z != 1) {
7922 printf("?The choices are 0 or 1\n");
7925 if ((y = cmcfm()) < 0) return(y);
7927 case PAD_DATA_FORWARD_CHAR:
7928 if ((y = cmnum("PAD data forward char","",10,&z,xxstring)) < 0)
7930 if (z != 0 && z != 2) {
7931 printf("?The choices are 0 or 2\n");
7934 if ((y = cmcfm()) < 0) return(y);
7936 case PAD_DATA_FORWARD_TIMEOUT:
7937 if ((y = cmnum("PAD data forward timeout","",10,&z,xxstring)) < 0)
7939 if (z < 0 || z > 255) {
7940 printf("?The choices are 0 or 1 <= timeout <= 255\n");
7943 if ((y = cmcfm()) < 0) return(y);
7945 case PAD_FLOW_CONTROL_BY_PAD:
7946 if ((y = cmnum("PAD pad flow control","",10,&z,xxstring)) < 0)
7948 if (z != 0 && z != 1) {
7949 printf("?The choices are 0 or 1\n");
7952 if ((y = cmcfm()) < 0) return(y);
7954 case PAD_SUPPRESSION_OF_SIGNALS:
7955 if ((y = cmnum("PAD service","",10,&z,xxstring)) < 0) return(y);
7956 if (z != 0 && z != 1) {
7957 printf("?The choices are 0 or 1\n");
7960 if ((y = cmcfm()) < 0) return(y);
7963 case PAD_BREAK_ACTION:
7964 if ((y = cmnum("PAD break action","",10,&z,xxstring)) < 0) return(y);
7965 if (z != 0 && z != 1 && z != 2 && z != 5 && z != 8 && z != 21) {
7966 printf("?The choices are 0, 1, 2, 5, 8 or 21\n");
7969 if ((y = cmcfm()) < 0) return(y);
7972 case PAD_SUPPRESSION_OF_DATA:
7973 if ((y = cmnum("PAD data delivery","",10,&z,xxstring)) < 0) return(y);
7974 if (z != 0 && z != 1) {
7975 printf("?The choices are 0 or 1\n");
7978 if ((y = cmcfm()) < 0) return(y);
7981 case PAD_PADDING_AFTER_CR:
7982 if ((y = cmnum("PAD crpad","",10,&z,xxstring)) < 0) return(y);
7983 if (z < 0 || z > 7) {
7984 printf("?The choices are 0 or 1 <= crpad <= 7\n");
7987 if ((y = cmcfm()) < 0) return(y);
7990 case PAD_LINE_FOLDING:
7991 if ((y = cmnum("PAD linefold","",10,&z,xxstring)) < 0) return(y);
7992 if (z < 0 || z > 255) {
7993 printf("?The choices are 0 or 1 <= linefold <= 255\n");
7996 if ((y = cmcfm()) < 0) return(y);
7999 case PAD_LINE_SPEED:
8000 if ((y = cmnum("PAD baudrate","",10,&z,xxstring)) < 0) return(y);
8001 if (z < 0 || z > 18) {
8002 printf("?The choices are 0 <= baudrate <= 18\n");
8005 if ((y = cmcfm()) < 0) return(y);
8008 case PAD_FLOW_CONTROL_BY_USER:
8009 if ((y = cmnum("PAD terminal flow control","",10,&z,xxstring)) < 0)
8011 if (z != 0 && z != 1) {
8012 printf("?The choices are 0 or 1\n");
8015 if ((y = cmcfm()) < 0) return(y);
8018 case PAD_LF_AFTER_CR:
8019 if ((y = cmnum("PAD crpad","",10,&z,xxstring)) < 0) return(y);
8020 if (z < 0 || z == 3 || z > 7) {
8021 printf("?The choices are 0, 1, 2, 4, 5, 6 or 7\n");
8024 if ((y = cmcfm()) < 0) return(y);
8027 case PAD_PADDING_AFTER_LF:
8028 if ((y = cmnum("PAD lfpad","",10,&z,xxstring)) < 0) return(y);
8029 if (z < 0 || z > 7) {
8030 printf("?The choices are 0 or 1 <= lfpad <= 7\n");
8033 if ((y = cmcfm()) < 0) return(y);
8037 if ((y = cmnum("PAD edit control","",10,&z,xxstring)) < 0) return(y);
8038 if (z != 0 && z != 1) {
8039 printf("?The choices are 0 or 1\n");
8042 if ((y = cmcfm()) < 0) return(y);
8045 case PAD_CHAR_DELETE_CHAR:
8046 if ((y = cmnum("PAD char delete char","",10,&z,xxstring)) < 0)
8048 if (z < 0 || z > 127) {
8049 printf("?The choices are 0 or 1 <= chardelete <= 127\n");
8052 if ((y = cmcfm()) < 0) return(y);
8055 case PAD_BUFFER_DELETE_CHAR:
8056 if ((y = cmnum("PAD buffer delete char","",10,&z,xxstring)) < 0)
8058 if (z < 0 || z > 127) {
8059 printf("?The choices are 0 or 1 <= bufferdelete <= 127\n");
8062 if ((y = cmcfm()) < 0) return(y);
8065 case PAD_BUFFER_DISPLAY_CHAR:
8066 if ((y = cmnum("PAD display line char","",10,&z,xxstring)) < 0)
8068 if (z < 0 || z > 127) {
8069 printf("?The choices are 0 or 1 <= displayline <= 127\n");
8072 if ((y = cmcfm()) < 0) return(y);
8076 return(success = 1);
8083 setat(rmsflg) int rmsflg; {
8085 if ((y = cmkey(attrtab,natr,"File Attribute packets","",xxstring)) < 0)
8087 if (y == AT_XALL) { /* ATTRIBUTES ALL ON or ALL OFF */
8088 if ((z = seton(&xx)) < 0) return(z);
8090 printf("Sorry, command not available\n");
8093 atenci = xx; /* Encoding in */
8094 atenco = xx; /* Encoding out */
8095 atdati = xx; /* Date in */
8096 atdato = xx; /* Date out */
8097 atdisi = xx; /* Disposition in/out */
8099 atleni = xx; /* Length in/out (both kinds) */
8101 atblki = xx; /* Blocksize in/out */
8103 attypi = xx; /* File type in/out */
8105 atsidi = xx; /* System ID in/out */
8107 atsysi = xx; /* System-dependent params in/out */
8109 #ifdef CK_PERMS /* Protection */
8110 atlpri = xx; /* Local in */
8111 atlpro = xx; /* Local out */
8112 atgpri = xx; /* Generic in */
8113 atgpro = xx; /* Generic out */
8114 #endif /* CK_PERMS */
8116 atfrmi = xx; /* Format in/out */
8118 atcrei = xx; /* Creator id in/out */
8120 atacti = xx; /* Account in/out */
8122 #endif /* STRATUS */
8125 } else if (y == AT_ALLY || y == AT_ALLN) { /* ATTRIBUTES ON or OFF */
8126 if ((x = cmcfm()) < 0) return(x);
8127 atcapr = (y == AT_ALLY) ? 1 : 0;
8129 sstate = setgen('S', "132", atcapr ? "1" : "0", "");
8130 return((int) sstate);
8131 } else return(success = 1);
8133 /* Otherwise, it's an individual attribute that wants turning off/on */
8135 if ((z = cmkey(onoff,2,"","",xxstring)) < 0) return(z);
8136 if ((x = cmcfm()) < 0) return(x);
8138 /* There are better ways to do this... */
8139 /* The real problem is that we're not separating the in and out cases */
8140 /* and so we have to arbitrarily pick the "in" case, i.e tell the remote */
8141 /* server to ignore incoming attributes of the specified type, rather */
8142 /* than telling it not to send them. The protocol does not (yet) define */
8143 /* codes for "in-and-out-at-the-same-time". */
8147 /* We're lumping local and generic protection together for now... */
8151 sstate = setgen('S', "143", z ? "1" : "0", "");
8152 return((int) sstate);
8154 atlpri = atlpro = atgpri = atgpro = z; break;
8155 #endif /* CK_PERMS */
8158 sstate = setgen('S', "142", z ? "1" : "0", "");
8159 return((int) sstate);
8161 atdisi = atdiso = z; break;
8164 sstate = setgen('S', "141", z ? "1" : "0", "");
8165 return((int) sstate);
8167 atenci = atenco = z; break;
8170 sstate = setgen('S', "135", z ? "1" : "0", "");
8171 return((int) sstate);
8173 atdati = atdato = z; break;
8177 sstate = setgen('S', "133", z ? "1" : "0", "");
8178 return((int) sstate);
8180 atleni = atleno = z; break;
8183 sstate = setgen('S', "139", z ? "1" : "0", "");
8184 return((int) sstate);
8186 atblki = atblko = z; break;
8189 sstate = setgen('S', "134", z ? "1" : "0", "");
8190 return((int) sstate);
8192 attypi = attypo = z; break;
8196 sstate = setgen('S', "136", z ? "1" : "0", "");
8197 return((int) sstate);
8199 atcrei = atcreo = z; break;
8202 sstate = setgen('S', "137", z ? "1" : "0", "");
8203 return((int) sstate);
8205 atacti = atacto = z; break;
8206 #endif /* STRATUS */
8209 sstate = setgen('S', "145", z ? "1" : "0", "");
8210 return((int) sstate);
8212 atsidi = atsido = z; break;
8215 sstate = setgen('S', "146", z ? "1" : "0", "");
8216 return((int) sstate);
8218 atfrmi = atfrmo = z; break;
8221 sstate = setgen('S', "147", z ? "1" : "0", "");
8222 return((int) sstate);
8224 atsysi = atsyso = z; break;
8226 printf("?Not available\n");
8236 if ((y = cmkey(inptab,ninp,"","",xxstring)) < 0) return(y);
8239 case IN_PAC: /* SET INPUT PACING */
8240 z = cmnum("milliseconds","0",10,&x,xxstring);
8241 return(setnum(&tt_inpacing,x,z,1000));
8242 case IN_TRM: /* SET INPUT TERMINAL */
8243 return(seton(&interm));
8245 case IN_DEF: /* SET INPUT DEFAULT-TIMEOUT */
8246 z = cmnum("Positive number","",10,&x,xxstring);
8247 return(setnum(&indef,x,z,94));
8249 case IN_SCA: /* SET INPUT SCALE-FACTOR */
8250 if ((x = cmfld("Number such as 2 or 0.5","1.0",&s, xxstring)) < 0)
8252 if (isfloat(s,0)) { /* A floating-point number? */
8253 extern char * inpscale;
8254 inscale = floatval; /* Yes, get its value */
8255 makestr(&inpscale,s); /* Save it as \v(inscale) */
8256 return(success = 1);
8260 #endif /* CKFLOAT */
8261 case IN_TIM: /* SET INPUT TIMEOUT-ACTION */
8262 if ((z = cmkey(intimt,2,"","",xxstring)) < 0) return(z);
8263 if ((x = cmcfm()) < 0) return(x);
8265 return(success = 1);
8266 case IN_CAS: /* SET INPUT CASE */
8267 if ((z = cmkey(incast,2,"","",xxstring)) < 0) return(z);
8268 if ((x = cmcfm()) < 0) return(x);
8270 return(success = 1);
8271 case IN_ECH: /* SET INPUT ECHO */
8272 return(seton(&inecho));
8273 case IN_SIL: /* SET INPUT SILENCE */
8274 z = cmnum("Seconds of inactivity before INPUT fails","",10,&x,
8276 return(setnum(&insilence,x,z,-1));
8278 case IN_BUF: /* SET INPUT BUFFER-SIZE */
8279 if ((z = cmnum("Number of bytes in INPUT buffer",
8280 ckitoa(INPBUFSIZ),10,&x, xxstring)) < 0)
8282 if ((y = cmcfm()) < 0) return(y);
8289 if (!(s = (char *)malloc(x + 1)))
8294 for (x = 0; x <= inbufsize; x++)
8296 return(success = 1);
8299 case IN_ADL: /* AUTODOWNLOAD */
8300 return(seton(&inautodl));
8301 #endif /* CK_AUTODL */
8303 case IN_CAN: /* SET INPUT INTERRUPTS */
8304 return(seton(&inintr));
8313 #ifndef NODIAL /* This depends on DIAL... */
8315 if (!ndinited) /* Don't free garbage... */
8317 for (i = 0; i < nhcount; i++) { /* Clean out previous list */
8324 for (j = 0; j < 4; j++) {
8334 ndinit() { /* Net directory pointers */
8335 #ifndef NODIAL /* This depends on DIAL... */
8337 if (ndinited++) /* Don't do this more than once. */
8339 for (i = 0; i < MAXDDIR; i++) { /* Init all pointers to NULL */
8342 for (i = 0; i < MAXDNUMS; i++) {
8345 for (j = 0; j < 4; j++)
8353 VOID /* Get net defaults from environment */
8357 makestr(&p,getenv("K_NET_DIRECTORY")); /* Dialing directories */
8360 xwords(p,MAXDDIR,netdir,0);
8361 for (i = 0; i < MAXDDIR; i++) { /* Fill in any gaps... */
8365 netdir[i] = netdir[i+1];
8366 debug(F111,"netdir[i]",netdir[i],i);
8371 #endif /* NETCONN */
8376 lunet(char *s) /* s = name to look up */
8379 #endif /* CK_ANSIC */
8381 #ifndef NODIAL /* This depends on DIAL... */
8382 int n, n1, t, dd = 0;
8387 int netdpy = dialdpy;
8390 nhcount = 0; /* Set this before returning */
8392 if (!s || nnetdir < 1) /* Validate arguments */
8395 if (isdigit(*s) || *s == '*' || *s == '.')
8398 if ((n1 = (int) strlen(s)) < 1) /* Length of string to look up */
8401 if (!(line = malloc(1024))) /* Allocate input buffer */
8405 f = NULL; /* Network directory file descriptor */
8406 t = nhcount = 0; /* Match count */
8407 dd = 0; /* Directory counter */
8410 while (1) { /* We make one pass */
8411 if (!f) { /* Directory not open */
8412 if (dd >= nnetdir) /* No directories left? */
8414 if ((f = fopen(netdir[dd],"r")) == NULL) { /* Open it */
8415 perror(netdir[dd]); /* Can't, print message saying why */
8417 continue; /* But go on to next one. */
8420 printf("Opening %s...\n",netdir[dd]);
8424 if (getnct(line,1023,f,1) < 0) { /* Read a line */
8425 if (f) { /* f can be clobbered! */
8426 fclose(f); /* Close the file */
8427 f = NULL; /* Indicate next one needs opening */
8431 if (!line[0]) /* Empty line */
8434 xwords(line,7,info,0); /* Parse it */
8436 if (!info[1] || !info[2] || !info[3]) /* Required fields */
8438 if (*info[1] == ';') /* Full-line comment */
8440 if ((n = (int) strlen(info[1])) < 1) /* Length of name-tag */
8442 if (n < n1) /* Search name is longer */
8443 continue; /* Can't possibly match */
8444 if (ambiguous && n != n1)
8446 if (ckstrcmp(s,info[1],n1,0)) /* Compare using length of */
8447 continue; /* search string s. */
8451 makestr(&(nh_p[nhcount]), info[3]); /* address */
8452 makestr(&(nh_p2[nhcount]),info[2]); /* net type */
8453 makestr(&(nh_px[0][nhcount]),info[4]); /* net-specific stuff... */
8454 makestr(&(nh_px[1][nhcount]),info[5]);
8455 makestr(&(nh_px[2][nhcount]),info[6]);
8456 makestr(&(nh_px[3][nhcount]),info[7]);
8458 nhcount++; /* Count this match */
8459 if (nhcount > MAXDNUMS) { /* Watch out for too many */
8460 printf("Warning: %d matches found, %d max\n",
8467 if (nhcount == 1) { /* First one - save entry name */
8468 if (n_name) { /* Free the one from before if any */
8472 if (!(n_name = (char *)malloc(n + 1))) { /* Allocate new storage */
8473 printf("?memory allocation error - lunet:3\n");
8481 t = n; /* Remember its length */
8482 strcpy(n_name,info[1]); /* safe */
8483 } else { /* Second or subsequent one */
8484 if ((int) strlen(info[1]) == t) /* Lengths compare */
8485 if (!ckstrcmp(n_name,info[1],t,0)) /* Caseless compare OK */
8488 /* Name given by user matches entries with different names */
8490 if (ambiguous) /* Been here before */
8493 ambiguous = 1; /* Now an exact match is required */
8494 ndreset(); /* Clear out previous list */
8495 goto lu_again; /* Do it all over again. */
8502 if (nhcount == 0 && ambiguous)
8503 printf("?\"%s\" - ambiguous in network directory\n",s);
8509 #endif /* NETCONN */
8512 /* C L S C O N N X -- Close connection */
8515 clsconnx(ask) int ask; {
8518 extern int ftpget, ftpisopen(), ftpbye();
8519 if ((ftpget == 1) || ((ftpget == 2) && !local && ftpisopen()))
8520 return(success = ftpbye());
8522 debug(F101,"clsconnx local","",local);
8524 x = ask ? hupok(1) : 1; /* Make sure it's OK to close */
8527 debug(F101,"clsconnx hupok says no","",rc);
8530 ttflui(); /* Clear away buffered up junk */
8533 /* Don't hangup a line that is shared with the SLIP or PPP driver */
8534 if (!ttslip && !ttppp)
8535 #endif /* OS2ONLY */
8538 if (network && msgflg)
8539 printf(" Closing connection\n");
8540 ttclos(0); /* Close old connection, if any */
8543 extern int wasclosed, whyclosed;
8545 whyclosed = WC_CLOS;
8547 if (nmac) { /* Any macros defined? */
8549 /* printf("ON_CLOSE CLSCONNX\n"); */
8551 k = mlook(mactab,"on_close",nmac); /* Look this up */
8552 if (k >= 0) { /* If found, */
8553 if (dodo(k,ckitoa(whyclosed),0) > -1) /* set it up, */
8554 parser(1); /* and execute it */
8558 whyclosed = WC_REMO;
8563 #ifdef VMS /* Or maybe #ifndef UNIX? */
8564 else { /* Need to do this in VMS to */
8565 ttclos(0); /* free the tty channel number */
8566 rc = 1; /* obtained in ttopen() or else */
8567 } /* subsequent ttopen's won't work */
8571 if (mdmtyp < 0) { /* Switching from net to async? */
8572 if (mdmsav > -1) /* Restore modem type from last */
8573 mdmtyp = mdmsav; /* SET MODEM command, if any. */
8581 if (oldplex > -1) { /* Restore previous duplex setting. */
8585 #endif /* NETCONN */
8587 ckstrncpy(ttname,dftty,TTNAMLEN); /* Restore default communication */
8589 local = dfloc; /* device and local/remote status */
8591 cxtype = CXT_DIRECT; /* Something reasonable */
8592 speed = ttgspd(); /* Get the current speed */
8594 cxtype = CXT_REMOTE;
8598 if (xreliable > -1 && !setreliable) {
8599 reliable = xreliable;
8600 debug(F101,"clsconnx reliable A","",reliable);
8601 } else if (!setreliable) {
8602 reliable = SET_AUTO;
8603 debug(F101,"clsconnx reliable B","",reliable);
8606 setflow(); /* Revert flow control */
8611 clskconnx(x) int x; { /* Close Kermit connection only */
8612 int t, rc; /* (not FTP) */
8625 /* May 2002: setlin() decomposition starts here ... */
8628 #define SRVBUFSIZ PIPENAML
8630 #define SRVBUFSIZ 63
8632 #define HOSTNAMLEN 15*65
8635 static char * tmpstring = NULL;
8636 static char * tmpusrid = NULL;
8639 char * sshcmd = NULL;
8640 char * defsshcmd = "ssh -e none";
8643 char * sshrcmd = NULL;
8644 char * sshtmpcmd = NULL;
8645 #endif /* SSHBUILTIN */
8648 /* c x _ f a i l -- Common error exit routine for cx_net, cx_line */
8651 cx_fail(msg, text) int msg; char * text; {
8652 makestr(&slmsg,text); /* For the record (or GUI) */
8653 if (msg) /* Not GUI, not quiet, etc */
8654 printf("?%s\n",text); /* Print error message */
8655 slrestor(); /* Restore LINE/HOST to known state */
8656 return(msg ? -9 : (success = 0)); /* Return appropriate code */
8660 /* c x _ n e t -- Make a network connection */
8665 protocol = protocol type
8666 host = string pointer to host name.
8667 svc = string pointer to service or port on host.
8668 username = username for connection
8669 password = password for connection
8670 command = command to execute
8671 param1 = Telnet: Authentication type
8673 param2 = Telnet: Encryption type
8674 SSH: Command as Subsystem
8675 param3 = Telnet: 1 to wait for negotiations, 0 otherwise
8677 cx = 1 to automatically enter Connect mode, 0 otherwise.
8678 sx = 1 to automatically enter Server mode, 0 otherwise.
8679 flag = if no host name given, 1 = close current connection, 0 = resume
8680 gui = 1 if called from GUI dialog, 0 otherwise.
8683 0 on failure and no message printed, slmsg set to failure message.
8684 -9 on failure and message printed, ditto.
8688 cx_net( int net, int protocol, char * xhost, char * svc,
8689 char * username, char * password, char * command,
8690 int param1, int param2, int param3, int cx, int sx, int flag, int gui)
8691 #else /* CK_ANSIC */
8692 cx_net(net, protocol, xhost, svc,
8693 username, password, command,
8694 param1, param2, param3, cx, sx, flag, gui)
8695 char * xhost, * svc, * username, *password, *command;
8696 int net, protocol, cx, sx, flag, param1, param2, param3, gui;
8697 #endif /* CK_ANSIC */
8703 extern char pwbuf[], * g_pswd;
8704 extern int pwflg, pwcrypt, g_pflg, g_pcpt, nolocal;
8706 char srvbuf[SRVBUFSIZ+1]; /* Service */
8707 char hostbuf[HOSTNAMLEN]; /* Host buffer to manipulate */
8708 char hostname[HOSTNAMLEN]; /* Copy of host parameter */
8709 char * host = hostbuf; /* Pointer to copy of host param */
8711 if (!xhost) xhost = ""; /* Watch out for null pointers */
8713 ckstrncpy(host,xhost,HOSTNAMLEN); /* Avoid buffer confusion */
8715 debug(F110,"cx_net host",host,0);
8716 debug(F111,"cx_net service",svc,SRVBUFSIZ);
8717 debug(F101,"cx_net network type","",net);
8719 msg = (gui == 0) && msgflg; /* Whether to print messages */
8722 debug(F101,"cx_net nnetdir","",nnetdir);
8723 x = 0; /* Look up in network directory */
8724 if (*host == '=') { /* If number starts with = sign */
8725 host++; /* strip it */
8726 while (*host == SP) host++; /* and any leading spaces */
8727 debug(F110,"cx_net host 2",host,0);
8729 } else if (*host) { /* We want to look it up. */
8730 if (nnetdir > 0) /* If there is a directory... */
8731 x = lunet(host); /* (sets nhcount) */
8732 else /* otherwise */
8733 nhcount = 0; /* we didn't find any there */
8734 if (x < 0) /* Internal error? */
8735 return(cx_fail(msg,"Network directory lookup error"));
8736 debug(F111,"cx_net lunet nhcount",host,nhcount);
8740 /* New connection wanted. Make a copy of the host name/address... */
8742 if (clskconnx(1) < 0) /* Close current Kermit connection */
8743 return(cx_fail(msg,"Error closing previous connection"));
8745 if (*host) { /* They gave a hostname */
8746 _local = 1; /* Network connection always local */
8748 mdmsav = mdmtyp; /* Remember old modem type */
8749 mdmtyp = -net; /* Special code for network */
8750 } else { /* They just said "set host" */
8751 host = dftty; /* So go back to normal */
8752 _local = dfloc; /* default tty, location, */
8753 if (flag) { /* Close current connection */
8754 setflow(); /* Maybe change flow control */
8755 haveline = 1; /* (* is this right? *) */
8765 /* XXX - Is this right? */
8766 /* Should we be returning without doing anything ? */
8767 /* Yes it's right -- we closed the old connection just above. */
8768 return(success = 1);
8772 if (host != line) /* line[] is a global */
8773 ckstrncpy(line,host,LINBUFSIZ);
8774 ckstrncpy(hostname,host,HOSTNAMLEN);
8775 ckstrncpy(srvbuf,svc,SRVBUFSIZ+1);
8778 if ((nhcount > 1) && msg) {
8780 printf("%d entr%s found for \"%s\"%s\n",
8782 (nhcount == 1) ? "y" : "ies",
8784 (nhcount > 0) ? ":" : "."
8786 for (i = 0; i < nhcount; i++) {
8787 printf("%3d. %-12s => %-9s %s",
8788 i+1,n_name,nh_p2[i],nh_p[i]);
8789 for (k = 0; k < 4; k++) { /* Also list net-specific items */
8790 if (nh_px[k][i]) /* free format... */
8791 printf(" %s",nh_px[k][i]);
8807 for (i = 0; i < n; i++) { /* Loop for each entry found */
8808 debug(F101,"cx_net loop i","",i);
8810 if (nhcount > 0) { /* If we found at least one entry... */
8811 ckstrncpy(line,nh_p[i],LINBUFSIZ); /* Copy current entry */
8812 if (lookup(netcmd,nh_p2[i],nnets,&x) > -1) { /* Net type */
8814 xx = netcmd[x].kwval;
8815 /* User specified SSH so don't let net directory override */
8816 if (net != NET_SSH || xx != NET_TCPB) {
8821 makestr(&slmsg,"Network type not supported");
8823 printf("Error - network type \"%s\" not supported\n",
8828 switch (net) { /* Net-specific directory things */
8830 case NET_SSH: /* SSH */
8831 /* Any SSH specific network directory stuff? */
8832 break; /* NET_SSH */
8833 #endif /* SSHBUILTIN */
8835 case NET_TCPB: { /* TCP/IP TELNET,RLOGIN,... */
8840 /* Extract ":service", if any, from host string */
8841 debug(F110,"cx_net service 1",line,0);
8842 for (q = line; (*q != '\0') && (*q != ':'); q++)
8844 if (*q == ':') { *q++ = NUL; flag = 1; }
8845 debug(F111,"cx_net service 2",line,flag);
8847 /* Get service, if any, from directory entry */
8851 ckstrncpy(srvbuf,nh_px[0][i],SRVBUFSIZ);
8852 debug(F110,"cx_net service 3",srvbuf,0);
8855 ckstrncpy(srvbuf,q,SRVBUFSIZ);
8856 debug(F110,"cx_net service 4",srvbuf,0);
8859 ckstrncpy(hostname,line,HOSTNAMLEN);
8861 /* If we have a service, append to host name/address */
8863 ckstrncat(line, ":", LINBUFSIZ);
8864 ckstrncat(line, srvbuf, LINBUFSIZ);
8865 debug(F110,"cx_net service 5",line,0);
8868 /* If no service given but command was RLOGIN */
8869 else if (ttnproto == NP_RLOGIN) { /* add this... */
8870 ckstrncat(line, ":login",LINBUFSIZ);
8871 debug(F110,"cx_net service 6",line,0);
8873 #ifdef CK_AUTHENTICATION
8875 else if (ttnproto == NP_K4LOGIN ||
8876 ttnproto == NP_K5LOGIN) { /* add this... */
8877 ckstrncat(line, ":klogin",LINBUFSIZ);
8878 debug(F110,"cx_net service 7",line,0);
8880 else if (ttnproto == NP_EK4LOGIN ||
8881 ttnproto == NP_EK5LOGIN) { /* add this... */
8882 ckstrncat(line, ":eklogin",LINBUFSIZ);
8883 debug(F110,"cx_net service 8",line,0);
8885 #endif /* CK_KERBEROS */
8886 #endif /* CK_AUTHENTICATION */
8887 #endif /* RLOGCODE */
8888 else { /* Otherwise, add ":telnet". */
8889 ckstrncat(line, ":telnet", LINBUFSIZ);
8890 debug(F110,"cx_net service 9",line,0);
8892 if (username) { /* This is a parameter... */
8893 ckstrncpy(uidbuf,username,UIDBUFLEN);
8896 /* Fifth field, if any, is user ID (for rlogin) */
8898 if (nh_px[1][i] && !uidflag)
8899 ckstrncpy(uidbuf,username,UIDBUFLEN);
8901 if (IS_RLOGIN() && !uidbuf[0])
8902 return(cx_fail(msg,"Username required"));
8903 #endif /* RLOGCODE */
8904 #endif /* TCPSOCKET */
8907 case NET_PIPE: /* Pipe */
8909 if (!pipename[0]) { /* User didn't give a pipename */
8910 if (nh_px[0][i]) { /* But directory entry has one */
8911 if (strcmp(pipename,"\\pipe\\")) {
8912 ckstrncpy(pipename,"\\pipe\\",LINBUFSIZ);
8913 ckstrncat(srvbuf,nh_px[0][i],PIPENAML-6);
8915 ckstrncpy(pipename,nh_px[0][i],PIPENAML);
8917 debug(F110,"cx_net pipeneme",pipename,0);
8923 case NET_SLAT: /* LAT / CTERM */
8925 if (!slat_pwd[0]) { /* User didn't give a password */
8926 if (nh_px[0][i]) { /* But directory entry has one */
8927 ckstrncpy(slat_pwd,nh_px[0][i],18);
8928 debug(F110,"cx_net SuperLAT password",slat_pwd,0);
8931 #endif /* SUPERLAT */
8934 case NET_SX25: /* X.25 keyword parameters */
8938 int k; /* Cycle through the four fields */
8939 for (k = 0; k < 4; k++) {
8940 if (!nh_px[k][i]) /* Bail out if none left */
8942 if (!ckstrcmp(nh_px[k][i],"cug=",4,0)) {
8943 closgr = atoi(nh_px[k][i]+4);
8944 debug(F101,"X25 CUG","",closgr);
8945 } else if (!ckstrcmp(nh_px[k][i],"cud=",4,0)) {
8947 ckstrncpy(udata,nh_px[k][i]+4,MAXCUDATA);
8948 debug(F110,"X25 CUD",cudata,0);
8949 } else if (!ckstrcmp(nh_px[k][i],"rev=",4,0)) {
8950 revcall = !ckstrcmp(nh_px[k][i]+4,"=on",3,0);
8951 debug(F101,"X25 REV","",revcall);
8953 } else if (!ckstrcmp(nh_px[k][i],"pad=",4,0)) {
8956 s1 = s2 = nh_px[k][i]+4; /* PAD parameters */
8957 while (*s2) { /* Pick them apart */
8963 } else if (*s2 == ',') {
8967 debug(F111,"X25 PAD",x3par,x3val);
8969 x3par <= MAXPADPARMS)
8970 padparms[x3par] = x3val;
8981 default: /* Nothing special for other nets */
8986 { /* No directory entries found. */
8987 ckstrncpy(line,hostname,LINBUFSIZ); /* Put this back... */
8988 /* If the user gave a TCP service */
8989 if (net == NET_TCPB || net == NET_SSH)
8990 if (*srvbuf) { /* Append it to host name/address */
8991 ckstrncat(line, ":", LINBUFSIZ);
8992 ckstrncat(line, srvbuf,LINBUFSIZ);
8996 Get here with host name/address and all net-specific
8997 parameters set, ready to open the connection.
8999 mdmtyp = -net; /* This should have been done */
9000 /* already but just in case ... */
9002 debug(F110,"cx_net net line[] before ttopen",line,0);
9003 debug(F101,"cx_net net mdmtyp before ttopen","",mdmtyp);
9004 debug(F101,"cx_net net ttnproto","",ttnproto);
9007 if (net == NET_SSH) {
9008 makestr(&ssh_hst,hostname); /* Stash everything */
9010 if (!sl_uid_saved) {
9011 ckstrncpy(sl_uidbuf,uidbuf,UIDBUFLEN);
9014 ckstrncpy(uidbuf,username,UIDBUFLEN);
9017 makestr(&ssh_prt,srvbuf);
9019 makestr(&ssh_prt,NULL);
9022 makestr(&ssh_cmd,brstrip(command));
9025 makestr(&ssh_cmd,NULL);
9029 if (!sl_ssh_ver_saved) {
9030 sl_ssh_ver = ssh_ver;
9031 sl_ssh_ver_saved = 1;
9033 #endif /* SSHTEST */
9038 if (!sl_ssh_xfw_saved) {
9039 sl_ssh_xfw = ssh_xfw;
9040 sl_ssh_xfw_saved = 1;
9042 #endif /* SSHTEST */
9045 } else /* NET_SSH */
9046 #endif /* SSHBUILTIN */
9048 if (net == NET_TCPB) {
9052 ttnproto = protocol;
9058 ttnproto = protocol;
9064 ttnproto = NP_TELNET;
9070 ttnproto = NP_TELNET;
9085 ttnproto = protocol;
9092 #ifdef CK_AUTHENTICATION
9093 if ((ttnproto == NP_TELNET || ttnproto == NP_KERMIT) &&
9095 if (!sl_auth_saved) {
9097 for (x = 0; x < AUTHTYPLSTSZ; x++)
9098 sl_auth_type_user[x] = auth_type_user[x];
9101 if (!sl_topt_a_s_saved) {
9102 sl_topt_a_su = TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION);
9103 sl_topt_a_s_saved = 1;
9105 if (!sl_topt_a_c_saved) {
9106 sl_topt_a_cm = TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION);
9107 sl_topt_a_c_saved = 1;
9111 auth_type_user[0] = AUTHTYPE_AUTO;
9112 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_RQ;
9113 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_RQ;
9116 auth_type_user[0] = AUTHTYPE_NULL;
9117 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_RF;
9118 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_RF;
9122 auth_type_user[0] = AUTHTYPE_SRP;
9123 auth_type_user[1] = AUTHTYPE_NULL;
9124 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9125 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9130 auth_type_user[0] = AUTHTYPE_SSL;
9131 auth_type_user[1] = AUTHTYPE_NULL;
9132 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9133 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9138 auth_type_user[0] = AUTHTYPE_NTLM;
9139 auth_type_user[1] = AUTHTYPE_NULL;
9140 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9141 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9145 case AUTHTYPE_KERBEROS_V4:
9146 auth_type_user[0] = AUTHTYPE_KERBEROS_V4;
9147 auth_type_user[1] = AUTHTYPE_NULL;
9148 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9149 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9152 case AUTHTYPE_KERBEROS_V5:
9153 auth_type_user[0] = AUTHTYPE_KERBEROS_V5;
9154 auth_type_user[1] = AUTHTYPE_NULL;
9155 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9156 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
9158 #endif /* CK_KERBEROS */
9162 If the user requires a particular type of Kerberos connection,
9163 make sure we have a valid TGT.
9165 makestr(&slmsg,"Authentication failure");
9166 if ((ttnproto == NP_TELNET || ttnproto == NP_KERMIT) &&
9168 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) == TN_NG_MU ||
9170 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) == TN_NG_MU)
9173 if ( auth_type_user[0] == AUTHTYPE_KERBEROS_V4 ) {
9174 extern int krb4_autoget;
9175 if (!ck_krb4_is_installed())
9177 "Required authentication method (Kerberos 4) is not installed"));
9179 /* This code results in false failures when using */
9180 /* kerberos to machines in realms other than the */
9181 /* default since we don't know the realm of the */
9182 /* other machine until perform the reverse DNS */
9184 else if (line[0] != '*' && !ck_krb4_is_tgt_valid() &&
9186 krb4_autoget && !ck_krb4_autoget_TGT(NULL))) {
9188 "Kerberos 4: Ticket Getting Ticket not valid"));
9190 #endif /* COMMENT */
9191 } else if (auth_type_user[0] == AUTHTYPE_KERBEROS_V5) {
9192 extern int krb5_autoget;
9193 if (!ck_krb5_is_installed()) {
9195 "Required authentication method (Kerberos 5) is not installed"));
9198 /* This code results in false failures when using */
9199 /* kerberos to machines in realms other than the */
9200 /* default since we don't know the realm of the */
9201 /* other machine until perform the reverse DNS */
9203 else if (line[0] != '*' && !ck_krb5_is_tgt_valid() &&
9205 krb5_autoget && !ck_krb5_autoget_TGT(NULL))) {
9207 "Kerberos 5: Ticket Getting Ticket not valid."));
9209 #endif /* COMMENT */
9211 #endif /* CK_KERBEROS */
9213 if (auth_type_user[0] == AUTHTYPE_NTLM) {
9214 if (!ck_ntlm_is_installed()) {
9216 "Required authentication method (NTLM) is not installed"));
9217 } else if (line[0] != '*' && !ck_ntlm_is_valid(0)) {
9218 return(cx_fail(msg,"NTLM: Credentials are unavailable."));
9223 if (auth_type_user[0] == AUTHTYPE_SSL) {
9224 if (!ck_ssleay_is_installed()) {
9226 "Required authentication method (SSL) is not installed"));
9231 if (auth_type_user[0] == AUTHTYPE_SRP) {
9232 if (!ck_srp_is_installed()) {
9234 "Required authentication method (SRP) is not installed"));
9239 #endif /* CK_AUTHENTICATION */
9240 #ifdef CK_ENCRYPTION
9241 if ((ttnproto == NP_TELNET || ttnproto == NP_KERMIT) &&
9244 sl_cx_type = cx_type;
9247 if (!sl_topt_e_s_saved) {
9248 sl_topt_e_su = TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION);
9249 sl_topt_e_sm = TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION);
9250 sl_topt_e_s_saved = 1;
9252 if (!sl_topt_e_c_saved) {
9253 sl_topt_e_cu = TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION);
9254 sl_topt_e_cm = TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION);
9255 sl_topt_e_c_saved = 1;
9258 if (cx_type == CX_AUTO) {
9259 TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
9260 TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
9261 TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
9262 TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
9263 } else if (cx_type == CX_NONE) {
9264 TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
9265 TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
9266 TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
9267 TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
9269 TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
9270 TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
9271 TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
9272 TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
9275 if (ttnproto == NP_EK4LOGIN || ttnproto == NP_EK5LOGIN ||
9276 (ttnproto == NP_TELNET || ttnproto == NP_KERMIT) &&
9278 TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) == TN_NG_MU &&
9279 TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_MU) ||
9281 TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) == TN_NG_MU &&
9282 TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_MU))
9284 if (!ck_crypt_is_installed()) {
9286 "Required Encryption methods are not installed"));
9289 #endif /* CK_ENCRYPTION */
9293 if (ttnproto == NP_K4LOGIN || ttnproto == NP_EK4LOGIN) {
9294 extern int krb4_autoget;
9298 /* We don't have the full hostname at yet so */
9299 /* we do a DNS lookup before calling ttopen() */
9301 realm = ck_krb4_realmofhost(ckgetfqhostname(hostname));
9302 ckmakmsg(tgt,256,"krbtgt.",realm,"@",realm);
9303 if (!ck_krb4_is_installed()) {
9305 "Required authentication method (Kerberos 4) is not installed"
9308 if ((ck_krb4_tkt_isvalid(tgt) <= 0) &&
9310 krb4_autoget && !ck_krb4_autoget_TGT(realm))) {
9312 "Kerberos 4: Ticket Getting Ticket not valid"));
9318 if (ttnproto == NP_K5LOGIN || ttnproto == NP_EK5LOGIN ||
9319 ttnproto == NP_K5U2U)
9321 extern int krb5_autoget;
9325 /* Must get full hostname before calling ttopen() */
9327 realm = ck_krb5_realmofhost(ckgetfqhostname(hostname));
9328 ckmakmsg(tgt,256,"krbtgt/",realm,"@",realm);
9330 if (!ck_krb5_is_installed()) {
9332 "Required authentication method (Kerberos 5) not installed"));
9333 } else if (!((ck_krb5_tkt_isvalid(NULL,tgt) > 0) ||
9334 ck_krb5_is_tgt_valid()) &&
9336 krb5_autoget && !ck_krb5_autoget_TGT(realm))) {
9338 "Kerberos 5: Ticket Getting Ticket not valid."));
9342 #endif /* CK_KERBEROS */
9343 #endif /* RLOGCODE */
9348 if (!sl_uid_saved) {
9349 ckstrncpy(sl_uidbuf,uidbuf,UIDBUFLEN);
9352 ckstrncpy(uidbuf,username,UIDBUFLEN);
9355 #endif /* RLOGCODE */
9358 sl_tn_wait = tn_wait_flg;
9361 tn_wait_flg = param3;
9364 } /* if (net == NET_TCPB) */
9365 #endif /* TCPSOCKET */
9371 ckstrncpy(pwbuf,password,PWBUFL+1);
9377 #endif /* CK_SECURITY */
9380 /* Try to open - network */
9381 ckstrncpy(ttname,line,TTNAMLEN);
9382 y = ttopen(line, &_local, mdmtyp, 0 );
9385 /* If the connection failed and we are using an HTTP Proxy
9386 * and the reason for the failure was an authentication
9387 * error, then we need to give the user to ability to
9388 * enter a username and password, just like a browser.
9390 * I tried to do all of this within the netopen() call
9391 * but it is much too much work.
9393 while (y < 0 && tcp_http_proxy != NULL ) {
9395 if (tcp_http_proxy_errno == 401 ||
9396 tcp_http_proxy_errno == 407 ) {
9397 char uid[UIDBUFLEN];
9399 struct txtbox tb[2];
9403 tb[0].t_len = UIDBUFLEN;
9404 tb[0].t_lbl = "Proxy Userid: ";
9405 tb[0].t_dflt = NULL;
9409 tb[1].t_lbl = "Proxy Passphrase: ";
9410 tb[1].t_dflt = NULL;
9413 ok = uq_mtxt("Proxy Server Authentication Required\n",
9417 char * proxy_user, * proxy_pwd;
9419 proxy_user = tcp_http_proxy_user;
9420 proxy_pwd = tcp_http_proxy_pwd;
9422 tcp_http_proxy_user = uid;
9423 tcp_http_proxy_pwd = pwd;
9425 ckstrncpy(ttname,line,TTNAMLEN);
9426 y = ttopen(line, &_local, mdmtyp, 0);
9427 memset(pwd,0,sizeof(pwd));
9428 tcp_http_proxy_user = proxy_user;
9429 tcp_http_proxy_pwd = proxy_pwd;
9438 makestr(&slmsg,"Network connection failure");
9440 if (msg && hints && !xcmdsrc && IS_RLOGIN()) {
9441 makestr(&slmsg,"RLOGIN failure");
9442 if (socket_errno == EACCES) {
9443 printf("*************************\n");
9445 "Hint: RLOGIN requires privileges to open an outbound port.\n");
9447 "(Use SET HINTS OFF to suppress future hints.)\n");
9448 printf("*************************\n");
9451 #else /* Not VMS... */
9454 debug(F111,"set host line, errno","",errno);
9455 makestr(&slmsg,ck_errstr());
9458 printf("Can't connect to %s\n",line);
9461 if (hints && !xcmdsrc && IS_RLOGIN()) {
9462 makestr(&slmsg,"RLOGIN failure");
9463 printf("*************************\n");
9465 "Hint: RLOGIN requires privileges to open an outbound port.\n");
9467 "(Use SET HINTS OFF to suppress future hints.)\n");
9468 printf("*************************\n");
9472 } else printf("Can't connect to %s\n",line);
9475 if (msg) printf("Can't open connection to %s\n",line);
9487 /* This works but it messes up interactive anonymous login */
9490 /* If we have connected to an Internet Kermit service */
9491 /* and a /USER: switch was given, then log in. */
9493 if (TELOPT_U(TELOPT_KERMIT) || TELOPT_ME(TELOPT_KERMIT)) {
9494 debug(F111,"cx_net IKSD /USER:",uidbuf,haveuser);
9495 if (haveuser /* && cx == 0 */ ) { /* /USER: given */
9496 char * psw = pwbuf; /* Do we have a password? */
9497 if (!*psw) { /* No... */
9498 if (!strcmp(uidbuf,"anonymous") ||
9499 !strcmp(uidbuf,"ftp")) {
9500 extern char myhost[];
9501 char * u = (char *)sl_uidbuf;
9502 char * h = (char *)myhost;
9503 if (!*u) u = "nobody";
9504 if (!*h) h = "nowhere";
9505 ckmakmsg(tmpbuf,TMPBUFSIZ,u,"@",h,NULL);
9507 debug(F110,"cx_net IKSD anon",psw,0);
9509 readpass(" Password: ",pwbuf,PWBUFL);
9512 sstate = setgen('I',uidbuf,psw,"");
9515 #endif /* IKS_OPTION */
9517 #endif /* COMMENT */
9521 duplex = 0; /* Remote echo */
9533 cxtype = CXT_NETBIOS;
9551 debug(F101,"cx_net post ttopen success","",success);
9553 local = dfloc; /* Go back to normal */
9555 ckstrncpy(ttname,dftty,TTNAMLEN); /* Restore default tty name */
9558 network = 0; /* No network connection active */
9560 if (mdmtyp < 0) { /* Switching from net to async? */
9561 if (mdmsav > -1) /* Restore modem type from last */
9562 mdmtyp = mdmsav; /* SET MODEM command, if any. */
9567 return(0); /* Return failure */
9569 if (_local > -1) local = _local; /* Opened ok, set local/remote. */
9570 makestr(&slmsg,NULL);
9571 network = (mdmtyp < 0); /* Remember connection type. */
9572 ckstrncpy(ttname,s,TTNAMLEN); /* Copy name into real place. */
9573 debug(F110,"cx_net ok",ttname,0);
9574 debug(F101,"cx_net network","",network);
9576 if ((reliable != SET_OFF || !setreliable)) /* Assume not reliable. */
9579 if (!network || istncomport())
9580 speed = ttgspd(); /* Get the current speed. */
9581 debug(F101,"cx_net local","",local);
9583 debug(F101,"cx_net net","",net);
9585 /* Force prefixing of 255 on TCP/IP connections... */
9589 #endif /* SSHBUILTIN */
9591 debug(F101,"cx_net reliable A","",reliable);
9593 ctlp[(unsigned)255] = 1;
9594 #endif /* CK_SPEED */
9595 if ((reliable != SET_OFF || !setreliable)) {
9597 if (istncomport()) { /* Telnet communication port */
9598 reliable = SET_OFF; /* Transport is not reliable */
9599 debug(F101,"cx_net reliable istncomport()","",1);
9601 reliable = SET_ON; /* Transport is reliable end to end */
9602 debug(F101,"cx_net reliable istncomport()","",0);
9605 reliable = SET_ON; /* Transport is reliable end to end */
9606 #endif /* ifdef TN_COMPORT */
9608 debug(F101,"cx_net reliable B","",reliable);
9609 } else if (net == NET_SX25 ||
9613 duplex = 1; /* Local echo for X.25 */
9614 if (reliable != SET_OFF || !setreliable)
9615 reliable = SET_ON; /* Transport is reliable end to end */
9620 debug(F101,"cx_net reliable","",reliable);
9623 if (mdmtyp <= 0) /* Network or Direct Connection */
9624 DialerSend(OPT_KERMIT_CONNECT, 0);
9629 setflow(); /* Set appropriate flow control */
9634 #endif /* CKLOGDIAL */
9638 if (nmac) { /* Any macros defined? */
9640 k = mlook(mactab,"on_open",nmac); /* Look this up */
9641 if (k >= 0) { /* If found, */
9642 if (dodo(k,ttname,0) > -1) /* set it up, */
9643 parser(1); /* and execute it */
9649 if (local && (cx || sx)) { /* /CONNECT or /SERVER switch given */
9650 if (cx) { /* /CONNECT */
9652 /* Command was confirmed so we can pre-pop command level. */
9653 /* This is so CONNECT module won't think we're executing a */
9654 /* script if CONNECT was the final command in the script. */
9666 success = doconect(0, cmdlvl == 0 ? 1 : 0);
9669 debug(F101,"cx_net post doconect success","",success);
9672 } else if (sx) { /* /SERVER */
9678 if (local) displa = 1;
9680 reqoff(); /* No DOS requestors while server */
9693 return(success = 1);
9695 #endif /* NETCONN */
9697 /* c x _ s e r i a l -- Make a serial connection */
9701 device = string pointer to device name.
9702 cx = 1 to automatically enter Connect mode, 0 otherwise.
9703 sx = 1 to automatically enter Server mode, 0 otherwise.
9704 shr = 1 if device should be opened in shareable mode, 0 otherwise.
9705 flag = if no dev name given: 1 = close current connection, 0 = resume.
9706 gui = 1 if called from GUI dialog, 0 otherwise.
9709 0 on failure and no message printed, slmsg set to failure message.
9710 -9 on failure and message printed, ditto.
9713 /* these are bit flags */
9720 cx_serial(char *device,
9721 int cx, int sx, int shr, int flag, int gui, int special)
9722 #else /* CK_ANSIC */
9723 cx_serial(device, cx, sx, shr, flag, gui, special)
9724 char * device; int cx, sx, shr, flag, gui, special;
9725 #endif /* CK_ANSIC */
9727 int i, n, x, y, msg;
9731 debug(F110,"cx_serial device",device,0);
9733 msg = (gui == 0) && msgflg; /* Whether to print messages */
9739 debug(F101,"cx_serial mdmtyp","",mdmtyp);
9740 if (clskconnx(1) < 0) /* Close the Kermit connection */
9741 return(success = 0);
9742 if (*s) { /* They gave a device name */
9743 _local = -1; /* Let ttopen decide about it */
9744 } else { /* They just said "set line" */
9745 s = dftty; /* so go back to normal tty */
9746 _local = dfloc; /* and mode. */
9750 extern int ok_to_share;
9755 #ifdef OS2 /* Must wait until after ttclos() */
9756 #ifdef NT /* to change these settings */
9758 tttapi = special & CX_TAPI;
9759 #endif /* CK_TAPI */
9761 ttslip = special & CX_SLIP;
9762 ttppp = special & CX_PPP;
9764 ttshare = shr; /* Shareable device ? */
9765 debug(F110,"OS2 SET PORT final s",s,"");
9768 /* Open the new line */
9770 ckstrncpy(ttname,s,TTNAMLEN);
9771 if ((y = ttopen(s,&_local,mdmtyp,cdtimo)) > -1) {
9772 cxtype = (mdmtyp > 0) ? CXT_MODEM : CXT_DIRECT;
9776 /* if the line is a tapi device, then we need to auto-execute */
9777 /* SET MODEM TYPE TAPI - which we do the equivalent of here. */
9781 initmdm(38); /* From ckudia.c n_TAPI == 38 */
9783 #endif /* CK_TAPI */
9786 } else { /* Failed */
9788 if (!strcmp(s,dftty)) /* Do not generate an error with dftty */
9790 else if (y == -6 && ttslip) {
9791 makestr(&slmsg,"Can't access SLIP driver");
9792 if (msg) printf("?%s\n",slmsg);
9793 } else if (y == -6 && ttppp) {
9794 makestr(&slmsg,"Can't access PPP driver");
9795 if (msg) printf("?%s\n",slmsg);
9797 #endif /* OS2ONLY */
9799 makestr(&slmsg,"Timed out - no carrier");
9801 printf("?%s\n",slmsg);
9803 printf("\n*************************\n");
9805 "HINT (Use SET HINTS OFF to suppress future hints):\n");
9807 "Try SET CARRIER OFF and SET LINE again, or else\n");
9808 printf("SET MODEM, SET LINE, and then DIAL.\n");
9809 printf("*************************\n\n");
9812 } else if (y == -3) {
9813 makestr(&slmsg,"Access to lock denied");
9817 "Sorry, write access to UUCP lockfile directory denied.\n");
9820 printf("\n*************************\n");
9822 "HINT (Use SET HINTS OFF to suppress future hints):\n");
9824 "Please read the installation instructions file, %sckuins.txt,\n",
9825 k_info_dir ? k_info_dir : ""
9828 "or the UNIX appendix of the manual, \"Using C-Kermit\"\n"
9831 "or visit http://www.columbia.edu/kermit/ckuins.html \n"
9833 printf("*************************\n\n");
9835 #endif /* NOHINTS */
9837 printf("Sorry, access to lock denied: %s\n",s);
9840 } else if (y == -4) {
9841 makestr(&slmsg,"Access to device denied");
9843 printf("Sorry, access to device denied: %s\n",s);
9847 printf("\n*************************\n");
9849 "HINT (Use SET HINTS OFF to suppress future hints):\n");
9851 "Please read the installation instructions file, %sckuins.txt,\n",
9852 k_info_dir ? k_info_dir : ""
9855 "or the UNIX appendix of the manual, \"Using C-Kermit\".\n"
9857 printf("*************************\n\n");
9859 #endif /* NOHINTS */
9862 } else if (y == -5) {
9863 makestr(&slmsg,"Device is in use or unavailable");
9867 "Sorry, device is in use or otherwise unavailable: %s\n",s);
9869 printf("Sorry, device is in use: %s\n",s);
9871 } else { /* Other error. */
9872 makestr(&slmsg,"Device open failed");
9880 int x; /* Find a safe, long buffer */
9881 makestr(&slmsg,ck_errstr());
9883 debug(F111,"cx_serial serial errno",slmsg,errno);
9886 printf("Connection to %s failed: %s\n",s,slmsg);
9888 printf("Sorry, can't open connection: %s\n",s);
9891 network = 0; /* No network connection active */
9894 local = dfloc; /* Go back to normal */
9896 ckstrncpy(ttname,dftty,TTNAMLEN); /* Restore default tty name */
9899 if (mdmtyp < 0) { /* Switching from net to async? */
9900 if (mdmsav > -1) /* Restore modem type from last */
9901 mdmtyp = mdmsav; /* SET MODEM command, if any. */
9906 return(msg ? -9 : 0); /* Return failure */
9909 local = _local; /* Opened ok, set local/remote. */
9910 makestr(&slmsg,NULL); /* Erase SET LINE message */
9911 ckstrncpy(ttname,s,TTNAMLEN); /* Copy name into real place. */
9912 debug(F110,"cx_serial ok",ttname,0);
9914 if ((reliable != SET_OFF || !setreliable)) /* Assume not reliable. */
9919 setflow(); /* Set appropriate flow control */
9923 #endif /* CKLOGDIAL */
9927 if (nmac) { /* Any macros defined? */
9929 k = mlook(mactab,"on_open",nmac); /* Look this up */
9930 if (k >= 0) { /* If found, */
9931 if (dodo(k,ttname,0) > -1) /* set it up, */
9932 parser(1); /* and execute it */
9938 if (local && (cx || sx)) { /* /CONNECT or /SERVER switch given */
9940 if (carrier != CAR_OFF) { /* Looking for carrier? */
9941 /* Open() turns on DTR -- wait up to a second for CD to come up */
9943 for (i = 0; i < 10; i++) { /* WAIT 1 CD... */
9945 if (x < 0 || x & BM_DCD)
9950 if (cx) { /* /CONNECT */
9951 /* Command was confirmed so we can pre-pop command level. */
9952 /* This is so CONNECT module won't think we're executing a */
9953 /* script if CONNECT was the final command in the script. */
9965 success = doconect(0, cmdlvl == 0 ? 1 : 0);
9970 } else if (sx) { /* /SERVER */
9976 if (local) displa = 1;
9978 reqoff(); /* No DOS requestors while server */
9991 return(success = 1);
9995 /* S E T L I N -- parse name of and then open communication device. */
9998 xx == XYLINE for a serial (tty) line, XYHOST for a network host,
9999 zz == 0 means if user doesn't give a device name, continue current
10000 active connection (if any);
10001 zz != 0 means if user doesn't give a device name, then close the
10002 current connection and restore the default communication device.
10003 fc == 0 to just make the connection, 1 to also CONNECT (e.g. "telnet").
10009 extern char pwbuf[], * g_pswd;
10010 extern int pwflg, pwcrypt, g_pflg, g_pcpt, nolocal;
10012 /* int tn_wait_sv; */
10015 int c, i, haveswitch = 0;
10018 int wild = 0; /* Filespec has wildcards */
10019 int cx = 0; /* Connect after */
10020 int sx = 0; /* Become server after */
10021 int a_type = -1; /* Authentication type */
10022 int e_type = -1; /* Telnet /ENCRYPT type */
10023 #ifdef CK_ENCRYPTION
10024 int encrypt = 0; /* Encrypted? */
10025 #endif /* CK_ENCRYPTION */
10026 int shr = 0; /* Share serial device */
10027 int confirmed = 0; /* Command has been entered */
10028 struct FDB sw, tx, nx;
10036 #endif /* TCPSOCKET */
10038 char srvbuf[SRVBUFSIZ+1];
10044 int xxslip = 0, xxppp = 0;
10050 debug(F101,"setlin fc","",fc);
10051 debug(F101,"setlin zz","",zz);
10052 debug(F101,"setlin xx","",xx);
10055 if (xx == XXSSH) { /* SSH becomes PTY SSH ... */
10059 #endif /* SSHCMD */
10062 /* tn_wait_sv = tn_wait_flg; */
10063 wait = tn_wait_flg;
10065 /* tn_wait_sv = 0; */
10067 #endif /* TNCODE */
10072 makestr(&slmsg,"Making connections is disabled");
10073 printf("?Sorry, making connections is disabled\n");
10079 if (fc != 0 || zz == 0) /* Preset /CONNECT switch */
10082 debug(F101,"setlin cx","",cx);
10092 makestr(&tmpstring,NULL);
10093 #endif /* CK_SECURITY */
10095 makestr(&tmpusrid,NULL);
10096 #endif /* NETCONN */
10098 autoflow = 1; /* Enable automatic flow setting */
10100 if (xx == XYHOST) { /* SET HOST <hostname> */
10102 makestr(&slmsg,"Network connections not supported");
10103 printf("?%s\n",slmsg);
10105 #else /* NETCONN */
10107 if ((mynet == NET_CMD || mynet == NET_PTY || dossh) && nopush) {
10108 makestr(&slmsg,"Access to external commands is disabled");
10109 printf("?Sorry, access to external commands is disabled\n");
10112 #endif /* NOPUSH */
10115 if (dossh) { /* SSH connection via pty */
10117 k = ckstrncpy(line, sshcmd ? sshcmd : defsshcmd, LINBUFSIZ);
10118 debug(F111,"setlin sshcmd 1",line,k);
10119 if ((x = cmtxt("Optional switches and hostname","",&s,xxstring))<0)
10122 printf("?SSH to where?\n");
10125 if (k < LINBUFSIZ) {
10128 debug(F111,"setlin sshcmd 2",line,k);
10129 } if (k < LINBUFSIZ) {
10130 ckstrncpy(&line[k],s,LINBUFSIZ-k);
10131 debug(F111,"setlin sshcmd 3",line,k);
10133 printf("?Too long\n");
10136 x = cx_net( NET_PTY, /* network type */
10137 0, /* protocol (not used) */
10139 NULL, /* service (not used) */
10140 NULL, /* username (not used) */
10141 NULL, /* password (not used) */
10142 NULL, /* command (not used) */
10143 -1,-1,-1, /* params 1-3 (not used) */
10144 1, /* connect immediately */
10146 zz, /* close current? */
10148 debug(F111,"setlin cx_net",line,x);
10151 #endif /* SSHCMD */
10154 Here we parse optional switches and then the hostname or whatever,
10155 which depends on the network type. The tricky part is, the network type
10156 can be set by a switch.
10159 makestr(&g_pswd,pwbuf); /* Save global pwbuf */
10160 g_pflg = pwflg; /* and flag */
10167 if (mynet != NET_FILE) {
10168 #endif /* NETFILE */
10169 ss = (mynet == NET_CMD || mynet == NET_PTY) ?
10170 "Command, or switch" :
10171 (mynet == NET_TCPA || mynet == NET_TCPB
10172 || mynet == NET_SSH) ?
10173 "Hostname, ip-address, or switch" :
10176 if (mynet == NET_TCPB &&
10177 (ttnproto == NP_TELNET || ttnproto == NP_KERMIT)) {
10180 cmfdbi(&sw,_CMKEY,ss,"","",nshteltab,4,xxstring,
10185 else if (mynet == NET_TCPB && ttnproto == NP_RLOGIN) {
10188 cmfdbi(&sw,_CMKEY,ss,"","",nshrlgtab,4,xxstring,
10192 #endif /* RLOGCODE */
10195 cmfdbi(&sw,_CMKEY,ss,"","",nshtab,4,xxstring,shtab,&nx);
10199 #endif /* NETFILE */
10200 if (mynet == NET_TCPB || mynet == NET_SLAT ||
10201 mynet == NET_SSH || mynet == NET_DEC) {
10202 cmfdbi(&nx,_CMFLD,"Host","","",0,0,xxstring,NULL,NULL);
10204 } else if (mynet == NET_FILE) {
10205 cmfdbi(&nx,_CMIFI,"Filename","","",0,0,xxstring,NULL,NULL);
10206 #endif /* NETFILE */
10208 } else if (mynet == NET_CMD || mynet == NET_PTY) {
10209 cmfdbi(&nx,_CMTXT,"Command","","",0,0,xxstring,NULL,NULL);
10210 #endif /* PTYORPIPE */
10212 cmfdbi(&nx,_CMTXT,"Host","","",0,0,xxstring,NULL,NULL);
10215 x = cmfdb(haveswitch ? &sw : &nx);
10216 debug(F101,"setlin cmfdb","",x);
10221 if ((x = cmcfm()) < 0) {
10228 if (cmresult.fcode != _CMKEY) { /* Not a switch */
10229 ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Save the data */
10230 s = line; /* that was parsed... */
10231 if (cmresult.fcode == _CMIFI) {
10232 wild = cmresult.nresult;
10233 } else if (cmresult.fcode == _CMTXT) {
10236 break; /* and break out of this loop */
10238 c = cmgbrk(); /* Have switch - get break character */
10239 getval = (c == ':' || c == '='); /* Must parse an agument? */
10240 if (getval && !(cmresult.kflags & CM_ARG)) {
10241 printf("?This switch does not take arguments\n");
10244 if (!getval && (cmgkwflgs() & CM_ARG)) {
10245 printf("?This switch requires an argument\n");
10248 switch (cmresult.nresult) { /* It's a switch.. */
10249 case SL_CNX: /* /CONNECT */
10253 case SL_SRV: /* /SERVER */
10258 case SL_CMD: /* /COMMAND */
10262 #endif /* NETCMD */
10264 case SL_PTY: /* /PTY */
10268 #endif /* NETPTY */
10269 case SL_NET: /* /NETWORK-TYPE */
10270 if ((x = cmkey(netcmd,nnets,"","",xxstring)) < 0)
10276 case SL_PSW: /* /PASSWORD: */
10280 if ((x = cmfld("Password","",&s,xxstring)) < 0) {
10282 makestr(&tmpstring,"");
10288 if ((x = (int)strlen(s)) > PWBUFL) {
10289 makestr(&slmsg,"Internal error");
10290 printf("?Sorry, too long - max = %d\n",PWBUFL);
10293 makestr(&tmpstring,s);
10296 #endif /* CK_SECURITY */
10298 case SL_UID: /* /USERID: */
10301 if ((x = cmfld("Userid","",&s,xxstring)) < 0) {
10303 makestr(&tmpusrid,"");
10309 if ((x = (int)strlen(s)) > 63) {
10310 makestr(&slmsg,"Internal error");
10311 printf("?Sorry, too long - max = %d\n",63);
10314 makestr(&tmpusrid,s);
10319 #ifdef CK_AUTHENTICATION
10322 a_type = AUTHTYPE_SRP;
10324 #endif /* CK_SRP */
10327 a_type = AUTHTYPE_SSL;
10329 #endif /* CK_SSL */
10332 a_type = AUTHTYPE_NTLM;
10337 a_type = AUTHTYPE_KERBEROS_V4;
10338 if (ttnproto == NP_RLOGIN)
10340 #ifdef CK_ENCRYPTION
10341 encrypt ? NP_EK4LOGIN :
10342 #endif /* CK_ENCRYPTION */
10344 else if (ttnproto == NP_K5LOGIN)
10345 ttnproto = NP_K4LOGIN;
10346 #ifdef CK_ENCRYPTION
10347 else if (ttnproto == NP_EK5LOGIN)
10348 ttnproto = NP_EK4LOGIN;
10349 #endif /* CK_ENCRYPTION */
10352 a_type = AUTHTYPE_KERBEROS_V5;
10353 if (ttnproto == NP_RLOGIN)
10355 #ifdef CK_ENCRYPTION
10356 encrypt ? NP_EK5LOGIN :
10357 #endif /* CK_ENCRYPTION */
10359 else if (ttnproto == NP_K4LOGIN)
10360 ttnproto = NP_K5LOGIN;
10361 #ifdef CK_ENCRYPTION
10362 else if (ttnproto == NP_EK4LOGIN)
10363 ttnproto = NP_EK5LOGIN;
10364 #endif /* CK_ENCRYPTION */
10366 #endif /* CK_KERBEROS */
10368 extern struct keytab autyptab[];
10370 if ((x = cmkey(autyptab,nautyp,"type of authentication",
10371 "automatic",xxstring)) < 0)
10376 #endif /* CK_AUTHENTICATION */
10377 #ifdef CK_ENCRYPTION
10379 switch (ttnproto) {
10381 ttnproto = NP_EK4LOGIN;
10385 ttnproto = NP_EK5LOGIN;
10390 static struct keytab * tnetbl = NULL;
10391 static int ntnetbl = 0;
10392 x = ck_get_crypt_table(&tnetbl,&ntnetbl);
10393 debug(F101,"ck_get_crypt_table x","",x);
10394 debug(F101,"ck_get_crypt_table n","",ntnetbl);
10395 if (x < 1 || !tnetbl || ntnetbl < 1) /* Didn't get it */
10398 makestr(&slmsg,"Internal error");
10399 printf("?Oops, types not loaded\n");
10402 if ((x = cmkey(tnetbl,ntnetbl,"type of encryption",
10403 "automatic",xxstring)) < 0)
10410 #endif /* CK_ENCRYPTION */
10421 if (mynet == NET_FILE) { /* Parsed by cmifi() */
10422 if ((x = cmcfm()) < 0) /* Needs confirmation */
10424 x = cx_net(mynet, /* nettype */
10425 0, /* protocol (not used) */
10428 NULL, /* alternate username */
10429 NULL, /* password */
10430 NULL, /* command to execute */
10434 cx, /* enter CONNECT mode */
10435 sx, /* enter SERVER mode */
10436 zz, /* close connection if open */
10440 #endif /* NETFILE */
10443 if (mynet == NET_CMD || mynet == NET_PTY) {
10446 if ((x = cmtxt("Rest of command","",&s,xxstring)) < 0)
10449 strncat(line," ",LINBUFSIZ);
10450 strncat(line,s,LINBUFSIZ);
10454 /* s == line - so we must protect the line buffer */
10457 ckstrncpy(line,p,LINBUFSIZ);
10460 x = cx_net( mynet, /* nettype */
10461 0, /* protocol (not used) */
10464 NULL, /* alternate username */
10465 NULL, /* password */
10466 NULL, /* command to execute */
10470 cx, /* enter CONNECT mode */
10471 sx, /* enter SERVER mode */
10472 zz, /* close connection if open */
10476 #endif /* NETCMD */
10478 #ifdef NPIPE /* Named pipe */
10479 if (mynet == NET_PIPE) { /* Needs backslash twiddling */
10481 if (strcmp(line,"*")) { /* If remote, begin with */
10484 ckstrncpy(line,"\\\\",LINBUFSIZ); /* server name */
10485 ckstrncat(line,p,LINBUFSIZ);
10490 ckstrncat(line,"\\pipe\\", LINBUFSIZ); /* Make pipe name */
10491 ckstrncat(line,pipename, LINBUFSIZ); /* Add name of pipe */
10493 x = cx_net(mynet, /* nettype */
10494 0, /* protocol (not used) */
10497 NULL, /* alternate username */
10498 NULL, /* password */
10499 NULL, /* command to execute */
10503 cx, /* enter CONNECT mode */
10504 sx, /* enter SERVER mode */
10505 zz, /* close connection if open */
10513 if (mynet == NET_SLAT) { /* Needs password, etc. */
10514 slat_pwd[0] = NUL; /* Erase any previous password */
10516 if (*line) { /* If they gave a host name... */
10518 "password,\n or carriage return if no password required",
10524 ckstrncpy(slat_pwd,s,18); /* Set the password, if any */
10526 if ((x = cmcfm()) < 0) return(x); /* Confirm the command */
10528 x = cx_net(mynet, /* nettype */
10529 0, /* protocol (not used) */
10532 NULL, /* alternate username */
10533 NULL, /* password */
10534 NULL, /* command to execute */
10538 cx, /* enter CONNECT mode */
10539 sx, /* enter SERVER mode */
10540 zz, /* close connection if open */
10544 #endif /* SUPERLAT */
10547 if (mynet == NET_DEC) {
10548 if (!line[0]) { /* If they gave a host name... */
10549 printf("?hostname required\n");
10552 if ((x = cmcfm()) < 0) return(x); /* Confirm the command */
10554 x = cx_net(mynet, /* nettype */
10555 0, /* protocol (not used) */
10558 NULL, /* alternate username */
10559 NULL, /* password */
10560 NULL, /* command to execute */
10564 cx, /* enter CONNECT mode */
10565 sx, /* enter SERVER mode */
10566 zz, /* close connection if open */
10570 #endif /* DECNET */
10573 if (mynet == NET_SSH) { /* SSH connection */
10574 int k, havehost = 0, trips = 0;
10575 int tmpver = -1, tmpxfw = -1, tmpssh_cas;
10577 extern int sl_ssh_xfw, sl_ssh_xfw_saved;
10578 extern int sl_ssh_ver, sl_ssh_ver_saved;
10579 #endif /* SSHTEST */
10580 extern struct keytab sshopnsw[];
10581 extern int nsshopnsw;
10582 extern char *ssh_tmpcmd, *ssh_tmpport;
10583 struct FDB sw, kw, fl;
10585 debug(F110,"setlin SSH service 0",srvbuf,0);
10586 debug(F110,"setlin SSH host s 2",s,0);
10587 if (*s) { /* If they gave a host name... */
10588 debug(F110,"setlin SSH host s 1",s,0);
10590 makestr(&slmsg,"Incoming connections not supported");
10592 "?Sorry, incoming connections not supported for SSH.\n"
10596 ckstrncpy(line,s,LINBUFSIZ);
10598 printf("?hostname required\n");
10602 /* Parse [ port ] [ switches ] */
10603 cmfdbi(&kw, /* Switches */
10605 "Port number or service name,\nor switch",
10614 cmfdbi(&fl, /* Port number or service name */
10625 trips = 0; /* Explained below */
10626 while (1) { /* Parse port and switches */
10627 y = cmfdb(&kw); /* Get a field */
10628 if (y == -3) /* User typed CR so quit from loop */
10630 if (y < 0) /* Other parse error, pass it back */
10632 switch (cmresult.fcode) { /* Field or Keyword? */
10633 case _CMFLD: /* Field */
10634 ckstrncpy(srvbuf,cmresult.sresult,SRVBUFSIZ);
10636 case _CMKEY: /* Keyword */
10637 switch (cmresult.nresult) { /* Which one? */
10640 printf("?This switch requires an argument\n");
10644 if ((y = cmfld("Password","",&s,xxstring)) < 0) {
10646 makestr(&tmpstring,"");
10652 if ((y = (int)strlen(s)) > PWBUFL) {
10653 makestr(&slmsg,"Internal error");
10654 printf("?Sorry, too long - max = %d\n",PWBUFL);
10657 makestr(&tmpstring,s);
10660 case SSHSW_USR: /* /USER: */
10662 printf("?This switch requires an argument\n");
10665 if ((y = cmfld("Username","",&s,xxstring)) < 0)
10668 makestr(&tmpusrid,s);
10671 if ((y = cmnum("Number","",10,&z,xxstring)) < 0)
10673 if (z < 1 || z > 2) {
10674 printf("?Out of range: %d\n",z);
10681 if ((y = cmfld("Text","",&s,xxstring)) < 0)
10683 makestr(&ssh_tmpcmd,s);
10684 tmpssh_cas = (cmresult.nresult == SSHSW_SUB);
10687 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0)
10695 if (trips++ == 0) { /* After first time through */
10696 cmfdbi(&kw, /* only parse switches, not port. */
10709 if ((y = cmcfm()) < 0) /* Get confirmation */
10712 debug(F110,"setlin pre-cx_net line",line,0);
10713 debug(F110,"setlin pre-cx_net srvbuf",srvbuf,0);
10714 x = cx_net( mynet, /* nettype */
10715 0, /* protocol (not used) */
10718 tmpusrid, /* alternate username */
10719 tmpstring, /* password */
10720 ssh_tmpcmd, /* command to execute */
10721 tmpver, /* param1 - ssh version */
10722 tmpssh_cas, /* param2 - ssh cas */
10723 tmpxfw, /* param3 - ssh x11fwd */
10724 cx, /* enter CONNECT mode */
10725 sx, /* enter SERVER mode */
10726 zz, /* close connection if open */
10730 makestr(&tmpusrid,NULL);
10732 makestr(&ssh_tmpcmd,NULL);
10734 #endif /* SSHBUILTIN */
10737 if (mynet == NET_TCPB) { /* TCP/IP connection */
10738 debug(F110,"setlin service 0",srvbuf,0);
10739 debug(F110,"setlin host s 2",s,0);
10740 if (*s) { /* If they gave a host name... */
10741 debug(F110,"setlin host s 1",s,0);
10744 makestr(&slmsg,"Incoming connections not supported");
10746 "?Sorry, incoming connections not supported in this version of Kermit.\n"
10750 #endif /* NOLISTEN */
10752 /* Allow a username if rlogin is requested */
10753 if (mynet == NET_TCPB &&
10754 (ttnproto == NP_RLOGIN || ttnproto == NP_K5LOGIN ||
10755 ttnproto == NP_EK5LOGIN || ttnproto == NP_K4LOGIN ||
10756 ttnproto == NP_EK4LOGIN
10760 /* Check for "host:service" */
10761 for ( ; (*s != '\0') && (*s != ':'); s++) ;
10762 if (*s) { /* Service, save it */
10764 ckstrncpy(srvbuf,++s,SRVBUFSIZ);
10765 } else { /* No :service, then use default. */
10767 switch (ttnproto) {
10769 ckstrncpy(srvbuf,"513",SRVBUFSIZ); /* "login" */
10773 ckstrncpy(srvbuf,"543",SRVBUFSIZ); /* "klogin" */
10777 ckstrncpy(srvbuf,"2105",SRVBUFSIZ); /* "eklogin" */
10781 switch (ttnproto) {
10783 ckstrncpy(srvbuf,"login",SRVBUFSIZ);
10787 ckstrncpy(srvbuf,"klogin",SRVBUFSIZ);
10791 ckstrncpy(srvbuf,"eklogin",SRVBUFSIZ);
10797 y = cmfld("Userid on remote system",
10798 uidbuf,&s,xxstring);
10799 if (y < 0 && y != -3)
10801 if ((int)strlen(s) > 63) {
10802 makestr(&slmsg,"Internal error");
10803 printf("Sorry, too long\n");
10806 makestr(&tmpusrid,s);
10808 } else { /* TELNET or SET HOST */
10809 #endif /* RLOGCODE */
10810 /* Check for "host:service" */
10811 for ( ; (*s != '\0') && (*s != ':'); s++) ;
10812 if (*s) { /* Service, save it */
10814 ckstrncpy(srvbuf,++s,SRVBUFSIZ);
10815 } else if (!confirmed) {
10816 /* No :service, let them type one. */
10817 if (*line != '*') { /* Not incoming */
10818 if (mynet == NET_TCPB && ttnproto == NP_KERMIT) {
10820 "TCP service name or number",
10821 "kermit",&s,xxstring)
10825 } else if (mynet == NET_TCPB &&
10826 ttnproto == NP_RLOGIN) {
10828 "TCP service name or number,\n or carriage return for rlogin (513)",
10829 "login",&s,xxstring)
10832 #ifdef CK_AUTHENTICATION
10834 } else if (mynet == NET_TCPB &&
10835 (ttnproto == NP_K4LOGIN ||
10836 ttnproto == NP_K5LOGIN)) {
10838 "TCP service name or number,\n or carriage return for klogin (543)",
10839 "klogin",&s,xxstring)
10842 } else if (mynet == NET_TCPB &&
10843 (ttnproto == NP_EK4LOGIN ||
10844 ttnproto == NP_EK5LOGIN)) {
10846 "TCP service name or number,\n or carriage return for eklogin (2105)",
10847 "eklogin",&s,xxstring)
10850 #endif /* CK_KERBEROS */
10851 #endif /* CK_AUTHENTICATION */
10852 #endif /* RLOGCODE */
10854 /* Do not set a default value in this call */
10855 /* If you do then it will prevent entries */
10856 /* in the network directory from accessing */
10857 /* alternate ports. */
10860 "TCP service name or number",
10865 } else { /* Incoming connection */
10866 if ((x = cmfld("TCP service name or number",
10871 if (*s) /* If they gave a service, */
10872 ckstrncpy(srvbuf,s,SRVBUFSIZ); /* copy it */
10873 debug(F110,"setlin service 0.5",srvbuf,0);
10877 #endif /* RLOGCODE */
10880 switch (ttnproto) {
10882 defproto = "/rlogin";
10885 defproto = "/k4login";
10888 defproto = "/k5login";
10891 defproto = "/ek4login";
10894 defproto = "/ek5login";
10898 defproto = "/telnet";
10901 defproto = "/default";
10903 if ((x = cmkey(tcprawtab,ntcpraw,"Switch",defproto,
10907 else if ((x = cmcfm()) < 0)
10911 if ((x = cmcfm()) < 0)
10916 debug(F110,"setlin pre-cx_net line",line,0);
10917 debug(F110,"setlin pre-cx_net srvbuf",srvbuf,0);
10918 x = cx_net( mynet, /* nettype */
10919 rawflg /* protocol */,
10922 tmpusrid, /* alternate username */
10923 tmpstring, /* password */
10924 NULL, /* command to execute */
10925 a_type, /* param1 - telnet authtype */
10926 e_type, /* param2 - telnet enctype */
10927 wait, /* param3 - telnet wait */
10928 cx, /* enter CONNECT mode */
10929 sx, /* enter SERVER mode */
10930 zz, /* close connection if open */
10934 #endif /* TCPSOCKET */
10938 makestr(&tmpstring,NULL);
10939 #endif /* CK_SECURITY */
10941 makestr(&tmpusrid,NULL);
10942 debug(F111,"setlin cx_net",line,x);
10944 #endif /* NETCONN */
10947 /* Serial tty device, possibly modem, connection... */
10952 COM1..COM8 = Regular COM port
10953 1..8 = Synonym for COM1..COM8, is translated to COM1..COM8
10954 _n = (n is a number) = open file handle
10955 string = any text string = name of some other kind of device,
10956 taken literally, as given.
10958 s = "Communication device name";
10962 cktapiBuildLineTable(&tapilinetab, &_tapilinetab, &ntapiline);
10963 if (!(tapilinetab && _tapilinetab && ntapiline > 0) &&
10964 xx == XYTAPI_LIN ) {
10965 makestr(&slmsg,"TAPI device not configured");
10966 printf("\nNo TAPI Line Devices are configured for this system\n");
10969 if (xx == XYTAPI_LIN) { /* Default (first) TAPI line */
10970 s = "tapi"; /* (whatever it is) */
10971 } else { /* Query the user */
10972 #endif /* CK_TAPI */
10974 /* Now parse optional switches and then device name */
10977 cmfdbi(&sw,_CMKEY,"Device name, or switch",
10978 "","",npsltab,4,xxstring,psltab,&fl);
10979 cmfdbi(&fl,_CMFLD,"",dftty,"",0,0,xxstring,NULL,NULL);
10982 debug(F101,"setlin cmfdb","",x);
10987 if ((x = cmcfm()) < 0) {
10994 if (cmresult.fcode == _CMFLD) {
10995 s = cmresult.sresult;
10997 } else if (cmresult.fcode == _CMKEY) {
10998 switch (cmresult.nresult) {
10999 case SL_CNX: /* /CONNECT */
11003 case SL_SRV: /* /SERVER */
11007 case SL_SHR: /* /SHARE */
11010 case SL_NSH: /* /NOSHARE */
11018 #endif /* CK_TAPI */
11020 debug(F110,"OS2 SET PORT s",s,0);
11021 y = lookup(os2devtab,s,nos2dev,&x); /* Look up in keyword table */
11022 debug(F101,"OS2 SET PORT x","",x);
11023 debug(F101,"OS2 SET PORT y","",y);
11024 if ((y > -1) && (x >= 0 && x < 8)) { /* User typed a digit 1..8 */
11025 s = os2devtab[x+8].kwd; /* Substitite its real name */
11029 xxslip = xxppp = 0;
11031 debug(F110,"OS2 SET PORT subst s",s,"");
11033 } else if ((y >-1) && (x >= 16 && x < 24)) { /* SLIP access */
11034 s = os2devtab[x-8].kwd; /* Substitite its real name */
11035 debug(F110,"OS2 SET PORT SLIP subst s",s,"");
11038 } else if ((y >-1) && (x >= 24 && x < 32)) { /* PPP access */
11039 s = os2devtab[x-16].kwd; /* Substitite its real name */
11040 debug(F110,"OS2 SET PORT PPP subst s",s,"");
11043 if ((y = cmkey(os2ppptab,
11045 "PPP driver interface",
11050 debug(F101,"OS2 SET PORT PPP INTERFACE y","",y);
11051 xxppp = (y % 10) + 1;
11053 } else if (*s == '_') { /* User used "_" prefix */
11054 s++; /* Remove it */
11055 /* Rest must be numeric */
11056 debug(F110,"OS2 SET PORT HANDLE _subst s",s,0);
11058 makestr(&slmsg,"Invalid file handle");
11059 printf("?Invalid format for file handle\n");
11065 xxslip = xxppp = 0;
11067 } else { /* A normal COMx port or a string */
11068 s = brstrip(s); /* Strip braces if any */
11071 /* Windows TAPI support - Look up in keyword table */
11072 if (tapilinetab && _tapilinetab && ntapiline > 0) {
11073 if (!ckstrcmp(s,"tapi",4,0)) {
11075 /* Find out what the lowest numbered TAPI device is */
11076 /* and use it as the default. */
11077 int j = 9999, k = -1;
11078 for (i = 0; i < ntapiline; i++) {
11079 if (tapilinetab[i].kwval < j) {
11080 j = tapilinetab[i].kwval;
11085 s = _tapilinetab[k].kwd;
11089 if ((y = cmkey(_tapilinetab,ntapiline,
11090 "TAPI device name",s,xxstring)) < 0)
11095 /* Get the non Underscored string */
11096 for (i = 0; i < ntapiline; i++ ) {
11097 if (tapilinetab[i].kwval == y) {
11098 s = tapilinetab[i].kwd;
11105 #endif /* CK_TAPI */
11107 /* not OS/2 SLIP or PPP */
11108 xxslip = xxppp = 0;
11111 ckstrncpy(tmpbuf,s,TMPBUFSIZ); /* Copy to a safe place */
11113 if ((x = cmcfm()) < 0)
11118 cmfdbi(&sw,_CMKEY,"Device name, or switch",
11119 "","",npsltab,4,xxstring,psltab,&tx);
11120 cmfdbi(&tx,_CMTXT,"",dftty,"",0,0,xxstring,NULL,NULL);
11121 while (!confirmed) {
11123 debug(F101,"setlin cmfdb","",x);
11128 if ((x = cmcfm()) < 0) {
11135 switch (cmresult.fcode) {
11137 ckstrncpy(tmpbuf,cmresult.sresult,TMPBUFSIZ);
11139 debug(F110,"setlin CMTXT",tmpbuf,0);
11142 case _CMKEY: /* Switch */
11143 debug(F101,"setlin CMKEY",tmpbuf,cmresult.nresult);
11144 switch (cmresult.nresult) {
11145 case SL_CNX: /* /CONNECT */
11149 case SL_SRV: /* /SERVER */
11154 case SL_SHR: /* /SHARE */
11157 case SL_NSH: /* /NOSHARE */
11164 debug(F101,"setlin bad cmfdb result","",cmresult.fcode);
11165 makestr(&slmsg,"Internal error");
11166 printf("?Internal parsing error\n");
11172 if ((x = cmcfm()) < 0)
11175 debug(F110,"setlin pre-cx_serial s",s,0);
11176 debug(F110,"setlin pre-cx_serial line",line,0);
11177 x = cx_serial(s,cx,sx,shr,zz,0,
11180 (xxtapi ? CX_TAPI : 0)
11182 (xxslip ? CX_SLIP : 0) | (xxppp ? CX_PPP : 0)
11188 debug(F111,"setlin cx_serial",line,x);
11191 #endif /* NOLOCAL */
11195 C-Library based file-i/o package for scripts. This should be portable to
11196 all C-Kermit versions since it uses the same APIs we have always used for
11197 processing command files. The entire channel i/o package is contained
11198 herein, apart from some keyword table entries in the main keyword table
11199 and the help text in the HELP command module.
11201 On platforms like VMS and VOS, this package handles only UNIX-style
11202 stream files. If desired, it can be replaced for those platforms by
11203 <#>ifdef'ing out this code and adding the equivalent replacement routines
11204 to the ck?fio.c module, e.g. for RMS-based file i/o in ckvfio.c.
11207 /* Define NOSTAT if the <#>include causes trouble. */
11211 #ifdef VAXC /* As it does in VAX C */
11215 #endif /* NOSTAT */
11218 #include <sys/stat.h>
11219 #endif /* NOSTAT */
11222 static int z_lt = 1; /* Length of line terminator */
11224 static int z_lt = 2;
11225 #endif /* NLCHAR */
11227 struct ckz_file { /* C-Kermit file struct */
11228 FILE * z_fp; /* Includes the C-Lib file struct */
11229 unsigned int z_flags; /* Plus C-Kermit mode flags, */
11230 long z_nline; /* current line number if known, */
11231 char z_name[CKMAXPATH+2]; /* and the file's name. */
11233 static struct ckz_file * z_file = NULL; /* Array of C-Kermit file structs */
11234 static int z_inited = 0; /* Flag for array initialized */
11235 int z_maxchan = Z_MAXCHAN; /* Max number of C-Kermit channels */
11236 int z_openmax = CKMAXOPEN; /* Max number of open files overall */
11237 int z_nopen = 0; /* How many channels presently open */
11238 int z_error = 0; /* Most recent error */
11239 int z_filcount = -1; /* Most recent FILE COUNT result */
11241 #define RD_LINE 0 /* FILE READ options */
11244 #define RD_TRIM 8 /* Like Snobol &TRIM = 1 */
11245 #define RD_UNTA 9 /* Untabify */
11247 #define WR_LINE RD_LINE /* FILE WRITE options */
11248 #define WR_CHAR RD_CHAR
11249 #define WR_SIZE RD_SIZE
11255 extern int ckmaxfiles; /* Filled in by sysinit(). */
11258 /* See ckcker.h for error numbers */
11259 /* See ckcdeb.h for Z_MAXCHAN and CKMAXOPEN definitions */
11260 /* NOTE: For VMS we might be able to fill in ckmaxfiles */
11261 /* from FILLM and CHANNELCNT -- find out about these... */
11263 static char * fopnargs[] = { /* Mode combinations for fopen() */
11265 /* All combinations of rwa */
11266 "", "r", "w", "rw", "a", "ra", "wa", "rwa", /* Text mode */
11267 "b", "rb", "wb", "rwb", "ab", "rab", "wab", "rwab" /* Binary mode */
11269 /* Combinations and syntax permitted by C libraries... */
11270 "", "r", "w", "r+", "a", "", "a", "", /* Text mode */
11272 "", "rb", "wb", "r+b", "ab", "", "ab", "" /* Binary modes for K95 */
11275 "", "rb", "wb", "r+b", "ab", "", "ab", "" /* Binary modes for VMS */
11277 "", "r", "w", "r+", "a", "", "a", "" /* Binary modes for UNIX */
11280 #endif /* COMMENT */
11282 static int nfopnargs = sizeof(fopnargs) / sizeof(char *);
11284 char * /* Error messages */
11285 ckferror(n) int n; {
11287 case FX_NER: return("No error");
11288 case FX_SYS: return(ck_errstr());
11289 case FX_EOF: return("End of file");
11290 case FX_NOP: return("File not open");
11291 case FX_CHN: return("Channel out of range");
11292 case FX_RNG: return("Parameter out of range");
11293 case FX_NMF: return("Too many files open");
11294 case FX_FOP: return("Operation conflicts with OPEN mode");
11295 case FX_NYI: return("OPEN mode not supported");
11296 case FX_BOM: return("Illegal combination of OPEN modes");
11297 case FX_ACC: return("Access denied");
11298 case FX_FNF: return("File not found");
11299 case FX_OFL: return("Buffer overflow");
11300 case FX_LNU: return("Current line number unknown");
11301 case FX_ROO: return("Off limits");
11302 case FX_UNK: return("Operation fails - reason unknown");
11303 default: return("Error number out of range");
11308 Z _ O P E N -- Open a file for the requested type of access.
11311 name: Name of file to be opened.
11312 flags: Any combination of FM_xxx values except FM_EOF (ckcker.h).
11314 >= 0 on success: The assigned channel number
11315 < 0 on failure: A negative FX_xxx error code (ckcker.h).
11318 z_open(name, flags) char * name; int flags; {
11322 debug(F111,"z_open",name,flags);
11323 if (!name) name = ""; /* Check name argument */
11325 return(z_error = FX_BFN);
11326 if (flags & FM_CMD) /* Opening pipes not implemented yet */
11327 return(z_error = FX_NYI); /* (and not portable either) */
11328 debug(F101,"z_open nfopnargs","",nfopnargs);
11329 if (flags < 0 || flags >= nfopnargs) /* Range check flags */
11330 return(z_error = FX_RNG);
11331 mode = fopnargs[flags]; /* Get fopen() arg */
11332 debug(F111,"z_open fopen args",mode,flags);
11333 if (!mode[0]) /* Check for illegal combinations */
11334 return(z_error = FX_BOM);
11335 if (!z_inited) { /* If file structs not inited */
11336 debug(F101,"z_open z_maxchan 1","",z_maxchan);
11338 debug(F101,"z_open ckmaxfiles","",ckmaxfiles);
11339 if (ckmaxfiles > 0) { /* Set in ck?tio.c: sysinit() */
11341 x = ckmaxfiles - ZNFILS - 5;
11342 if (x > z_maxchan) /* sysconf() value greater than */
11343 z_maxchan = x; /* value from header files. */
11344 debug(F101,"z_open z_maxchan 2","",z_maxchan);
11347 if (z_maxchan < Z_MINCHAN) /* Allocate at least this many. */
11348 z_maxchan = Z_MINCHAN;
11349 debug(F101,"z_open z_maxchan 3","",z_maxchan);
11350 /* Note: This could be a pretty big chunk of memory */
11351 /* if z_maxchan is a big number. If this becomes a problem */
11352 /* we'll need to malloc and free each element at open/close time */
11353 if (!(z_file = (struct ckz_file *)
11354 malloc(sizeof(struct ckz_file) * (z_maxchan + 1))))
11355 return(z_error = FX_NMF);
11356 for (i = 0; i < z_maxchan; i++) {
11357 z_file[i].z_fp = NULL;
11358 z_file[i].z_flags = 0;
11359 z_file[i].z_nline = 0;
11360 *(z_file[i].z_name) = '\0';
11362 z_inited = 1; /* Remember we did */
11364 for (n = -1, i = 0; i < z_maxchan; i++) {
11365 if (!z_file[i].z_fp) {
11370 if (n < 0 || n >= z_maxchan) /* Any free channels? */
11371 return(z_error = FX_NMF); /* No, fail. */
11374 z_file[n].z_flags = 0; /* In case of failure... */
11376 t = fopen(name, mode); /* Try to open the file. */
11377 if (!t) { /* Failed... */
11378 debug(F111,"z_open error",name,errno);
11380 if (errno == EMFILE)
11381 return(z_error = FX_NMF);
11382 #endif /* EMFILE */
11383 return(z_error = (errno ? FX_SYS : FX_UNK)); /* Return error code */
11386 #ifdef O_SEQUENTIAL
11387 if (t) /* Caching hint for NT */
11388 _setmode(_fileno(t),O_SEQUENTIAL);
11389 #endif /* O_SEQUENTIAL */
11391 z_nopen++; /* Open, count it. */
11392 z_file[n].z_fp = t; /* Stash the file pointer */
11393 z_file[n].z_flags = flags; /* and the flags */
11395 zfnqfp(name,CKMAXPATH,z_file[n].z_name); /* and the file's full name */
11396 return(n); /* Return the channel number */
11400 z_close(channel) int channel; { /* Close file on given channel */
11403 if (!z_inited) /* Called before any files are open? */
11404 return(z_error = FX_NOP);
11405 if (channel >= z_maxchan) /* Channel out of range? */
11406 return(z_error = FX_CHN);
11407 if (!(t = z_file[channel].z_fp)) /* Channel wasn't open? */
11408 return(z_error = FX_NOP);
11409 errno = 0; /* Set errno 0 to get a good reading */
11410 x = fclose(t); /* Try to close */
11411 if (x == EOF) /* On failure */
11412 return(z_error = FX_SYS); /* indicate system error. */
11413 z_nopen--; /* Closed OK, decrement open count */
11414 z_file[channel].z_fp = NULL; /* Set file pointer to NULL */
11415 z_file[channel].z_nline = 0; /* Current line number is 0 */
11416 z_file[channel].z_flags = 0; /* Set flags to 0 */
11417 *(z_file[channel].z_name) = '\0'; /* Clear name */
11418 return(z_error = 0);
11422 Z _ O U T -- Output string to channel.
11425 channel: Channel number to write to.
11426 s: String to write.
11427 length > -1: How many characters of s to write.
11428 length < 0: Write entire NUL-terminated string.
11429 flags == 0: Supply line termination.
11430 flags > 0: Don't supply line termination.
11431 flags < 0: Write 'length' NUL characters.
11433 If flags > -1 and s is empty or NULL and length == 1, write 1 NUL.
11435 Number of characters written to channel on success, or
11436 negative FX_xxx error code on failure.
11439 z_out(channel,s,length,flags) int channel, flags, length; char * s; {
11444 if (!s) s = ""; /* Guard against null pointer */
11447 debug(F111,"z_out",s,channel);
11448 debug(F101,"z_out length","",length);
11449 debug(F101,"z_out flags","",flags);
11452 if (!z_inited) /* File i/o inited? */
11453 return(z_error = FX_NOP);
11454 if (channel >= z_maxchan) /* Channel in range? */
11455 return(z_error = FX_CHN);
11456 if (!(t = z_file[channel].z_fp)) /* File open? */
11457 return(z_error = FX_NOP);
11458 if (!((z_file[channel].z_flags) & (FM_WRI|FM_APP))) /* In write mode? */
11459 return(z_error = FX_FOP);
11460 n = length; /* Length of string to write */
11461 if (n < 0) { /* Negative means get it ourselves */
11462 if (flags < 0) /* Except when told to write NULs in */
11463 return(z_error = FX_RNG); /* which case args are inconsistent */
11464 n = strlen(s); /* Get length of string arg */
11466 errno = 0; /* Reset errno */
11467 debug(F101,"z_out n","",n);
11468 if (flags < 0) { /* Writing NULs... */
11470 for (i = 0; i < n; i++) {
11471 x = fwrite(&c,1,1,t);
11473 return(z_error = (errno ? FX_SYS : FX_UNK));
11475 z_file[channel].z_nline = -1; /* Current line no longer known */
11478 } else { /* Writing string arg */
11479 if (n == 1 && !s[0]) /* Writing one char but it's NUL */
11480 x = fwrite(&c,1,1,t);
11481 else /* Writing non-NUL char or string */
11482 x = fwrite(s,1,n,t);
11483 debug(F101,"z_out fwrite",ckitoa(x),errno);
11484 if (x < n) /* Failure to write requested amount */
11485 return(z_error = (errno ? FX_SYS : FX_UNK)); /* Return error */
11486 if (flags == 0) { /* If supplying line termination */
11487 if (fwrite("\n",1,1,t)) /* do that */
11488 x += z_lt; /* count the terminator */
11489 if (z_file[channel].z_nline > -1) /* count this line */
11490 z_file[channel].z_nline++;
11492 z_file[channel].z_nline = -1; /* Current line no longer known */
11499 #define Z_INBUFLEN 64
11502 Z _ I N -- Multichannel i/o file input function.
11505 channel number to read from.
11506 s = address of destination buffer.
11507 buflen = destination buffer length.
11508 length = Number of bytes to read, must be < buflen.
11509 flags: 0 = read a line; nonzero = read the given number of bytes.
11511 Number of bytes read into buffer or a negative error code.
11512 A terminating NUL is deposited after the last byte that was read.
11515 z_in(channel,s,buflen,length,flags)
11516 int channel, buflen, length, flags; char * s;
11522 if (!z_inited) /* Check everything... */
11523 return(z_error = FX_NOP);
11524 if (channel >= z_maxchan)
11525 return(z_error = FX_CHN);
11526 if (!(t = z_file[channel].z_fp))
11527 return(z_error = FX_NOP);
11528 if (!((z_file[channel].z_flags) & FM_REA))
11529 return(z_error = FX_FOP);
11530 if (!s) /* Check destination */
11531 return(z_error = FX_RNG);
11533 if (length == 0) /* Read 0 bytes - easy. */
11534 return(z_error = 0);
11535 debug(F101,"z_in channel","",channel);
11536 debug(F101,"z_in buflen","",buflen);
11537 debug(F101,"z_in length","",length);
11538 debug(F101,"z_in flags","",flags);
11539 if (length < 0 || buflen < 0) /* Check length args */
11540 return(z_error = FX_RNG);
11541 if (buflen <= length)
11542 return(z_error = FX_RNG);
11543 errno = 0; /* Reset errno */
11544 if (flags) { /* Read block or byte */
11545 i = fread(s,1,length,t);
11548 debug(F111,"z_in block",s,i);
11549 debug(F101,"z_in block errno","",errno);
11550 debug(F101,"z_in block ferror","",ferror(t));
11551 debug(F101,"z_in block feof","",feof(t));
11554 z_file[channel].z_nline = -1; /* Current line no longer known */
11555 } else { /* Read line */
11557 /* This method is used because it's simpler than the others */
11558 /* and also marginally faster. */
11559 debug(F101,"z_in getc loop","",ftell(t));
11560 for (i = 0; i < length; i++) {
11561 if ((x = getc(t)) == EOF) {
11562 debug(F101,"z_in getc error","",ftell(t));
11567 if (s[i] == '\n') {
11572 debug(F111,"z_in line byte loop",ckitoa(errno),i);
11573 debug(F111,"z_in line got",s,z_file[channel].z_nline);
11574 if (z_file[channel].z_nline > -1)
11575 z_file[channel].z_nline++;
11578 /* Straightforward but strlen() slows it down. */
11581 if (fgets(s,length,t)) {
11583 if (i > 0 && s[i-1] == '\n') i--;
11585 debug(F111,"z_in line fgets",ckitoa(errno),i);
11586 if (z_file[channel].z_nline > -1)
11587 z_file[channel].z_nline++;
11589 /* This is a do-it-yourself fgets() with its own readahead and */
11590 /* putback. It's a bit faster than real fgets() but not enough */
11591 /* to justify the added complexity or the risk of the ftell() and */
11592 /* fseek() calls failing. */
11595 for (i = 0; !flag && i <= (length - Z_INBUFLEN); i += Z_INBUFLEN) {
11596 k = ((length - i) < Z_INBUFLEN) ? length - i : Z_INBUFLEN;
11597 if ((x = fread(s+i,1,k,t)) < 1)
11600 for (j = 0; j < x; j++) {
11601 if (s[i+j] == '\n') {
11606 pos -= (x - j - 1);
11607 x = fseek(t, pos, 0);
11611 return(z_error = FX_SYS);
11615 if (z_file[channel].z_nline > -1)
11616 z_file[channel].z_nline++;
11617 debug(F111,"z_in line chunk loop",ckitoa(errno),i);
11618 #endif /* COMMENT2 */
11619 #endif /* COMMENT */
11621 debug(F111,"z_in i",ckitoa(errno),i);
11622 if (i < 0) i = 0; /* NUL-terminate result */
11628 if (i == 0 && feof(t)) /* EOF on reading? */
11629 return(z_error = FX_EOF); /* Return EOF code */
11630 return(errno ? (z_error = -1) : i); /* Return length or system error */
11634 z_flush(channel) int channel; { /* Flush output channel */
11637 if (!z_inited) /* Regular checks */
11638 return(z_error = FX_NOP);
11639 if (channel >= z_maxchan)
11640 return(z_error = FX_CHN);
11641 if (!(t = z_file[channel].z_fp))
11642 return(z_error = FX_NOP);
11643 if (!((z_file[channel].z_flags) & (FM_WRI|FM_APP))) /* Write access? */
11644 return(z_error = FX_FOP);
11645 errno = 0; /* Reset errno */
11646 x = fflush(t); /* Try to flush */
11647 return(x ? (z_error = FX_SYS) : 0); /* Return system error or 0 if OK */
11652 z_seek(int channel, long pos) /* Move file pointer to byte */
11654 z_seek(channel,pos) int channel; long pos; /* (seek to given position) */
11655 #endif /* CK_ANSIC */
11659 if (!z_inited) /* Check... */
11660 return(z_error = FX_NOP);
11661 if (channel >= z_maxchan)
11662 return(z_error = FX_CHN);
11663 if (!(t = z_file[channel].z_fp))
11664 return(z_error = FX_NOP);
11667 pos = (pos == -2) ? -1L : 0L;
11670 rc = fseek(t,pos,x); /* Try to seek */
11671 debug(F111,"z_seek",ckitoa(errno),rc);
11672 if (rc < 0) /* OK? */
11673 return(z_error = FX_SYS); /* No. */
11674 z_file[channel].z_nline = ((pos || x) ? -1 : 0);
11675 return(z_error = 0);
11680 z_line(int channel, long pos) /* Move file pointer to line */
11682 z_line(channel,pos) int channel; long pos; /* (seek to given position) */
11683 #endif /* CK_ANSIC */
11686 long current = 0L, prev = -1L, old = -1L;
11689 if (!z_inited) /* Check... */
11690 return(z_error = FX_NOP);
11691 if (channel >= z_maxchan)
11692 return(z_error = FX_CHN);
11693 if (!(t = z_file[channel].z_fp))
11694 return(z_error = FX_NOP);
11695 debug(F101,"z_line pos","",pos);
11696 if (pos < 0L) { /* EOF wanted */
11698 n = z_file[channel].z_nline;
11699 debug(F101,"z_line n","",n);
11700 if (n < 0 || pos < 0) {
11704 while (1) { /* This could take a while... */
11705 if ((x = getc(t)) == EOF)
11715 debug(F101,"z_line old","",old);
11716 debug(F101,"z_line prev","",prev);
11718 if ((x = z_seek(channel,old)) < 0)
11719 return(z_error = x);
11723 z_file[channel].z_nline = n;
11724 return(z_error = 0);
11726 if (pos == 0L) { /* Rewind wanted */
11727 z_file[channel].z_nline = 0L;
11729 debug(F100,"z_line rewind","",0);
11732 tmpbuf[255] = NUL; /* Make sure buf is NUL terminated */
11733 current = z_file[channel].z_nline; /* Current line */
11735 If necessary the following could be optimized, e.g. for positioning
11736 to a previous line in a large file without starting over.
11738 if (current < 0 || pos < current) { /* Not known or behind us... */
11739 debug(F101,"z_line rewinding","",pos);
11740 if ((x = z_seek(channel, 0L)) < 0) /* Rewind */
11741 return(z_error = x);
11742 if (pos == 0) /* If 0th line wanted we're done */
11743 return(z_error = 0);
11746 while (current < pos) { /* Search for specified line */
11747 if (fgets(tmpbuf,255,t)) {
11748 len = strlen(tmpbuf);
11749 if (len > 0 && tmpbuf[len-1] == '\n') {
11751 debug(F111,"z_line read",ckitoa(len),current);
11752 } else if (len == 0) {
11753 return(z_error = FX_UNK);
11756 z_file[channel].z_nline = -1L;
11757 debug(F101,"z_line premature EOF","",current);
11758 return(z_error = FX_EOF);
11761 z_file[channel].z_nline = current;
11762 debug(F101,"z_line result","",current);
11768 z_getname(channel) int channel; { /* Return name of file on channel */
11774 if (channel >= z_maxchan) {
11778 if (!(t = z_file[channel].z_fp)) {
11782 return((char *)(z_file[channel].z_name));
11786 z_getmode(channel) int channel; { /* Return OPEN modes of channel */
11787 FILE * t; /* 0 if file not open */
11790 struct _stat statbuf;
11792 struct stat statbuf;
11794 #endif /* NOSTAT */
11798 if (channel >= z_maxchan)
11799 return(z_error = FX_CHN);
11800 if (!(t = z_file[channel].z_fp))
11802 x = z_file[channel].z_flags;
11803 if (feof(t)) { /* This might not work for */
11804 x |= FM_EOF; /* output files */
11806 /* But this does if we can use it. */
11807 } else if (stat(z_file[channel].z_name,&statbuf) > -1) {
11808 if (ftell(t) == statbuf.st_size)
11810 #endif /* NOSTAT */
11816 z_getpos(channel) int channel; { /* Get file pointer position */
11817 FILE * t; /* on this channel */
11820 return(z_error = FX_NOP);
11821 if (channel >= z_maxchan)
11822 return(z_error = FX_CHN);
11823 if (!(t = z_file[channel].z_fp))
11824 return(z_error = FX_NOP);
11826 return((x < 0L) ? (z_error = FX_SYS) : x);
11830 z_getline(channel) int channel; { /* Get current line number */
11831 FILE * t; /* in file on this channel */
11834 return(z_error = FX_NOP);
11835 if (channel >= z_maxchan)
11836 return(z_error = FX_CHN);
11837 if (!(t = z_file[channel].z_fp))
11838 return(z_error = FX_NOP);
11839 debug(F101,"z_getline","",z_file[channel].z_nline);
11840 rc = z_file[channel].z_nline;
11841 return((rc < 0) ? (z_error = FX_LNU) : rc);
11845 z_getfnum(channel) int channel; { /* Get file number / handle */
11846 FILE * t; /* for file on this channel */
11848 return(z_error = FX_NOP);
11849 if (channel >= z_maxchan)
11850 return(z_error = FX_CHN);
11851 if (!(t = z_file[channel].z_fp))
11852 return(z_error = FX_NOP);
11858 Line-oriented counts and seeks are as dumb as they can be at the moment.
11859 Later we can speed them up by building little indexes.
11862 z_count(channel, what) int channel, what; { /* Count bytes or lines in file */
11865 long pos, count = 0L;
11866 if (!z_inited) /* Check stuff... */
11867 return(z_error = FX_NOP);
11868 if (channel >= z_maxchan)
11869 return(z_error = FX_CHN);
11870 if (!(t = z_file[channel].z_fp))
11871 return(z_error = FX_NOP);
11872 pos = ftell(t); /* Save current file pointer */
11875 if (what == RD_CHAR) { /* Size in bytes requested */
11876 if (!fseek(t,0L,2)) { /* Seek to end */
11877 count = ftell(t); /* Get file pointer */
11878 fseek(t,pos,0); /* Restore file file pointer */
11880 } else /* Fallback in case seek fails */
11881 return(zgetfs(z_file[channel].z_name));
11883 rewind(t); /* Line count requested - rewind. */
11884 while (1) { /* Count lines. */
11885 if ((x = getc(t)) == EOF) /* Stupid byte loop */
11886 break; /* but it works as well as anything */
11887 if (x == '\n') /* else... */
11890 x = fseek(t,pos,0); /* Restore file pointer */
11894 /* User interface for generalized channel-oriented file i/o */
11896 struct keytab fctab[] = { /* FILE subcommands */
11897 { "close", FIL_CLS, 0 },
11898 { "count", FIL_COU, 0 },
11899 { "flush", FIL_FLU, 0 },
11900 { "list", FIL_LIS, 0 },
11901 { "open", FIL_OPN, 0 },
11902 { "read", FIL_REA, 0 },
11903 { "rewind", FIL_REW, 0 },
11904 { "seek", FIL_SEE, 0 },
11905 { "status", FIL_STA, 0 },
11906 { "write", FIL_WRI, 0 }
11908 int nfctab = (sizeof (fctab) / sizeof (struct keytab));
11910 static struct keytab fcswtab[] = { /* OPEN modes */
11911 { "/append", FM_APP, 0 },
11912 { "/binary", FM_BIN, 0 },
11914 { "/command", FM_CMD, 0 }, /* Not implemented */
11915 #endif /* COMMENT */
11916 { "/read", FM_REA, 0 },
11917 { "/write", FM_WRI, 0 }
11919 static int nfcswtab = (sizeof (fcswtab) / sizeof (struct keytab));
11921 static struct keytab fclkwtab[] = { /* CLOSE options */
11925 static struct keytab fsekwtab[] = { /* SEEK symbols */
11929 static int nfsekwtab = (sizeof (fsekwtab) / sizeof (struct keytab));
11931 #define SEE_LINE RD_LINE /* SEEK options */
11932 #define SEE_CHAR RD_CHAR
11936 static struct keytab fskswtab[] = {
11937 { "/absolute", SEE_ABS, 0 },
11938 { "/byte", SEE_CHAR, 0 },
11939 { "/character", SEE_CHAR, CM_INV },
11940 { "/line", SEE_LINE, 0 },
11941 { "/relative", SEE_REL, 0 }
11943 static int nfskswtab = (sizeof (fskswtab) / sizeof (struct keytab));
11945 #define COU_LINE RD_LINE /* COUNT options */
11946 #define COU_CHAR RD_CHAR
11950 static struct keytab fcoswtab[] = {
11951 { "/bytes", COU_CHAR, 0 },
11952 { "/characters",COU_CHAR, CM_INV },
11953 { "/lines", COU_LINE, 0 },
11954 { "/list", COU_LIS, 0 },
11955 { "/nolist", COU_NOL, 0 },
11956 { "/quiet", COU_NOL, CM_INV }
11958 static int nfcoswtab = (sizeof (fcoswtab) / sizeof (struct keytab));
11960 static struct keytab frdtab[] = { /* READ types */
11961 { "/block", RD_SIZE, CM_INV|CM_ARG },
11962 { "/byte", RD_CHAR, CM_INV },
11963 { "/character", RD_CHAR, 0 },
11964 { "/line", RD_LINE, 0 },
11965 { "/size", RD_SIZE, CM_ARG },
11966 { "/trim", RD_TRIM, 0 },
11967 { "/untabify", RD_UNTA, 0 }
11969 static int nfrdtab = (sizeof (frdtab) / sizeof (struct keytab));
11971 static struct keytab fwrtab[] = { /* WRITE types */
11972 { "/block", WR_SIZE, CM_INV|CM_ARG },
11973 { "/byte", WR_CHAR, CM_INV },
11974 { "/character", WR_CHAR, 0 },
11975 { "/line", WR_LINE, 0 },
11976 { "/lpad", WR_LPAD, CM_ARG },
11977 { "/rpad", WR_RPAD, CM_ARG },
11978 { "/size", WR_SIZE, CM_ARG },
11979 { "/string", WR_STRI, 0 }
11981 static int nfwrtab = (sizeof (fwrtab) / sizeof (struct keytab));
11983 static char blanks[] = "\040\040\040\040"; /* Some blanks for formatting */
11986 dofile(op) int op; { /* Do the FILE command */
11987 char vnambuf[VNAML]; /* Buffer for variable names */
11988 char *vnp = NULL; /* Pointer to same */
11989 char zfilnam[CKMAXPATH+2];
11991 struct FDB fl, sw, nu;
11993 int rsize, filmode = 0, relative = -1, eofflg = 0;
11994 int rc, x, y, cx, n, getval, dummy, confirmed, listing = -1;
11995 int charflag = 0, sizeflag = 0;
11996 int pad = 32, wr_lpad = 0, wr_rpad = 0, rd_trim = 0, rd_untab = 0;
11998 if (op == XXFILE) { /* FILE command was given */
11999 /* Get subcommand */
12000 if ((cx = cmkey(fctab,nfctab,"Operation","",xxstring)) < 0) {
12002 printf("?File operation required\n");
12007 } else { /* Shorthand command was given */
12009 case XXF_CL: cx = FIL_CLS; break; /* FCLOSE */
12010 case XXF_FL: cx = FIL_FLU; break; /* FFLUSH */
12011 case XXF_LI: cx = FIL_LIS; break; /* FLIST */
12012 case XXF_OP: cx = FIL_OPN; break; /* etc... */
12013 case XXF_RE: cx = FIL_REA; break;
12014 case XXF_RW: cx = FIL_REW; break;
12015 case XXF_SE: cx = FIL_SEE; break;
12016 case XXF_ST: cx = FIL_STA; break;
12017 case XXF_WR: cx = FIL_WRI; break;
12018 case XXF_CO: cx = FIL_COU; break;
12019 default: return(-2);
12022 switch (cx) { /* Do requested subcommand */
12023 case FIL_OPN: /* OPEN */
12024 cmfdbi(&sw, /* Switches */
12025 _CMKEY, /* fcode */
12026 "Variable or switch", /* hlpmsg */
12028 "", /* addtl string data */
12029 nfcswtab, /* addtl numeric data 1: tbl size */
12030 4, /* addtl numeric data 2: 4 = cmswi */
12031 xxstring, /* Processing function */
12032 fcswtab, /* Keyword table */
12033 &fl /* Pointer to next FDB */
12035 cmfdbi(&fl, /* Anything that doesn't match */
12036 _CMFLD, /* fcode */
12037 "Variable", /* hlpmsg */
12047 x = cmfdb(&sw); /* Parse something */
12050 printf("?Variable name and file name required\n");
12055 if (cmresult.fcode == _CMFLD)
12057 else if (cmresult.fcode == _CMKEY) {
12061 (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
12062 printf("?This switch does not take an argument\n");
12066 /* Uncomment if we add any switches ere that take args */
12067 if (!getval && (cmgkwflgs() & CM_ARG)) {
12068 printf("?This switch requires an argument\n");
12069 return(-9); /* (none do...) */
12071 #endif /* COMMENT */
12072 filmode |= cmresult.nresult; /* OR in the file mode */
12076 /* Not a switch - get the string */
12077 ckstrncpy(vnambuf,cmresult.sresult,VNAML);
12078 if (!vnambuf[0] || chknum(vnambuf)) { /* (if there is one...) */
12079 printf("?Variable name required\n");
12082 vnp = vnambuf; /* Check variable-name syntax */
12083 if (vnambuf[0] == CMDQ &&
12084 (vnambuf[1] == '%' || vnambuf[1] == '&'))
12087 if (*vnp == '%' || *vnp == '&') {
12088 if ((y = parsevar(vnp,&x,&dummy)) < 0) {
12089 printf("?Syntax error in variable name\n");
12093 if (!(filmode & FM_RWA)) /* If no access mode specified */
12094 filmode |= FM_REA; /* default to /READ. */
12096 y = 0; /* Now parse the filename */
12097 if ((filmode & FM_RWA) == FM_WRI)
12098 x = cmofi("Name of new file","",&s,xxstring);
12099 else if ((filmode & FM_RWA) == FM_REA)
12100 x = cmifi("Name of existing file","",&s,&y,xxstring);
12102 x = cmiofi("Filename","",&s,&y,xxstring);
12103 debug(F101,"fopen /append x","",x);
12106 if (zchko(s) < 0) {
12107 printf("Can't create \"%s\"\n",s);
12110 } else if (x < 0) {
12112 printf("?Filename required\n");
12117 if (y) { /* No wildcards */
12118 printf("?Wildcards not allowed here\n");
12121 if (filmode & (FM_APP|FM_WRI)) { /* Check output access */
12123 if (zchko(s) < 0) { /* and set error code if denied */
12125 printf("?Write access denied - \"%s\"\n",s);
12130 ckstrncpy(zfilnam,s,CKMAXPATH); /* Is OK - make safe copy */
12131 if ((x = cmcfm()) < 0) /* Get confirmation of command */
12133 if ((n = z_open(zfilnam,filmode)) < 0) {
12134 printf("?OPEN failed - %s: %s\n",zfilnam,ckferror(n));
12137 addmac(vnambuf,ckitoa(n)); /* Assign channel number to variable */
12138 return(success = 1);
12140 case FIL_REW: /* REWIND */
12141 if ((x = cmnum("Channel number","",10,&n, xxstring)) < 0) {
12143 printf("?Channel number required\n");
12148 if ((x = cmcfm()) < 0)
12150 if ((rc = z_seek(n,0L)) < 0) {
12151 printf("?REWIND failed - Channel %d: %s\n",n,ckferror(rc));
12154 return(success = 1);
12156 case FIL_CLS: /* CLOSE */
12157 cmfdbi(&sw, /* Second FDB - switches */
12158 _CMKEY, /* fcode */
12159 "Channel number; or keyword",
12161 "", /* addtl string data */
12162 1, /* addtl numeric data 1: tbl size */
12163 0, /* addtl numeric data 2: 4 = cmswi */
12164 xxstring, /* Processing function */
12165 fclkwtab, /* Keyword table */
12166 &nu /* Pointer to next FDB */
12168 cmfdbi(&nu, /* First FDB - command switches */
12169 _CMNUM, /* fcode */
12172 "", /* addtl string data */
12173 10, /* addtl numeric data 1: radix */
12174 0, /* addtl numeric data 2: 0 */
12175 xxstring, /* Processing function */
12176 NULL, /* Keyword table */
12177 NULL /* Pointer to next FDB */
12179 x = cmfdb(&sw); /* Parse something */
12182 printf("?Channel number or ALL required\n");
12187 if (cmresult.fcode == _CMNUM)
12188 n = cmresult.nresult;
12189 else if (cmresult.fcode == _CMKEY)
12191 if ((x = cmcfm()) < 0)
12197 for (i = 0; i < z_maxchan; i++) {
12200 printf("?CLOSE failed - Channel %d: %s\n",n,ckferror(x));
12205 debug(F101,"FILE CLOSE ALL","",count);
12206 } else if ((x = z_close(n)) < 0) {
12207 printf("?CLOSE failed - Channel %d: %s\n",n,ckferror(x));
12210 return(success = rc);
12212 case FIL_REA: /* READ */
12213 case FIL_WRI: /* WRITE */
12215 cmfdbi(&sw, /* Switches */
12216 _CMKEY, /* fcode */
12217 "Channel or switch", /* hlpmsg */
12219 "", /* addtl string data */
12220 (cx == FIL_REA) ? nfrdtab : nfwrtab,
12221 4, /* addtl numeric data 2: 4 = cmswi */
12222 xxstring, /* Processing function */
12223 (cx == FIL_REA) ? frdtab : fwrtab, /* Keyword table */
12224 &nu /* Pointer to next FDB */
12226 cmfdbi(&nu, /* Channel number */
12227 _CMNUM, /* fcode */
12230 "", /* addtl string data */
12231 10, /* addtl numeric data 1: radix */
12232 0, /* addtl numeric data 2: 0 */
12233 xxstring, /* Processing function */
12234 NULL, /* Keyword table */
12235 NULL /* Pointer to next FDB */
12238 x = cmfdb(&sw); /* Parse something */
12241 printf("?Channel number required\n");
12246 if (cmresult.fcode == _CMNUM) /* Channel number */
12248 else if (cmresult.fcode == _CMKEY) { /* Switch */
12252 (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
12253 printf("?This switch does not take an argument\n");
12256 if (!getval && (cmgkwflgs() & CM_ARG)) {
12257 printf("?This switch requires an argument\n");
12260 switch (cmresult.nresult) {
12272 if ((x = cmnum("Bytes","",10,&rsize, xxstring)) < 0) {
12274 printf("?Number required\n");
12289 if ((x = cmnum("Numeric ASCII character value",
12290 "32",10,&pad, xxstring)) < 0)
12292 if (cmresult.nresult == WR_LPAD)
12304 debug(F101,"FILE READ rsize 2","",rsize);
12308 (cmresult.fcode == _CMKEY);
12310 n = cmresult.nresult; /* Channel */
12311 debug(F101,"FILE READ/WRITE channel","",n);
12313 if (cx == FIL_WRI) { /* WRITE */
12315 if ((x = cmtxt("Text","",&s,xxstring)) < 0)
12317 ckstrncpy(line,s,LINBUFSIZ); /* Make a safe copy */
12319 s = brstrip(s); /* Strip braces */
12320 if (charflag) { /* Write one char */
12321 len = 1; /* So length = 1 */
12322 rsize = 1; /* Don't supply terminator */
12323 } else if (!sizeflag) { /* Write a string */
12324 len = -1; /* So length is unspecified */
12325 } else { /* Write a block of given size */
12327 if (rsize > TMPBUFSIZ) {
12329 printf("?Buffer overflow\n");
12332 len = rsize; /* rsize is really length */
12333 rsize = 1; /* Don't supply a terminator */
12334 xx = strlen(s); /* Size of given string */
12335 if (xx >= len) { /* Bigger or equal */
12337 } else if (wr_lpad) { /* Smaller, left-padding requested */
12338 for (i = 0; i < len - xx; i++) /* Must make a copy */
12340 ckstrncpy(tmpbuf+i,s,TMPBUFSIZ-i);
12342 s = tmpbuf; /* Redirect write source */
12343 } else if (wr_rpad) { /* Smaller with right-padding */
12344 for (i = xx; i < len; i++)
12349 if ((rc = z_out(n,s,len,rsize)) < 0) { /* Try to write */
12350 printf("?Channel %d WRITE error: %s\n",n,ckferror(rc));
12353 } else { /* FIL_REA READ */
12356 x = cmfld("Variable name","",&s,NULL);
12357 debug(F111,"FILE READ cmfld",s,x);
12359 if (x == -3 || !*s) {
12360 if ((x = cmcfm()) < 0)
12367 ckstrncpy(vnambuf,s,VNAML);
12368 debug(F111,"FILE READ vnambuf",vnambuf,confirmed);
12369 if (vnambuf[0]) { /* Variable name given, check it */
12378 if (vnambuf[0] == CMDQ &&
12379 (vnambuf[1] == '%' || vnambuf[1] == '&'))
12382 if (*vnp == '%' || *vnp == '&') {
12383 if ((y = parsevar(vnp,&x,&dummy)) < 0) {
12384 printf("?Syntax error in variable name\n");
12389 debug(F111,"FILE READ variable",vnambuf,confirmed);
12392 if ((x = cmcfm()) < 0)
12395 line[0] = NUL; /* Clear destination buffer */
12396 if (rsize >= LINBUFSIZ) /* Don't overrun it */
12397 rsize = LINBUFSIZ - 1;
12399 if (rsize == 0) { /* Read a line */
12400 rc = z_in(n,line,LINBUFSIZ,LINBUFSIZ-1,0);
12402 rc = z_in(n,line,LINBUFSIZ,rsize,1); /* Read a block */
12404 if (rc < 0) { /* Error... */
12405 debug(F101,"FILE READ error","",rc);
12406 debug(F101,"FILE READ errno","",errno);
12407 if (rc == FX_EOF) { /* EOF - fail but no error message */
12408 return(success = 0);
12409 } else { /* Other error - fail and print msg */
12410 printf("?READ error: %s\n",ckferror(rc));
12414 if (rsize == 0) { /* FREAD /LINE postprocessing */
12415 if (rd_trim) { /* Trim */
12419 for (i = k-1; i > 0; i--) {
12420 if (line[i] == SP || line[i] == '\t')
12427 if (rd_untab) { /* Untabify */
12428 if (untabify(line,tmpbuf,TMPBUFSIZ) > -1)
12429 ckstrncpy(line,tmpbuf,LINBUFSIZ);
12432 debug(F110,"FILE READ data",line,0);
12433 if (vnambuf[0]) /* Read OK - If variable name given */
12434 addmac(vnambuf,line); /* Assign result to variable */
12435 else /* otherwise */
12436 printf("%s\n",line); /* just print it */
12438 return(success = 1);
12440 case FIL_SEE: /* SEEK */
12441 case FIL_COU: /* COUNT */
12442 rsize = RD_CHAR; /* Defaults to /BYTE */
12443 cmfdbi(&sw, /* Switches */
12444 _CMKEY, /* fcode */
12445 "Channel or switch", /* hlpmsg */
12447 "", /* addtl string data */
12448 ((cx == FIL_SEE) ? nfskswtab : nfcoswtab),
12449 4, /* addtl numeric data 2: 4 = cmswi */
12450 xxstring, /* Processing function */
12451 ((cx == FIL_SEE) ? fskswtab : fcoswtab),
12452 &nu /* Pointer to next FDB */
12454 cmfdbi(&nu, /* Channel number */
12455 _CMNUM, /* fcode */
12458 "", /* addtl string data */
12459 10, /* addtl numeric data 1: radix */
12460 0, /* addtl numeric data 2: 0 */
12461 xxstring, /* Processing function */
12462 NULL, /* Keyword table */
12463 NULL /* Pointer to next FDB */
12466 x = cmfdb(&sw); /* Parse something */
12469 printf("?Channel number required\n");
12474 if (cmresult.fcode == _CMNUM) /* Channel number */
12476 else if (cmresult.fcode == _CMKEY) { /* Switch */
12480 (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
12481 printf("?This switch does not take an argument\n");
12484 if (cx == FIL_SEE) {
12485 switch (cmresult.nresult) {
12486 case SEE_REL: relative = 1; break;
12487 case SEE_ABS: relative = 0; break;
12488 default: rsize = cmresult.nresult;
12490 } else if (cx == FIL_COU) {
12491 switch (cmresult.nresult) {
12492 case COU_LIS: listing = 1; break;
12493 case COU_NOL: listing = 0; break;
12494 default: rsize = cmresult.nresult;
12499 (cmresult.fcode == _CMKEY);
12501 n = cmresult.nresult; /* Channel */
12502 debug(F101,"FILE SEEK/COUNT channel","",n);
12503 if (cx == FIL_COU) {
12504 if ((x = cmcfm()) < 0)
12506 z_filcount = z_count(n,rsize);
12507 if (z_filcount < 0) {
12509 printf("?COUNT error: %s\n",ckferror(rc));
12513 listing = !xcmdsrc;
12515 printf(" %ld %s%s\n",
12517 ((rsize == RD_CHAR) ? "byte" : "line"),
12518 ((z_filcount == 1L) ? "" : "s")
12520 return(success = (z_filcount > -1) ? 1 : 0);
12522 cmfdbi(&sw, /* SEEK symbolic targets (EOF) */
12523 _CMKEY, /* fcode */
12524 "Channel number;\n or keyword",
12526 "", /* addtl string data */
12527 nfsekwtab, /* addtl numeric data 1: table size */
12528 0, /* addtl numeric data 2: 4 = cmswi */
12529 xxstring, /* Processing function */
12530 fsekwtab, /* Keyword table */
12531 &nu /* Pointer to next FDB */
12533 cmfdbi(&nu, /* Channel number */
12534 _CMNUM, /* fcode */
12537 "", /* addtl string data */
12538 10, /* addtl numeric data 1: radix */
12539 0, /* addtl numeric data 2: 0 */
12540 xxstring, /* Processing function */
12541 NULL, /* Keyword table */
12542 NULL /* Pointer to next FDB */
12544 x = cmfdb(&sw); /* Parse something */
12547 printf("?Channel number or EOF required\n");
12552 if (cmresult.fcode == _CMNUM) {
12553 y = cmresult.nresult;
12554 debug(F110,"FILE SEEK atmbuf",atmbuf,0);
12555 if (relative < 0) {
12556 if (cx == FIL_SEE && (atmbuf[0] == '+' || atmbuf[0] == '-'))
12561 } else if (cmresult.fcode == _CMKEY) {
12562 eofflg = cmresult.nresult;
12566 if ((x = cmcfm()) < 0)
12568 z = y; /* Convert to long */
12569 y = 1; /* Recycle this */
12571 debug(F101,"FILE SEEK relative","",relative);
12572 debug(F101,"FILE SEEK rsize","",rsize);
12574 if (rsize == RD_CHAR) { /* Seek to byte position */
12575 if (relative > 0) {
12580 printf("?Relative SEEK failed: %s\n",ckferror(rc));
12585 if (z < 0 && !eofflg) { /* Negative arg but not relative */
12586 y = 0; /* Remember this was bad */
12587 z = 0; /* but substitute 0 */
12590 debug(F101,"FILE SEEK /CHAR z","",z);
12591 if (z < 0 && !eofflg) {
12593 return(success = 0);
12595 if ((rc = z_seek(n,z)) < 0) {
12596 if (rc == FX_EOF) return(success = 0);
12597 printf("?SEEK /BYTE failed - Channel %d: %s\n",n,ckferror(rc));
12600 } else { /* Seek to line */
12601 if (relative > 0) {
12603 pos = z_getline(n);
12604 debug(F101,"FILE SEEK /LINE pos","",pos);
12607 printf("?Relative SEEK failed: %s\n",ckferror(rc));
12612 debug(F101,"FILE SEEK /LINE z","",z);
12613 debug(F101,"FILE SEEK /LINE eofflg","",eofflg);
12614 if (z < 0 && !eofflg) {
12616 return(success = 0);
12618 if ((rc = z_line(n,z)) < 0) {
12619 if (rc == FX_EOF) return(success = 0);
12620 printf("?SEEK /LINE failed - Channel %d: %s\n",n,ckferror(rc));
12624 return(success = y);
12626 case FIL_LIS: { /* LIST open files */
12628 extern int cmd_rows, cmd_cols;
12629 #endif /* CK_TTGWSIZ */
12630 extern int xaskmore;
12631 int i, x, n = 0, paging = 0;
12634 if ((x = cmcfm()) < 0)
12638 if (cmd_rows > 0 && cmd_cols > 0)
12639 #endif /* CK_TTGWSIZ */
12642 printf("System open file limit: %4d\n", z_openmax);
12643 printf("Maximum for FILE OPEN: %4d\n", z_maxchan);
12644 printf("Files currently open: %4d\n\n", z_nopen);
12646 for (i = 0; i < z_maxchan; i++) {
12647 s = z_getname(i); /* Got one? */
12651 printf("%2d. %s",i,s); /* Print name */
12652 n++; /* Count it */
12653 x = z_getmode(i); /* Get modes & print them */
12655 if (x & FM_REA) ckstrncat(m,"R",8);
12656 if (x & FM_WRI) ckstrncat(m,"W",8);
12657 if (x & FM_APP) ckstrncat(m,"A",8);
12658 if (x & FM_BIN) ckstrncat(m,"B",8);
12664 printf(" %ld",z_getpos(i)); /* And file position too */
12668 if (paging > 0) { /* Pause at end of screen */
12669 if (n > cmd_rows - 3) {
12676 #endif /* CK_TTGWSIZ */
12679 return(success = 1);
12682 case FIL_FLU: /* FLUSH */
12683 if ((x = cmnum("Channel number","",10,&n, xxstring)) < 0) {
12685 printf("?Channel number required\n");
12690 if ((x = cmcfm()) < 0)
12692 if ((rc = z_flush(n)) < 0) {
12693 printf("?FLUSH failed - Channel %d: %s\n",n,ckferror(rc));
12696 return(success = 1);
12698 case FIL_STA: /* STATUS */
12699 if ((x = cmnum("Channel number","",10,&n, xxstring)) < 0) {
12701 printf("?Channel number required\n");
12706 if ((x = cmcfm()) < 0)
12708 p = blanks + 3; /* Tricky formatting... */
12712 if ((rc = z_getmode(n)) < 0) {
12713 printf("Channel %d:%s%s\n",n,p,ckferror(rc));
12714 return(success = 0);
12716 printf("Channel %d:%sNot open\n",n,p);
12717 return(success = 0);
12721 if (!s) s = "(name unknown)";
12722 printf("Channel %d:%sOpen\n",n,p);
12723 printf(" File: %s\n Modes: ",s);
12724 if (rc & FM_REA) printf(" /READ");
12725 if (rc & FM_WRI) printf(" /WRITE");
12726 if (rc & FM_APP) printf(" /APPEND");
12727 if (rc & FM_BIN) printf(" /BINARY");
12728 if (rc & FM_CMD) printf(" /COMMAND");
12729 if (rc & FM_EOF) printf(" [EOF]");
12730 printf("\n Size: %ld\n",z_count(n,RD_CHAR));
12731 printf(" At byte: %ld\n",z_getpos(n));
12734 printf(" At line: %ld\n",xx);
12735 return(success = 1);
12741 #endif /* CKCHANNELIO */
12744 /* Save Key maps and in OS/2 Mouse maps */
12746 savkeys(name,disp) char * name; int disp; {
12748 static struct filinfo xx;
12749 int savfil, i, j, k;
12755 xx.bs = 0; xx.cs = 0; xx.rl = 0; xx.org = 0; xx.cc = 0;
12756 xx.typ = 0; xx.dsp = XYFZ_A; xx.os_specific = "";
12758 savfil = zopeno(ZMFILE,name,NULL,&xx);
12759 } else savfil = zopeno(ZMFILE,name,NULL,NULL);
12764 zsout(ZMFILE, "; Kermit 95 SAVE KEYMAP file: ");
12768 "if eq \"\\v(program)\" \"C-Kermit\" set mskermit keycodes on");
12771 "if NOT eq \"\\v(program)\" \"C-Kermit\" stop 1 C-Kermit required.");
12772 zsoutl(ZMFILE,"set mskermit keycodes off");
12777 zsout(ZMFILE, "; C-Kermit SAVE KEYMAP file: ");
12781 zsoutl(ZMFILE,"; Clear previous keyboard mappings ");
12782 zsoutl(ZMFILE,"set key clear");
12784 for (k = 0; k < nttkey; k++) {
12785 if (!ttkeytab[k].flgs) {
12787 "set terminal key ",
12792 zsoutl(ZMFILE,buf);
12798 for (i = 0; i < KMSIZE; i++) {
12800 int len = strlen((char *)macrotab[i]);
12805 ckitoa(mskkeys ? cktomsk(i) : i),
12819 for (j = 0; j < len; j++) {
12820 char ch = macrotab[i][j];
12821 if (ch <= SP || ch >= DEL ||
12822 ch == '-' || ch == ',' ||
12823 ch == '{' || ch == '}' ||
12824 ch == ';' || ch == '?' ||
12825 ch == '.' || ch == '\'' ||
12826 ch == '\\' || ch == '/' ||
12828 ckmakmsg(buf,1024,"\\{",ckitoa((int)ch),"}",NULL);
12831 ckmakmsg(buf,1024,ckctoa((char)ch),NULL,NULL,NULL);
12836 ckmakmsg(buf,1024,"\t; ",keyname(i),NULL,NULL);
12837 zsoutl(ZMFILE,buf);
12841 } else if ( keymap[i] != i ) {
12843 if (IS_KVERB(keymap[i])) {
12844 for (j = 0; j < nkverbs; j++)
12845 if (kverbs[j].kwval == (keymap[i] & ~F_KVERB))
12847 if (j != nkverbs) {
12850 sprintf(buf, "set key \\%d \\K%s\t; %s",
12851 mskkeys ? cktomsk(i) : i,
12852 kverbs[j].kwd, keyname(i)
12855 ckmakxmsg(buf, /* 12 string args */
12858 ckitoa(mskkeys ? cktomsk(i) : i),
12863 NULL, NULL, NULL, NULL, NULL, NULL);
12864 #endif /* COMMENT */
12865 zsoutl(ZMFILE,buf);
12868 sprintf(buf, "set key \\%d \\K%s", i, kverbs[j].kwd);
12876 #endif /* COMMENT */
12877 zsoutl(ZMFILE,buf);
12881 #endif /* NOKVERBS */
12885 sprintf(buf, "set key \\%d \\{%d}\t; %s",
12886 mskkeys ? cktomsk(i) : i,
12891 ckmakxmsg(buf, /* 8 string args */
12894 ckitoa(mskkeys ? cktomsk(i) : i),
12899 NULL,NULL,NULL,NULL,NULL,NULL);
12900 #endif /* COMMENT */
12901 zsoutl(ZMFILE,buf);
12904 sprintf(buf, "set key \\%d \\{%d}", i, keymap[i]);
12906 ckmakxmsg(buf,1024,
12912 NULL,NULL,NULL,NULL,NULL,NULL,NULL);
12913 #endif /* COMMENT */
12914 zsoutl(ZMFILE,buf);
12920 /* OS/2 also has the SET TERMINAL KEY <termtype> defines */
12921 for (k = 0; k < nttkey; k++) {
12922 extern struct keynode * ttkeymap[];
12923 struct keynode * pnode = NULL;
12925 if (ttkeytab[k].flgs) /* Don't process CM_INV or CM_ABR */
12929 ckmakmsg(buf,1024,"; SET TERMINAL KEY ",ttkeytab[k].kwd,NULL,NULL);
12930 zsoutl(ZMFILE,buf);
12932 for (pnode = ttkeymap[ttkeytab[k].kwval];
12934 pnode = pnode->next
12936 switch (pnode->def.type) {
12939 sprintf(buf, "set terminal key %s \\%d \\{%d}\t; %s",
12941 mskkeys ? cktomsk(pnode->key) : pnode->key,
12942 pnode->def.key.scancode,
12943 keyname(pnode->key)
12948 "set terminal key ",
12952 cktomsk(pnode->key) :
12955 ckitoa(pnode->def.key.scancode),
12957 keyname(pnode->key),
12958 NULL,NULL,NULL,NULL
12960 #endif /* COMMENT */
12961 zsoutl(ZMFILE,buf);
12964 for (j = 0; j < nkverbs; j++)
12965 if (kverbs[j].kwval == (pnode->def.kverb.id & ~F_KVERB))
12967 if (j != nkverbs) {
12969 sprintf(buf, "set terminal key %s \\%d \\K%s\t; %s",
12971 mskkeys ? cktomsk(pnode->key) : pnode->key,
12972 kverbs[j].kwd, keyname(pnode->key)
12977 "set terminal key ",
12981 cktomsk(pnode->key) :
12986 keyname(pnode->key),
12987 NULL,NULL,NULL,NULL
12989 #endif /* COMMENT */
12990 zsoutl(ZMFILE,buf);
12994 int len = strlen((char *)pnode->def.macro.string);
12996 sprintf(buf,"set terminal key %s \\%d ",
12998 mskkeys ? cktomsk(pnode->key) : pnode->key);
13002 "set terminal key ",
13006 cktomsk(pnode->key) :
13009 NULL,NULL,NULL,NULL,NULL,NULL,NULL
13011 #endif /* COMMENT */
13014 for (j = 0; j < len; j++) {
13015 char ch = pnode->def.macro.string[j];
13016 if (ch <= SP || ch >= DEL ||
13017 ch == '-' || ch == ',' ||
13018 ch == '{' || ch == '}' ||
13019 ch == ';' || ch == '?' ||
13020 ch == '.' || ch == '\'' ||
13021 ch == '\\' || ch == '/' ||
13024 "\\{",ckitoa((int)ch),"}",NULL);
13028 ckctoa((char)ch),NULL,NULL,NULL);
13032 ckmakmsg(buf,1024,"\t; ",keyname(pnode->key),NULL,NULL);
13033 zsoutl(ZMFILE,buf);
13037 int len = strlen((char *)pnode->def.literal.string);
13039 sprintf(buf,"set terminal key %s /literal \\%d ",
13041 mskkeys ? cktomsk(pnode->key) : pnode->key);
13045 "set terminal key ",
13049 cktomsk(pnode->key) :
13052 NULL,NULL,NULL,NULL,NULL,NULL,NULL);
13053 #endif /* COMMENT */
13056 for (j = 0; j < len; j++) {
13057 char ch = pnode->def.literal.string[j];
13058 if (ch <= SP || ch >= DEL ||
13059 ch == '-' || ch == ',' ||
13060 ch == '{' || ch == '}' ||
13061 ch == ';' || ch == '?' ||
13062 ch == '.' || ch == '\'' ||
13063 ch == '\\' || ch == '/' ||
13066 "\\{",ckitoa((int)ch),"}",NULL);
13070 ckctoa((char)ch),NULL,NULL,NULL);
13074 ckmakmsg(buf,1024,"\t; ",keyname(pnode->key),NULL,NULL);
13075 zsoutl(ZMFILE,buf);
13081 "set terminal key %s /literal \\%d \\{%d}\\{%d}\t; %s",
13083 mskkeys ? cktomsk(pnode->key) : pnode->key,
13084 ISDG200(ttkeytab[k].kwval) ? 30 : 27,
13085 pnode->def.esc.key & ~F_ESC,
13086 keyname(pnode->key)
13091 "set terminal key ",
13095 cktomsk(pnode->key) :
13098 ckitoa(ISDG200(ttkeytab[k].kwval) ? 30 : 27),
13100 ckitoa(pnode->def.esc.key & ~F_ESC),
13102 keyname(pnode->key),
13105 #endif /* COMMENT */
13106 zsoutl(ZMFILE,buf);
13111 "set terminal key %s /literal \\%d \\{27}[\\{%d}\t; %s",
13113 mskkeys ? cktomsk(pnode->key) : pnode->key,
13114 pnode->def.csi.key & ~F_CSI,
13115 keyname(pnode->key)
13120 "set terminal key ",
13124 cktomsk(pnode->key) :
13127 ckitoa(pnode->def.csi.key & ~F_CSI),
13129 keyname(pnode->key),
13130 NULL,NULL,NULL,NULL
13132 #endif /* COMMENT */
13133 zsoutl(ZMFILE,buf);
13143 zsoutl(ZMFILE,"; End");
13145 return(success = 1);
13147 return(success = 0);
13150 #endif /* NOSETKEY */
13157 static struct keytab trmtrmopt[] = {
13158 { "scrollback", SV_SCRL, 0 }
13160 #endif /* NOLOCAL */
13163 static struct keytab cmdtrmopt[] = {
13165 { "history", SV_HIST, 0 },
13166 #endif /* CK_RECALL */
13169 { "scrollback", SV_SCRL, 0 },
13170 #endif /* NOLOCAL */
13174 static int ncmdtrmopt = (sizeof (cmdtrmopt) / sizeof (struct keytab)) - 1;
13178 _PROTOTYP(int savscrbk, (int, char *, int));
13179 #endif /* NOLOCAL */
13183 _PROTOTYP(int savhistory, (char *, int));
13184 #endif /* CK_RECALL */
13187 dosave(xx) int xx; {
13188 int x, y = 0, disp;
13190 extern struct keytab disptb[];
13192 struct zfnfp * fnp;
13193 #endif /* ZFNQFP */
13196 if (xx == XSKEY) { /* SAVE KEYMAP.. */
13197 z = cmofi("Name of Kermit command file","keymap.ksc",&s,xxstring);
13199 #endif /* NOSETKEY */
13201 case XSCMD: /* SAVE COMMAND.. */
13202 if ((y = cmkey(cmdtrmopt, ncmdtrmopt, "What to save",
13213 case XSTERM: /* SAVE TERMINAL.. */
13214 if ((y = cmkey(trmtrmopt,1,
13215 "What to save","scrollback",xxstring)) < 0)
13218 #endif /* NOLOCAL */
13221 z = cmofi("Filename",
13222 ((y == SV_SCRL) ? "scrollbk.txt" : "history.txt"),
13228 #endif /* NOSETKEY */
13229 if (z < 0) /* Check output-file parse results */
13232 printf("?Sorry, %s is a directory name\n",s);
13236 if ((fnp = zfnqfp(s,TMPBUFSIZ - 1,tmpbuf))) {/* Convert to full pathname */
13238 if ((int) strlen(fnp->fpath) > 0)
13241 #endif /* ZFNQFP */
13243 ckstrncpy(line,s,LINBUFSIZ); /* Make safe copy of pathname */
13248 /* Get NEW/APPEND disposition */
13249 if ((z = cmkey(disptb,2,"Disposition","new",xxstring)) < 0)
13253 if ((x = cmcfm()) < 0) /* Get confirmation */
13256 switch (xx) { /* Do action.. */
13258 case XSKEY: /* SAVE KEYMAP */
13259 return (savkeys(s,disp));
13260 #endif /* NOSETKEY */
13262 case XSCMD: /* SAVE COMMAND.. */
13265 if (y == SV_SCRL) /* .. SCROLLBACK */
13266 return(success = savscrbk(VCMD,s,disp));
13267 #endif /* NOLOCAL */
13270 if (y == SV_HIST) /* .. HISTORY */
13271 return(success = savhistory(s,disp));
13273 #endif /* NORECALL */
13277 case XSTERM: /* SAVE TERMINAL SCROLLBACK */
13278 return(success = savscrbk(VTERM,s,disp));
13279 #endif /* NOLOCAL */
13289 Read text with a custom prompt into given buffer using command parser but
13290 with no echoing or entry into recall buffer.
13293 readtext(prmpt, buffer, bufsiz) char * prmpt; char * buffer; int bufsiz; {
13295 extern int on_recall; /* Around Password prompting */
13296 #endif /* CK_RECALL */
13301 extern int startflags;
13302 int vmode_sav = vmode;
13304 if (!prmpt) prmpt = "";
13306 if (win95_popup && !(startflags & 96)
13311 return(popup_readtext(vmode,NULL,prmpt,buffer,bufsiz,0));
13313 if (vmode == VTERM) {
13315 VscrnIsDirty(VTERM);
13316 VscrnIsDirty(VCMD);
13319 #endif /* NOLOCAL */
13323 #endif /* CK_RECALL */
13324 cmsavp(psave,PROMPTL); /* Save old prompt */
13325 cmsetp(prmpt); /* Make new prompt */
13326 concb((char)escape); /* Put console in cbreak mode */
13327 cmini(1); /* and echo mode */
13328 if (pflag) prompt(xxstring); /* Issue prompt if at top level */
13329 cmres(); /* Reset the parser */
13330 for (rc = -1; rc < 0; ) { /* Prompt till they answer */
13331 rc = cmtxt("","",&s,NULL); /* Get a literal line of text */
13332 cmres(); /* Reset the parser again */
13334 ckstrncpy(buffer,s,bufsiz);
13335 cmsetp(psave); /* Restore original prompt */
13339 if (vmode != vmode_sav) {
13341 VscrnIsDirty(VCMD);
13342 VscrnIsDirty(VTERM);
13345 #endif /* NOLOCAL */
13350 /* A general function to allow a Password or other information */
13351 /* to be read from the command prompt without it going into */
13352 /* the recall buffer or being echo'd. */
13355 readpass(prmpt, buffer, bufsiz) char * prmpt; char * buffer; int bufsiz; {
13358 if (!prmpt) prmpt = "";
13359 printf("%s", prmpt);
13361 /* Some linkers won't allow this because it's unsafe */
13363 #else /* COMMENT */
13365 int c, i; char * p;
13367 for (i = 0; i < bufsiz-1; i++) {
13368 if ((c = getchar()) == EOF)
13376 #endif /* COMMENT */
13380 extern int on_recall; /* around Password prompting */
13381 #endif /* CK_RECALL */
13386 extern int startflags;
13387 int vmode_sav = vmode;
13389 #endif /* NOLOCAL */
13392 #endif /* CKSYSLOG */
13393 if (!prmpt) prmpt = "";
13395 debok = 0; /* Don't log */
13397 if (win95_popup && !(startflags & 96)
13402 x = popup_readpass(vmode,NULL,prmpt,buffer,bufsiz,0);
13407 #endif /* NOLOCAL */
13410 savlog = ckxsyslog; /* Save and turn off syslogging */
13412 #endif /* CKSYSLOG */
13415 if (vmode == VTERM) {
13417 VscrnIsDirty(VTERM);
13418 VscrnIsDirty(VCMD);
13421 #endif /* NOLOCAL */
13424 #endif /* CK_RECALL */
13425 cmsavp(psave,PROMPTL); /* Save old prompt */
13426 cmsetp(prmpt); /* Make new prompt */
13427 concb((char)escape); /* Put console in cbreak mode */
13428 cmini(0); /* and no-echo mode */
13429 if (pflag) prompt(xxstring); /* Issue prompt if at top level */
13430 cmres(); /* Reset the parser */
13431 for (rc = -1; rc < 0; ) { /* Prompt till they answer */
13432 rc = cmtxt("","",&s,NULL); /* Get a literal line of text */
13433 cmres(); /* Reset the parser again */
13435 ckstrncpy(buffer,s,bufsiz);
13436 printf("\r\n"); /* Echo a CRLF */
13437 cmsetp(psave); /* Restore original prompt */
13438 cmini(1); /* Restore echo mode */
13441 if (vmode != vmode_sav) {
13443 VscrnIsDirty(VCMD);
13444 VscrnIsDirty(VTERM);
13447 #endif /* NOLOCAL */
13449 ckxsyslog = savlog; /* Restore syslogging */
13450 #endif /* CKSYSLOG */
13457 struct keytab authtab[] = { /* Available authentication types */
13459 { "k4", AUTH_KRB4, CM_INV },
13460 { "k5", AUTH_KRB5, CM_INV },
13461 { "kerberos4", AUTH_KRB4, 0 },
13462 { "kerberos5", AUTH_KRB5, 0 },
13463 { "krb4", AUTH_KRB4, CM_INV },
13464 { "krb5", AUTH_KRB5, CM_INV },
13465 #endif /* CK_KERBEROS */
13467 { "ntlm", AUTH_NTLM, 0 },
13470 { "srp", AUTH_SRP, 0 },
13471 #endif /* CK_SRP */
13473 { "ssl", AUTH_SSL, 0 },
13474 #endif /* CK_SSL */
13477 int authtabn = sizeof(authtab)/sizeof(struct keytab)-1;
13480 struct keytab kerbtab[] = { /* Kerberos authentication types */
13481 { "k4", AUTH_KRB4, CM_INV },
13482 { "k5", AUTH_KRB5, CM_INV },
13483 { "kerberos4", AUTH_KRB4, 0 },
13484 { "kerberos5", AUTH_KRB5, 0 },
13485 { "krb4", AUTH_KRB4, CM_INV },
13486 { "krb5", AUTH_KRB5, CM_INV }
13488 int kerbtabn = sizeof(kerbtab)/sizeof(struct keytab);
13490 static struct keytab krb_s_tbl[] = { /* AUTHENTICATE command switches: */
13491 { "/cache", KRB_S_CA, CM_ARG }
13493 static int krb_s_n = sizeof(krb_s_tbl)/sizeof(struct keytab);
13495 static struct keytab krb_v_tbl[] = { /* KERBEROS version values: */
13497 { "5", 5, 0 }, /* (add others as needed...) */
13498 { "auto", 0, 0 } /* Note: 0 = auto */
13500 static int krb_v_n = sizeof(krb_v_tbl)/sizeof(struct keytab);
13502 static struct keytab krb_a_tbl[] = { /* KERBEROS actions: */
13503 { "destroy", KRB_A_DE, 0 },
13504 { "initialize", KRB_A_IN, 0 },
13505 { "list-credentials", KRB_A_LC, 0 }
13507 static int krb_a_n = sizeof(krb_a_tbl)/sizeof(struct keytab);
13509 static struct keytab krb4_i_tbl[] = { /* KERBEROS 4 INITIALIZE switches: */
13510 { "/brief", KRB_I_BR, 0 }, /* /BRIEF */
13511 { "/instance", KRB_I_IN, CM_ARG }, /* /INSTANCE: */
13512 { "/lifetime", KRB_I_LF, CM_ARG }, /* /LIFETIME: */
13513 { "/not-preauth", KRB_I_NPA, 0 }, /* /NOT-PREAUTH */
13514 { "/password", KRB_I_PW, CM_ARG }, /* /PASSWORD: */
13516 { "/popup", KRB_I_POP, 0 }, /* /POPUP */
13518 { "/preauth", KRB_I_PA, 0 }, /* /PREAUTH */
13519 { "/realm", KRB_I_RL, CM_ARG }, /* /REALM: */
13520 { "/verbose", KRB_I_VB, 0 }, /* /VERBOSE */
13523 static int krb4_i_n = sizeof(krb4_i_tbl)/sizeof(struct keytab) - 1;
13525 static struct keytab krb5_i_tbl[] = { /* KERBEROS 5 INITIALIZE switches: */
13526 { "/addresses", KRB_I_ADR, CM_ARG },
13527 { "/forwardable", KRB_I_FW, 0 }, /* /FORWARDABLE */
13528 { "/instance", KRB_I_IN, CM_ARG }, /* /INSTANCE: */
13529 { "/k4", KRB_I_K4, CM_INV }, /* /KERBEROS4 */
13530 { "/kerberos4", KRB_I_K4, 0 }, /* /KERBEROS4 */
13531 { "/krb4", KRB_I_K4, CM_INV }, /* /KERBEROS4 */
13532 { "/lifetime", KRB_I_LF, CM_ARG }, /* /LIFETIME: */
13533 { "/no-addresses", KRB_I_NAD, 0 }, /* /NO-ADDRESSES */
13534 { "/no-k4", KRB_I_NK4, CM_INV },/* /NO-KERBEROS4 */
13535 { "/no-kerberos4", KRB_I_NK4, 0 }, /* /NO-KERBEROS4 */
13536 { "/no-krb4", KRB_I_NK4, CM_INV },/* /NO-KERBEROS4 */
13537 { "/not-forwardable", KRB_I_NFW, 0 }, /* /NOT-FORWARDABLE */
13538 { "/not-proxiable", KRB_I_NPR, 0 }, /* /NOT-PROXIABLE */
13539 { "/password", KRB_I_PW, CM_ARG }, /* /PASSWORD: */
13541 { "/popup", KRB_I_POP, 0 }, /* /POPUP */
13543 { "/postdate", KRB_I_PD, CM_ARG }, /* /POSTDATE: */
13544 { "/pr", KRB_I_PR, CM_INV|CM_ABR }, /* to allow for */
13545 { "/pro", KRB_I_PR, CM_INV|CM_ABR }, /* different spellings */
13546 { "/prox", KRB_I_PR, CM_INV|CM_ABR },
13547 { "/proxiable", KRB_I_PR, 0 }, /* /PROXIABLE */
13548 { "/proxyable", KRB_I_PR, CM_INV }, /* /PROXYABLE */
13549 { "/realm", KRB_I_RL, CM_ARG }, /* /REALM: */
13550 { "/renew", KRB_I_RN, 0 }, /* /RENEW */
13551 { "/renewable", KRB_I_RB, CM_ARG }, /* /RENEWABLE: */
13552 { "/service", KRB_I_SR, CM_ARG }, /* /SERVICE: */
13553 { "/validate", KRB_I_VA, 0 }, /* /VALIDATE */
13556 static int krb5_i_n = sizeof(krb5_i_tbl)/sizeof(struct keytab) - 1;
13558 static struct keytab klctab[] = { /* List Credentials switches*/
13559 { "/addresses", XYKLCAD, 0 },
13560 { "/encryption", XYKLCEN, 0 },
13561 { "/flags", XYKLCFL, 0 }
13563 static int nklctab = sizeof(klctab)/sizeof(struct keytab);
13565 extern int krb_action;
13566 extern struct krb_op_data krb_op;
13568 extern struct krb5_list_cred_data krb5_lc;
13569 extern struct krb5_init_data krb5_init;
13570 extern char * krb5_d_principal; /* Default principal */
13571 extern char * krb5_d_instance;
13572 extern char * krb5_d_realm; /* Default realm */
13573 extern char * krb5_d_cc; /* Default credentials cache */
13574 extern char * krb5_d_srv; /* Default service name */
13575 extern int krb5_d_lifetime; /* Default lifetime */
13576 extern int krb5_d_forwardable;
13577 extern int krb5_d_proxiable;
13578 extern int krb5_d_renewable;
13579 extern int krb5_autoget;
13580 extern int krb5_autodel;
13581 extern int krb5_d_getk4;
13582 extern int krb5_d_no_addresses;
13583 extern int krb5_checkaddrs;
13584 extern char * krb5_d_addrs[];
13585 extern char * k5_keytab; /* Keytab file */
13587 extern struct krb4_init_data krb4_init;
13588 extern char * krb4_d_principal; /* Default principal */
13589 extern char * krb4_d_realm; /* Default realm */
13590 extern char * krb4_d_srv; /* Default service name */
13591 extern int krb4_d_lifetime; /* Default lifetime */
13592 extern int krb4_d_preauth;
13593 extern char * krb4_d_instance;
13594 extern int krb4_autoget;
13595 extern int krb4_autodel;
13596 extern int krb4_checkaddrs;
13597 extern char * k4_keytab; /* Keytab file */
13598 #endif /* CK_KERBEROS */
13605 extern int ckxsyslog, ckxwtmp, ckxanon;
13607 extern int ckxpriv;
13610 extern int ckxperms;
13611 #endif /* CK_PERMS */
13612 extern char * anonfile, * userfile, * anonroot;
13614 extern char * anonacct;
13617 extern char * iks_domain;
13619 #endif /* CK_LOGIN */
13621 extern char * wtmpfile;
13622 #endif /* CKWTMP */
13624 extern char * dbfile;
13625 extern int dbenabled;
13628 extern int logintimo;
13629 #endif /* CK_LOGIN */
13630 extern int srvcdmsg, success, iksdcf, noinit, arg_x;
13631 extern char * cdmsgfile[], * cdmsgstr, *kermrc;
13632 char * bannerfile = NULL;
13633 char * helpfile = NULL;
13634 extern int xferlog;
13635 extern char * xferfile;
13639 printf("?Command disabled\r\n");
13640 return(success = 0);
13643 printf("IKS Settings\r\n");
13646 printf(" Anonymous Account: %s\r\n",anonacct?anonacct:"<none>");
13648 printf(" Anonymous Initfile: %s\r\n",anonfile?anonfile:"<none>");
13649 printf(" Anonymous Login: %d\r\n",ckxanon);
13650 printf(" Anonymous Root: %s\r\n",anonroot?anonroot:"<none>");
13651 #endif /* CK_LOGIN */
13652 printf(" Bannerfile: %s\r\n",bannerfile?bannerfile:"<none>");
13653 printf(" CDfile: %s\r\n",cdmsgfile[0]?cdmsgfile[0]:"<none>");
13654 for ( i=1;i<16 && cdmsgfile[i];i++ )
13655 printf(" CDfile: %s\r\n",cdmsgfile[i]);
13656 printf(" CDMessage: %d\r\n",srvcdmsg);
13658 printf(" DBfile: %s\r\n",dbfile?dbfile:"<none>");
13659 printf(" DBenabled: %d\r\n",dbenabled);
13663 printf(" Default-domain: %s\r\n",iks_domain?iks_domain:".");
13665 #endif /* CK_LOGIN */
13666 printf(" Helpfile: %s\r\n",helpfile?helpfile:"<none>");
13667 printf(" Initfile: %s\r\n",kermrc?kermrc:"<none>");
13668 printf(" No-Initfile: %d\r\n",noinit);
13671 printf(" Permission code: %0d\r\n",ckxperms);
13672 #endif /* CK_PERM */
13674 printf(" Privileged Login: %d\r\n",ckxpriv);
13676 #endif /* CK_LOGIN */
13677 printf(" Server-only: %d\r\n",arg_x);
13678 printf(" Syslog: %d\r\n",ckxsyslog);
13679 printf(" Timeout (seconds): %d\r\n",logintimo);
13680 printf(" Userfile: %s\r\n",userfile?userfile:"<none>");
13683 printf(" Wtmplog: %d\r\n",ckxwtmp);
13684 printf(" Wtmpfile: %s\r\n",wtmpfile?wtmpfile:"<none>");
13685 #endif /* CKWTMP */
13686 #endif /* CK_LOGIN */
13687 printf(" Xferfile: %s\r\n",xferfile?xferfile:"<none>");
13688 printf(" Xferlog: %d\r\n",xferlog);
13689 #else /* IKSDCONF */
13690 printf("?Nothing to show.\r\n");
13691 #endif /* IKSDCONF */
13692 return(success = 1);
13695 #ifdef CK_AUTHENTICATION
13697 sho_auth(cx) int cx; {
13698 extern int auth_type_user[], cmd_rows;
13701 int kv = 0, all = 0, n = 0;
13704 if (inserver && isguest) {
13705 printf("?Sorry, command disabled.\r\n");
13706 return(success = 0);
13711 } else if (auth_type_user[0] != AUTHTYPE_AUTO) {
13712 kv = auth_type_user[0];
13715 kv = AUTHTYPE_KERBEROS_V4;
13719 case AUTHTYPE_KERBEROS_V4:
13720 kv = all ? AUTHTYPE_KERBEROS_V5 : 0;
13721 if (ck_krb4_is_installed()) {
13722 printf(" Authentication: Kerberos 4\n");
13723 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13725 printf(" Authentication: Kerberos 4 (not installed)\n");
13726 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13730 printf(" Keytab file: %s\n",
13731 k4_keytab ? k4_keytab : "(none)");
13732 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13733 if (krb_action < 0) {
13736 for (p = "", i = 0; i < krb_a_n; i++) {
13737 if (krb_action == krb_a_tbl[i].kwval) {
13738 p = krb_a_tbl[i].kwd;
13743 printf(" Action: %s\n", p);
13744 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13745 printf(" Default lifetime %d\n",krb4_d_lifetime);
13746 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13747 printf(" Lifetime: %d (minutes)\n",krb4_init.lifetime);
13748 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13749 printf(" Default preauth: %d\n",krb4_d_preauth);
13750 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13751 printf(" Preauth: %d\n",krb4_init.preauth);
13752 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13753 printf(" Default principal: \"%s\"\n",
13754 krb4_d_principal ? krb4_d_principal : "");
13755 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13756 printf(" Principal: \"%s\"\n",
13757 krb4_init.principal ? krb4_init.principal : "");
13758 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13759 printf(" Default realm: \"%s\"\n",
13760 krb4_d_realm ? krb4_d_realm : "");
13761 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13762 printf(" Realm: \"%s\"\n",
13763 krb4_init.realm ? krb4_init.realm : "");
13764 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13765 printf(" Default instance: \"%s\"\n",
13766 krb4_d_instance ? krb4_d_instance : "");
13767 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13768 printf(" Instance: \"%s\"\n",
13769 krb4_init.instance ? krb4_init.instance : "");
13770 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13771 printf(" Auto-Get TGTs: %d\n",krb4_autoget);
13772 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13773 printf(" Auto-Destroy TGTs: %s\n",
13774 krb4_autodel==KRB_DEL_NO?"never":
13775 krb4_autodel==KRB_DEL_CL?"on-close":"on-exit");
13776 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13777 printf(" Check IP Addresses: %d\n",krb4_checkaddrs);
13778 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13780 printf(" Password: \"%s\"\n",
13781 krb4_init.password ? krb4_init.password : "");
13782 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13783 #endif /* COMMENT */
13784 #endif /* CK_KERBEROS */
13786 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13788 case AUTHTYPE_KERBEROS_V5:
13789 kv = all ? AUTHTYPE_SSL : 0;
13790 if (ck_krb5_is_installed()) {
13791 if (ck_gssapi_is_installed())
13792 printf(" Authentication: Kerberos 5 plus GSSAPI\n");
13794 printf(" Authentication: Kerberos 5\n");
13795 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13797 printf(" Authentication: Kerberos 5 (not installed)\n");
13798 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13803 printf(" Cache file: %s\n",
13804 krb_op.cache ? krb_op.cache : "(none)");
13805 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13806 printf(" Default cache: %s\n",
13807 krb5_d_cc ? krb5_d_cc : "(none)");
13808 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13809 printf(" Keytab file: %s\n",
13810 k5_keytab ? k5_keytab : "(none)");
13811 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13812 if (krb_action < 0) {
13815 for (p = "", i = 0; i < krb_a_n; i++) {
13816 if (krb_action == krb_a_tbl[i].kwval) {
13817 p = krb_a_tbl[i].kwd;
13822 printf(" Action: %s\n", p);
13823 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13825 printf(" Default forwardable %d\n",krb5_d_forwardable);
13826 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13827 printf(" Forwardable: %d\n",krb5_init.forwardable);
13828 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13829 printf(" Default lifetime %d\n",krb5_d_lifetime);
13830 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13831 printf(" Lifetime: %d (minutes)\n",krb5_init.lifetime);
13832 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13833 printf(" Postdate: \"%s\"\n",
13834 krb5_init.postdate ? krb5_init.postdate: "");
13835 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13836 printf(" Default proxiable: %d\n",krb5_d_proxiable);
13837 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13838 printf(" Proxiable: %d\n",krb5_init.proxiable);
13839 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13840 printf(" Renew: %d\n",krb5_init.renew);
13841 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13842 printf(" Default renewable: %d (minutes)\n",krb5_d_renewable);
13843 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13844 printf(" Renewable: %d (minutes)\n",krb5_init.renewable);
13845 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13846 printf(" Service: \"%s\"\n",
13847 krb5_init.service ? krb5_init.service : "");
13848 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13849 printf(" Validate: %d\n",krb5_init.validate);
13850 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13851 printf(" Default principal: \"%s\"\n",
13852 krb5_d_principal ? krb5_d_principal : "");
13853 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13854 printf(" Principal: \"%s\"\n",
13855 krb5_init.principal ? krb5_init.principal : "");
13856 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13857 printf(" Default instance: \"%s\"\n",
13858 krb5_d_instance ? krb5_d_instance : "");
13859 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13860 printf(" Default realm: \"%s\"\n",
13861 krb5_d_realm ? krb5_d_realm : "");
13862 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13863 printf(" Realm: \"%s\"\n",
13864 krb5_init.realm ? krb5_init.realm : "");
13865 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13866 printf(" Auto-Get TGTs: %d\n",krb5_autoget);
13867 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13868 printf(" Auto-Destroy TGTs: %s\n",
13869 krb5_autodel==KRB_DEL_NO?"never":
13870 krb5_autodel==KRB_DEL_CL?"on-close":"on-exit");
13871 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13872 printf(" Default get K4 TGTs: %d\n",krb5_d_getk4);
13873 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13874 printf(" Get K4 TGTs: %d\n",krb5_init.getk4);
13875 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13876 printf(" Check IP Addresses: %d\n",krb5_checkaddrs);
13877 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13878 printf(" No IP Addresses: %d\n",krb5_d_no_addresses);
13879 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13880 printf(" IP-Addresses: ");
13881 if (krb5_init.addrs && krb5_init.addrs[0]) {
13882 for (i = 0; krb5_init.addrs[i]; i++) {
13885 printf("%s",krb5_init.addrs[i]);
13887 } else if (krb5_d_addrs[0]) {
13888 for (i = 0;i < KRB5_NUM_OF_ADDRS && krb5_d_addrs[i];i++) {
13891 printf("%s",krb5_d_addrs[i]);
13894 printf("(use default)");
13897 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13899 printf(" Password: \"%s\"\n",
13900 krb5_init.password ? krb5_init.password : "");
13901 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13902 #endif /* COMMENT */
13903 #endif /* CK_KERBEROS */
13905 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13908 kv = all ? AUTHTYPE_SRP : 0;
13909 if (ck_ssleay_is_installed()) {
13910 printf(" Authentication: SSL/TLS (%s)\n",
13911 SSLeay_version(SSLEAY_VERSION));
13912 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13914 printf(" Authentication: SSL/TLS (not installed)\n");
13915 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13920 printf(" RSA Certs file: %s\n",ssl_rsa_cert_file?
13921 ssl_rsa_cert_file:"(none)");
13922 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13923 printf(" RSA Certs Chain file: %s\n",ssl_rsa_cert_chain_file?
13924 ssl_rsa_cert_chain_file:"(none)");
13925 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13926 printf(" RSA Key file: %s\n",ssl_rsa_key_file?
13927 ssl_rsa_key_file:"(none)");
13928 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13929 printf(" DSA Certs file: %s\n",ssl_dsa_cert_file?
13930 ssl_dsa_cert_file:"(none)");
13931 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13932 printf(" DSA Certs Chain file: %s\n",ssl_dsa_cert_chain_file?
13933 ssl_dsa_cert_chain_file:"(none)");
13934 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13935 printf(" DH Key file: %s\n",ssl_dh_key_file?
13936 ssl_dh_key_file:"(none)");
13937 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13938 printf(" DH Param file: %s\n",ssl_dh_param_file?
13939 ssl_dh_param_file:"(none)");
13940 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13941 printf(" CRL file: %s\n",ssl_crl_file?
13942 ssl_crl_file:"(none)");
13943 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13944 printf(" CRL dir: %s\n",ssl_crl_dir?
13945 ssl_crl_dir:"(none)");
13946 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13947 printf(" Random file: %s\n",ssl_rnd_file?
13948 ssl_rnd_file:"(none)");
13949 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13950 printf(" Verify file: %s\n",ssl_verify_file?
13951 ssl_verify_file:"(none)");
13952 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13953 printf(" Verify dir: %s\n",ssl_verify_dir?
13954 ssl_verify_dir:"(none)");
13955 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13956 printf(" Cipher list: %s\n",ssl_cipher_list ? ssl_cipher_list :
13957 DEFAULT_CIPHER_LIST);
13958 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13959 if (ssl_con == NULL) {
13960 SSL_library_init();
13961 ssl_ctx = (SSL_CTX *)
13962 SSL_CTX_new((SSL_METHOD *)TLSv1_method());
13963 if (ssl_ctx != NULL)
13964 ssl_con= (SSL *) SSL_new(ssl_ctx);
13966 if (ssl_con != NULL) {
13970 for (i = 0; ; i++) {
13971 p = (CHAR *) SSL_get_cipher_list(ssl_con,i);
13975 if (++n > cmd_rows - 3)
13976 if (!askmore()) return(0); else n = 0;
13979 printf(" Certs OK? %s\n",ssl_certsok_flag? "yes" : "no");
13980 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13981 printf(" Debug mode: %s\n", ssl_debug_flag ? "on" : "off");
13982 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13983 printf(" Verbose mode: %s\n", ssl_verbose_flag ? "on" : "off");
13984 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13985 printf(" Verify mode: %s\n",
13986 ssl_verify_flag == SSL_VERIFY_NONE ? "none" :
13987 ssl_verify_flag == SSL_VERIFY_PEER ? "peer-cert" :
13988 "fail-if-no-peer-cert");
13989 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13990 printf(" SSL only? %s\n", ssl_only_flag ? "yes" : "no");
13991 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13992 printf(" TLS only? %s\n", tls_only_flag ? "yes" : "no");
13993 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13994 #endif /* CK_SSL */
13996 case AUTHTYPE_NTLM:
13998 if (ck_ntlm_is_installed()) {
13999 printf(" Authentication: NTLM\n");
14000 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14001 printf(" No options\n");
14002 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14004 printf(" Authentication: NTLM (not installed)\n");
14005 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14009 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14012 kv = all ? AUTHTYPE_NTLM : 0;
14013 if (ck_srp_is_installed()) {
14014 if (ck_krypto_is_installed())
14015 printf(" Authentication: SRP plus Krypto API\n");
14017 printf(" Authentication: SRP\n");
14018 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14019 printf(" No options\n");
14020 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14022 printf(" Authentication: SRP (not installed)\n");
14023 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14027 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
14031 return(success = 1);
14033 #endif /* CK_AUTHENTICATION */
14034 #endif /* NOSHOW */
14038 /* C P _ A U T H -- AUTHENTICATE command parsing */
14041 cp_auth() { /* Command_Parse AUTHENTICATE */
14042 int c, i, n; /* Workers */
14043 int rc = 0; /* Return code */
14044 int getval; /* Parsing helpers */
14045 int tmpauth = 0; /* Temporary authentication type */
14046 int kv = 0; /* Temporary Kerberos version */
14047 int tmp_action = -1; /* Temporary Kerberos action */
14048 int tmp_klc = 0; /* Temporary list-credentials */
14049 char tmphlp[256]; /* For building help message */
14051 char * tmppswd = NULL; /* Password */
14052 char * tmpprinz = NULL; /* Principal */
14053 char * tmprealm = NULL; /* Realm */
14054 char * tmpcache = NULL; /* Cache file */
14055 char * tmpinst = NULL; /* K4 Instance */
14056 char * tmpaddrs[KRB5_NUM_OF_ADDRS];
14058 extern int on_recall; /* around Password prompting */
14059 #endif /* CK_RECALL */
14060 struct stringint { /* Temporary array for switch values */
14061 char * sval; /* String value */
14062 int ival; /* Integer value */
14063 } pv[KRB_I_MAX+1]; /* This many */
14064 struct FDB kw, sw, fl; /* FDBs for each parse function */
14066 krb_action = -1; /* Initialize Kerberos action. */
14067 tmp_action = -1; /* And our local copy. */
14068 for (i = 0; i < KRB5_NUM_OF_ADDRS; i++)
14069 tmpaddrs[i] = NULL;
14071 if ((y = cmkey(kerbtab,kerbtabn,"authentication type","",xxstring)) < 0)
14074 printf("?Authentication type not specified - nothing happens\n");
14078 debug(F101,"kerberos authentication","",tmpauth);
14080 case AUTH_KRB4: kv = 4; break; /* Don't assume values are the same */
14081 case AUTH_KRB5: kv = 5; break;
14083 printf("?Authentication type not supported: \"%s\"\n",atmbuf);
14087 /* From here down is Kerberos */
14088 ini_kerb(); /* Reset Init data to defaults */
14090 if (kv == 4) { /* Set K4 defaults */
14092 makestr(&tmprealm,krb4_d_realm);
14093 if (krb4_d_principal)
14094 makestr(&tmpprinz,krb4_d_principal);
14095 if (krb4_d_instance)
14096 makestr(&tmpinst,krb4_d_instance);
14097 } else if (kv == 5) { /* Set K5 defaults */
14099 makestr(&tmpcache,krb5_d_cc);
14101 makestr(&tmprealm,krb5_d_realm);
14102 if (krb5_d_principal)
14103 makestr(&tmpprinz,krb5_d_principal);
14104 if (krb5_d_instance)
14105 makestr(&tmpinst,krb5_d_instance);
14108 for (i = 0; i <= KRB_I_MAX; i++) { /* Initialize switch values */
14109 pv[i].sval = NULL; /* to null pointers */
14110 pv[i].ival = 0; /* and 0 int values */
14113 if (kv == 4) { /* Kerberos 4 */
14114 pv[KRB_I_LF].ival = krb4_d_lifetime;
14115 pv[KRB_I_PA].ival = krb4_d_preauth;
14117 if ((n = cmkey(krb_a_tbl,krb_a_n,"Kerberos 4 action","",xxstring)) < 0)
14120 printf("?Action not specified - nothing happens.\n");
14123 } else if (kv == 5) { /* Kerberos 5 */
14124 pv[KRB_I_FW].ival = krb5_d_forwardable;
14125 pv[KRB_I_PR].ival = krb5_d_proxiable;
14126 pv[KRB_I_LF].ival = krb5_d_lifetime;
14127 pv[KRB_I_RB].ival = krb5_d_renewable;
14128 pv[KRB_I_K4].ival = krb5_d_getk4;
14129 pv[KRB_I_NAD].ival = krb5_d_no_addresses;
14131 /* Make help message that shows switches and action keywords */
14132 ckstrncpy(tmphlp,"Kerberos 5 action, one of the following:\n ",256);
14133 for (i = 0; i < krb_a_n; i++) {
14134 ckstrncat(tmphlp,krb_a_tbl[i].kwd,sizeof(tmphlp));
14135 if (i == krb_a_n - 1)
14136 ckstrncat(tmphlp,"\nor switch",sizeof(tmphlp));
14138 ckstrncat(tmphlp," ",sizeof(tmphlp));
14140 /* Set up first set of chained FDB's */
14142 cmfdbi(&sw, /* First FDB - command switches */
14143 _CMKEY, /* fcode */
14144 tmphlp, /* hlpmsg */
14145 "", /* default (none) */
14146 "", /* addtl string data */
14147 krb_s_n, /* Switch table size */
14148 4, /* addtl numeric data 2: 4 = cmswi */
14149 xxstring, /* Processing function */
14150 krb_s_tbl, /* Switch table */
14151 &kw /* Pointer to next FDB */
14153 cmfdbi(&kw, /* Second FDB - action keywords */
14154 _CMKEY, /* fcode */
14155 "Kerberos action", /* hlpmsg */
14156 "", /* default (none) */
14157 "", /* addtl string data */
14158 krb_a_n, /* Switch table size */
14159 0, /* addtl num data (0 = NOT switch) */
14160 xxstring, /* Processing function */
14161 krb_a_tbl, /* Keyword table */
14162 NULL /* Pointer to next FDB (none) */
14167 while (1) { /* Parse 0 or more switches */
14168 rc = cmfdb(&sw); /* Parse something */
14169 debug(F101,"kerberos cmfdb 1 rc","",rc);
14170 if (rc < 0) { /* Error */
14172 printf("?Action not specified - nothing happens.\n");
14173 return(rc); /* or reparse needed */
14175 if (cmresult.fdbaddr != &sw) /* Break out if not a switch */
14177 c = cmgbrk(); /* Have switch - get break character */
14178 getval = (c == ':' || c == '='); /* Must parse an agument? */
14179 if (getval && !(cmresult.kflags & CM_ARG)) {
14180 printf("?This switch does not take arguments\n");
14181 return(-9); /* OK because nothing malloc'd yet */
14183 if (!getval && (cmgkwflgs() & CM_ARG)) {
14184 printf("?This switch requires an argument\n");
14187 n = cmresult.nresult; /* Numeric result = switch value */
14188 debug(F101,"kerberos command switch","",n);
14190 switch (n) { /* Handle the switch */
14191 case KRB_S_CA: /* /CACHE:<filename> */
14192 p = krb5_d_cc ? krb5_d_cc : "";
14193 if ((y = cmofi("Name of cache file",p,&s,xxstring)) < 0) {
14199 makestr(&tmpcache,s);
14202 printf("?Unexpected switch value - internal error\n");
14203 return(-9); /* (if) nothing malloc'd yet. */
14206 if (cmresult.fdbaddr != &kw) { /* Checking... */
14207 printf("?Unexpected result - internal error\n");
14208 return(-9); /* Nothing malloc'd yet. */
14210 n = cmresult.nresult; /* Get keyword value */
14212 printf("?Unexpected Kerberos version - Internal error\n");
14215 debug(F101,"kerberos action","",n);
14217 case KRB_A_IN: /* INITIALIZE */
14218 case KRB_A_DE: /* DESTROY */
14219 case KRB_A_LC: /* LIST-CREDENTIALS */
14220 tmp_action = n; /* OK, set */
14222 default: /* Not OK, punt. */
14223 printf("?Unexpected action - internal error\n");
14226 if (tmp_action == KRB_A_IN) { /* Action is INITIALIZE */
14228 cmfdbi(&sw, /* INITIALIZE switches */
14229 _CMKEY, /* fcode */
14230 "Principal,\n or optional INITIALIZE switch(es)", /* hlpmsg */
14231 "", /* default (none) */
14232 "", /* addtl string data */
14233 kv == 4 ? krb4_i_n : krb5_i_n, /* Switch table size */
14234 4, /* addtl numeric data 2: 4 = cmswi */
14235 xxstring, /* Processing function */
14236 kv == 4 ? krb4_i_tbl : krb5_i_tbl, /* Switch table */
14237 &fl /* Pointer to next FDB */
14239 cmfdbi(&fl, /* 3rd FDB - command to send from */
14240 _CMFLD, /* fcode */
14241 "Principal", /* hlpmsg */
14242 kv == 4 ? krb4_d_principal : krb5_d_principal, /* principal */
14243 "", /* addtl string data */
14244 0, /* addtl numeric data 1 */
14245 0, /* addtl numeric data 2 */
14250 while (1) { /* Parse INIT switches or principal */
14252 debug(F101,"kerberos cmfdb 2 rc","",rc);
14255 printf("?Principal name required\n");
14258 debug(F101,"kerberos cmfdb 2 fcode","",cmresult.fcode);
14259 if (cmresult.fcode != _CMKEY) /* Not a switch, quit switch loop */
14261 c = cmgbrk(); /* Switch - get break character */
14262 debug(F101,"kerberos cmfdb 2 cmgbrk","",c);
14263 getval = (c == ':' || c == '=');
14264 if (getval && !(cmresult.kflags & CM_ARG)) {
14265 printf("?This switch does not take arguments\n");
14266 return(-9); /* OK because nothing malloc'd yet */
14268 if (!getval && (cmgkwflgs() & CM_ARG)) {
14269 printf("?This switch requires an argument\n");
14272 n = cmresult.nresult; /* Numeric result = switch value */
14274 /* These don't take args... */
14275 case KRB_I_PA: /* /PREAUTH */
14276 case KRB_I_FW: /* /FORWARDABLE */
14277 case KRB_I_PR: /* /PROXIABLE */
14278 case KRB_I_RN: /* /RENEW */
14279 case KRB_I_VA: /* /VALIDATE */
14280 case KRB_I_NPA: /* /NOT-PREAUTH */
14281 case KRB_I_NFW: /* /NOT-FORWARDABLE */
14282 case KRB_I_NPR: /* /NOT-PROXIABLE */
14283 case KRB_I_VB: /* /VERBOSE */
14284 case KRB_I_BR: /* /BRIEF */
14285 case KRB_I_K4: /* /KERBEROS4 */
14286 case KRB_I_NK4: /* /NO-KERBEROS4 */
14287 case KRB_I_POP: /* /POPUP */
14288 case KRB_I_NAD: /* /NO-ADDRESSES */
14290 printf("?This switch does not take a value\n");
14296 pv[KRB_I_PA].ival = 0;
14299 pv[KRB_I_FW].ival = 0;
14302 pv[KRB_I_PR].ival = 0;
14305 pv[KRB_I_BR].ival = 0;
14308 pv[KRB_I_K4].ival = 0;
14315 /* These do take arguments */
14317 case KRB_I_RB: /* /RENEWABLE:<minutes> */
14319 if (!getval) break;
14320 if ((rc = cmnum("Minutes",ckitoa(krb5_init.renewable),
14321 10,&y, xxstring)) < 0)
14326 case KRB_I_LF: /* /LIFETIME:<minutes> */
14328 /* Default is previous value */
14329 sprintf(tmpbuf,"%d", /* SAFE */
14331 krb4_init.lifetime :
14334 if (!getval) break;
14335 if ((rc = cmnum("Minutes",tmpbuf,10,&y, xxstring)) < 0)
14340 case KRB_I_PD: /* /POSTDATE:<timestamp> */
14345 if (!getval) break;
14346 if ((rc = cmdate("date-time","",&s,0,xxstring)) < 0)
14348 makestr(&(pv[n].sval),s);
14351 case KRB_I_SR: /* /SERVICE:<name> */
14356 if (!getval) break;
14357 if ((rc = cmfld("Service-name","",&s,xxstring)) < 0)
14359 makestr(&(pv[n].sval),s);
14362 case KRB_I_RL: /* /REALM:<name> */
14367 if (!getval) break;
14369 p = krb4_d_realm ? krb4_d_realm : "";
14371 p = krb5_d_realm ? krb5_d_realm : "";
14372 if ((rc = cmfld("Realm",p,&s,xxstring)) < 0)
14374 makestr(&(pv[n].sval),s);
14377 case KRB_I_IN: /* /INSTANCE:<name> */
14382 if (!getval) break;
14384 p = krb4_d_instance ? krb4_d_instance : "";
14386 p = krb5_d_instance ? krb5_d_instance : "";
14387 if ((rc = cmfld("Instance",p,&s,xxstring)) < 0)
14389 makestr(&(pv[n].sval),s);
14392 case KRB_I_PW: /* /PASSWORD:<password> */
14398 if (!getval) break;
14399 if ((rc = cmfld("Password","",&s,xxstring)) < 0)
14402 makestr(&(pv[n].sval),s);
14405 case KRB_I_ADR: /* /ADDRESSES:{<address-list>} */
14410 if (!getval) break;
14411 if ((rc = cmfld("List of IP addresses","",&s,xxstring)) < 0)
14413 makelist(s,tmpaddrs,KRB5_NUM_OF_ADDRS);
14414 for (i = 0; i < KRB5_NUM_OF_ADDRS && tmpaddrs[i]; i++) {
14415 if (inet_addr(tmpaddrs[i]) == 0xffffffff) {
14416 printf("invalid ip address: %s\n",tmpaddrs[i]);
14421 pv[KRB_I_NAD].ival = 0;
14425 printf("?Unexpected switch value - internal error\n");
14430 if (cmresult.fcode != _CMFLD) {
14431 printf("?Unexected result - internal error\n");
14435 /* cmresult.sresult may be of the form PRINCIPAL@REALM */
14436 i = ckindex("@",cmresult.sresult,0,0,0);
14438 makestr(&tmprealm,&cmresult.sresult[i]);
14439 cmresult.sresult[i-1] = '\0';
14441 makestr(&tmpprinz,cmresult.sresult); /* Principal (user) */
14443 if ((rc = cmcfm()) < 0) { /* Now get confirmation */
14445 printf("?Principal name required\n");
14449 if (!tmpprinz || !tmpprinz[0]) {
14450 printf("?Principal name required\n");
14453 if (!pv[KRB_I_RN].ival && !pv[KRB_I_VA].ival) {
14454 /* Don't use a password if Validating or Renewing */
14455 if (pv[KRB_I_PW].sval) { /* If they gave a /PASSWORD switch */
14456 makestr(&tmppswd,pv[KRB_I_PW].sval); /* use this value */
14459 /* Password prompting has been moved to ck_krb[45]_initTGT() */
14460 else { /* Otherwise must prompt for it */
14462 if (pv[KRB_I_RL].sval)
14463 sprintf(prmpt,"%s@%s's Password: ",
14464 tmpprinz,pv[KRB_I_RL].sval);
14466 sprintf(prmpt,"%s@%s's Password: ",
14467 tmpprinz,tmprealm);
14469 sprintf(prmpt,"%s's Password: ",tmpprinz);
14471 if (pv[KRB_I_POP].ival) {
14472 char passwd[80]="";
14473 readpass(prmpt,passwd,80);
14474 makestr(&tmppswd,passwd);
14475 memset(passwd,0,80);
14481 #endif /* CK_RECALL */
14482 cmsavp(psave,PROMPTL); /* Save old prompt */
14483 cmsetp(prmpt); /* Make new prompt */
14484 concb((char)escape); /* Put console in cbreak mode */
14485 cmini(0); /* and no-echo mode */
14486 /* Issue prompt if at top level */
14487 if (pflag) prompt(xxstring);
14488 cmres(); /* Reset the parser */
14489 for (rc = -1; rc < 0; ) { /* Prompt till they answer */
14490 /* Get a literal line of text */
14491 rc = cmtxt("","",&s,NULL);
14492 cmres(); /* Reset the parser again */
14494 makestr(&tmppswd,s);
14495 printf("\n"); /* Echo a CRLF */
14496 cmsetp(psave); /* Restore original prompt */
14499 x = 0; /* Check for password */
14504 printf("?Password required\n");
14507 #endif /* COMMENT */
14509 } else if (kv == 5 && tmp_action == KRB_A_LC) { /* LIST-CREDENTIALS */
14512 if ((x = cmkey(klctab,nklctab,"Switch","",xxstring)) < 0) {
14514 if ((rc = cmcfm()) < 0)
14525 } else if ((rc = cmcfm()) < 0) /* DESTROY, just confirm */
14528 /* Done - Move confirmed data to final locations */
14530 krb_action = tmp_action; /* Action requested */
14531 krb_op.version = kv; /* Kerberos version */
14532 krb_op.cache = tmpcache; /* Cache file */
14533 tmpcache = NULL; /* So we don't free it */
14535 switch (krb_action) {
14536 case KRB_A_IN: /* INITIALIZE */
14538 krb5_init.forwardable = pv[KRB_I_FW].ival;
14539 krb5_init.proxiable = pv[KRB_I_PR].ival;
14540 krb5_init.lifetime = pv[KRB_I_LF].ival;
14541 krb5_init.renew = pv[KRB_I_RN].ival;
14542 krb5_init.renewable = pv[KRB_I_RB].ival;
14543 krb5_init.validate = pv[KRB_I_VA].ival;
14545 /* Here we just reassign the pointers and then set them to NULL */
14546 /* so they won't be freed below. */
14548 krb5_init.postdate = pv[KRB_I_PD].sval; pv[KRB_I_PD].sval = NULL;
14549 krb5_init.service = pv[KRB_I_SR].sval; pv[KRB_I_SR].sval = NULL;
14550 if (pv[KRB_I_RL].sval) {
14551 krb5_init.realm = pv[KRB_I_RL].sval; pv[KRB_I_RL].sval = NULL;
14552 } else if (tmprealm) {
14553 krb5_init.realm = tmprealm; tmprealm = NULL;
14555 if (pv[KRB_I_IN].sval) {
14556 krb5_init.instance = pv[KRB_I_IN].sval;
14557 pv[KRB_I_IN].sval = NULL;
14558 } else if ( tmpinst ) {
14559 krb5_init.instance = tmpinst;
14563 krb5_init.principal = tmpprinz;
14566 krb5_init.password = tmppswd;
14569 krb5_init.getk4 = pv[KRB_I_K4].ival;
14570 if (krb5_init.getk4) {
14571 krb4_init.lifetime = pv[KRB_I_LF].ival;
14572 if (krb5_init.realm)
14573 makestr(&krb4_init.realm,krb5_init.realm);
14574 krb4_init.preauth = krb4_d_preauth;
14575 krb4_init.verbose = pv[KRB_I_BR].ival ? 0 : 1;
14576 if (krb5_init.principal)
14577 makestr(&krb4_init.principal,krb5_init.principal);
14578 if (krb5_init.principal)
14579 makestr(&krb4_init.password,krb5_init.password);
14581 krb5_init.no_addresses = pv[KRB_I_NAD].ival;
14583 for (i = 0; i < KRB5_NUM_OF_ADDRS; i++) {
14584 if (krb5_init.addrs[i]) {
14585 free(krb5_init.addrs[i]);
14586 krb5_init.addrs[i] = NULL;
14588 krb5_init.addrs[i] = tmpaddrs[i];
14589 tmpaddrs[i] = NULL;
14592 } else if (kv == 4) { /* Same deal for Kerberos 4 */
14593 krb4_init.lifetime = pv[KRB_I_LF].ival;
14594 if (pv[KRB_I_RL].sval) {
14595 krb4_init.realm = pv[KRB_I_RL].sval;
14596 pv[KRB_I_RL].sval = NULL;
14597 } else if ( tmprealm ) {
14598 krb4_init.realm = tmprealm;
14601 if (pv[KRB_I_IN].sval) {
14602 krb4_init.instance = pv[KRB_I_IN].sval;
14603 pv[KRB_I_IN].sval = NULL;
14604 } else if ( tmpinst ) {
14605 krb4_init.instance = tmpinst;
14608 krb4_init.preauth = pv[KRB_I_PA].ival;
14609 krb4_init.verbose = pv[KRB_I_BR].ival ? 0 : 1;
14612 krb4_init.principal = tmpprinz;
14615 krb4_init.password = tmppswd;
14619 case KRB_A_LC: /* List Credentials */
14620 krb5_lc.encryption = tmp_klc & XYKLCEN;
14621 krb5_lc.flags = tmp_klc & XYKLCFL;
14622 krb5_lc.addr = tmp_klc & XYKLCAD;
14626 /* Common exit - Free temporary storage */
14629 for (i = 0; i <= KRB_I_MAX; i++) { /* Free malloc'd switch data */
14633 for (i = 0; i < KRB5_NUM_OF_ADDRS; i++) {
14637 if (tmpprinz) free(tmpprinz); /* And these too. */
14638 if (tmppswd) free(tmppswd);
14639 if (tmpcache) free(tmpcache);
14640 if (tmprealm) free(tmprealm);
14641 if (tmpinst) free(tmpinst);
14643 return(rc); /* Return the return code */
14645 #endif /* CK_KERBEROS */
14650 ckxlogin(CHAR * userid, CHAR * passwd, CHAR * acct, int promptok)
14651 #else /* CK_ANSIC */
14652 ckxlogin(userid, passwd, acct, promptok)
14653 CHAR * userid; CHAR * passwd; CHAR * acct; int promptok;
14654 #endif /* CK_ANSIC */
14657 extern int on_recall; /* around Password prompting */
14658 #endif /* CK_RECALL */
14661 #endif /* CK_PAM */
14662 int rprompt = 0; /* Restore prompt */
14665 #endif /* CKSYSLOG */
14667 extern int what, srvcdmsg;
14669 int x = 0, ok = 0, rc = 0;
14670 CHAR * _u = NULL, * _p = NULL, * _a = NULL;
14672 debug(F111,"ckxlogin userid",userid,promptok);
14673 debug(F110,"ckxlogin passwd",passwd,0);
14675 isguest = 0; /* Global "anonymous" flag */
14677 if (!userid) userid = (CHAR *)"";
14678 if (!passwd) passwd = (CHAR *)"";
14680 debug(F111,"ckxlogin userid",userid,what);
14684 #endif /* CK_RECALL */
14687 savlog = ckxsyslog; /* Save and turn off syslogging */
14688 #endif /* CKSYSLOG */
14690 if ((!*userid || !*passwd) && /* Need to prompt for missing info */
14692 cmsavp(psave,PROMPTL); /* Save old prompt */
14693 debug(F110,"ckxlogin saved",psave,0);
14699 cmsetp("Username: "); /* Make new prompt */
14700 concb((char)escape); /* Put console in cbreak mode */
14703 /* Flush typeahead */
14707 "ckxlogin TELOPT_SB(TELOPT_KERMIT).kermit.me_start",
14709 TELOPT_SB(TELOPT_KERMIT).kermit.me_start
14711 #endif /* IKS_OPTION */
14713 while (ttchk() > 0) {
14715 debug(F101,"ckxlogin flush user x","",x);
14717 doexit(GOOD_EXIT,0); /* Connection lost */
14721 x = tn_doop((CHAR)(x & 0xff),ckxech,ttinc);
14722 debug(F101,"ckxlogin user tn_doop","",x);
14725 "ckxlogin user TELOPT_SB(TELOPT_KERMIT).kermit.me_start",
14727 TELOPT_SB(TELOPT_KERMIT).kermit.me_start
14729 #endif /* IKS_OPTION */
14734 case 1: ckxech = 1; break; /* Turn on echoing */
14735 case 2: ckxech = 0; break; /* Turn off echoing */
14737 case 4: /* IKS event */
14738 if (!TELOPT_SB(TELOPT_KERMIT).kermit.me_start)
14739 break; /* else fall thru... */
14740 #endif /* IKS_OPTION */
14741 case 6: /* Logout */
14746 #endif /* TNCODE */
14748 if (pflag) prompt(xxstring); /* Issue prompt if at top level */
14749 cmres(); /* Reset the parser */
14750 for (x = -1; x < 0;) { /* Prompt till they answer */
14751 /* Get a literal line of text */
14752 x=cmtxt("Your username, or \"ftp\", or \"anonymous\"","",&s,NULL);
14753 if (x == -4 || x == -10) {
14754 printf("\r\n%sLogin cancelled\n",
14755 x == -10 ? "Timed out: " : "");
14757 ckxsyslog = savlog;
14758 #endif /* CKSYSLOG */
14759 doexit(GOOD_EXIT,0);
14761 if (sstate) /* Did a packet come instead? */
14763 cmres(); /* Reset the parser again */
14765 if ((_u = (CHAR *)malloc((int)strlen(s) + 1)) == NULL) {
14766 printf("?Internal error: malloc\n");
14769 strcpy((char *)_u,s); /* safe */
14773 ok = zvuser((char *)userid); /* Verify username */
14774 debug(F111,"ckxlogin zvuser",userid,ok);
14776 if (!*passwd && promptok
14779 #endif /* CK_PAM */
14784 savlog = ckxsyslog; /* Save and turn off syslogging */
14786 #endif /* CKSYSLOG */
14788 /* Flush typeahead again */
14790 while (ttchk() > 0) {
14792 debug(F101,"ckxlogin flush user x","",x);
14796 x = tn_doop((CHAR)(x & 0xff),ckxech,ttinc);
14797 debug(F101,"ckxlogin pass tn_doop","",x);
14800 "ckxlogin pass TELOPT_SB(TELOPT_KERMIT).kermit.me_start",
14802 TELOPT_SB(TELOPT_KERMIT).kermit.me_start
14804 #endif /* IKS_OPTION */
14808 case 1: ckxech = 1; break; /* Turn on echoing */
14809 case 2: ckxech = 0; break; /* Turn off echoing */
14810 case 4: /* IKS event */
14811 if (!TELOPT_SB(TELOPT_KERMIT).kermit.me_start)
14812 break; /* else fall thru... */
14813 case 6: /* Logout */
14818 #endif /* TNCODE */
14820 if (!strcmp((char *)userid,"anonymous") ||
14821 !strcmp((char *)userid,"ftp")) {
14824 ckstrncpy(prmpt,"Enter e-mail address as Password: ",80);
14825 } else if (*userid && strlen((char *)userid) < 60) {
14827 extern CHAR * pReferenceDomainName;
14828 if (pReferenceDomainName)
14832 pReferenceDomainName,
14836 NULL,NULL,NULL,NULL,NULL,NULL,NULL
14840 ckmakmsg(prmpt,80,"Enter ",(char *)userid,"'s Password: ",NULL);
14842 ckstrncpy(prmpt,"Enter Password: ",80);
14843 cmsetp(prmpt); /* Make new prompt */
14844 concb((char)escape); /* Put console in cbreak mode */
14845 if (strcmp((char *)userid,"anonymous") &&
14846 strcmp((char *)userid,"ftp")) { /* and if not anonymous */
14848 cmini(0); /* and no-echo mode */
14852 if (pflag) prompt(xxstring); /* Issue prompt if at top level */
14853 cmres(); /* Reset the parser */
14854 for (x = -1; x < 0;) { /* Prompt till they answer */
14855 x = cmtxt("","",&s,NULL); /* Get a literal line of text */
14856 if (x == -4 || x == -10) {
14857 printf("\r\n%sLogin cancelled\n",
14858 x == -10 ? "Timed out: " : "");
14860 ckxsyslog = savlog;
14861 #endif /* CKSYSLOG */
14862 doexit(GOOD_EXIT,0);
14864 if (sstate) /* In case of a Kermit packet */
14866 cmres(); /* Reset the parser again */
14868 printf("\r\n"); /* Echo a CRLF */
14869 if ((_p = (CHAR *)malloc((int)strlen(s) + 1)) == NULL) {
14870 printf("?Internal error: malloc\n");
14873 strcpy((char *)_p,s); /* safe */
14879 cmres(); /* Reset the parser */
14881 /* We restore the prompt now because the PAM engine will call */
14882 /* readpass() which will overwrite psave. */
14884 cmsetp(psave); /* Restore original prompt */
14885 debug(F110,"ckxlogin restored",psave,0);
14889 #endif /* CK_PAM */
14892 ckxsyslog = savlog;
14893 #endif /* CKSYSLOG */
14896 ok = zvpass((char *)passwd); /* Check password */
14897 debug(F101,"ckxlogin zvpass","",ok);
14900 if (ok > 0 && isguest) {
14903 #endif /* NOPUSH */
14906 rc = ok; /* Set the return code */
14907 if ((char *)uidbuf != (char *)userid)
14908 ckstrncpy(uidbuf,(char *)userid,UIDBUFLEN); /* Remember username */
14910 XCKXLOG: /* Common exit */
14912 ckxsyslog = savlog; /* In case of GOTO above */
14913 #endif /* CKSYSLOG */
14915 cmsetp(psave); /* Restore original prompt */
14916 debug(F110,"ckxlogin restored",psave,0);
14918 if (_u || _p || _a) {
14928 doexit(GOOD_EXIT,0); /* doexit calls zvlogout */
14929 return(0); /* not reached */
14931 #endif /* CK_LOGIN */