source: trunk/third/kermit/ckuus7.c @ 10780

Revision 10780, 161.3 KB checked in by brlewis, 27 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r10779, which included commits to RCS files with non-trunk default branches.
Line 
1#include "ckcsym.h"
2#ifndef NOICP
3
4/*  C K U U S 7 --  "User Interface" for C-Kermit, part 7  */
5 
6/*
7  Author: Frank da Cruz <fdc@columbia.edu>,
8  Columbia University Academic Information Systems, New York City.
9
10  Copyright (C) 1985, 1996, Trustees of Columbia University in the City of New
11  York.  The C-Kermit software may not be, in whole or in part, licensed or
12  sold for profit as a software product itself, nor may it be included in or
13  distributed with commercial products or otherwise distributed by commercial
14  concerns to their clients or customers without written permission of the
15  Office of Kermit Development and Distribution, Columbia University.  This
16  copyright notice must not be removed, altered, or obscured.
17*/
18 
19/*
20  This file created from parts of ckuus3.c, which became to big for
21  Mark Williams Coherent compiler to handle.
22*/
23
24/*
25  Definitions here supersede those from system include files.
26*/
27#include "ckcdeb.h"                     /* Debugging & compiler things */
28#include "ckcasc.h"                     /* ASCII character symbols */
29#include "ckcker.h"                     /* Kermit application definitions */
30#include "ckcxla.h"                     /* Character set translation */
31#include "ckcnet.h"                     /* Network symbols */
32#include "ckuusr.h"                     /* User interface symbols */
33#include "ckucmd.h"
34#ifdef CKOUNI
35#include "ckouni.h"
36#endif /* CKOUNI */
37
38#ifdef OS2
39#ifndef NT
40#define INCL_NOPM
41#define INCL_VIO            /* needed for ckocon.h */
42#define INCL_DOSMODULEMGR
43#include <os2.h>
44#undef COMMENT
45#else /* NT */
46#define APIRET ULONG
47#include "cknwin.h"
48#include "ckntap.h"
49#endif /* NT */
50#include "ckowin.h"
51#include "ckocon.h"
52#include "ckodir.h"
53#ifdef OS2MOUSE
54#include "ckokey.h"
55#endif /* OS2MOUSE */
56#ifdef KUI
57#include "ikui.h"
58#endif /* KUI */
59#ifdef putchar
60#undef putchar
61#endif /* putchar */
62#define putchar(x) conoc(x)
63extern int mskkeys;
64#endif /* OS2 */   
65
66#ifdef STRATUS                          /* Stratus Computer, Inc.  VOS */
67#ifdef putchar
68#undef putchar
69#endif /* putchar */
70#define putchar(x) conoc(x)
71#ifdef getchar
72#undef getchar
73#endif /* getchar */
74#define getchar(x) coninc(0)
75#endif /* STRATUS */
76
77static int x, y = 0, z;
78static char *s;
79
80#ifdef CK_SPEED
81extern short ctlp[];                    /* Control-char prefixing table */
82#endif /* CK_SPEED */
83
84#ifdef NETCONN
85extern struct keytab netcmd[];
86#ifndef NODIAL
87extern int dirline;
88extern int nnets, nnetdir;              /* Network services directory */
89extern char *netdir[];
90_PROTOTYP( VOID ndinit, (void) );
91_PROTOTYP( VOID ndreset, (void) );
92char *nh_p[MAXDNUMS + 1];               /* Network directory entry pointers */
93char *nh_p2[MAXDNUMS + 1];              /* Network directory entry nettype */
94char *nh_px[4][MAXDNUMS + 1];           /* Network-specific stuff... */
95#endif /* NODIAL */
96int nhcount = 0;
97int ndinited = 0;
98char * n_name = NULL;                   /* Network name pointer */
99static int oldplex = -1;                /* Duplex holder around network */
100#endif /* NETCONN */
101
102_PROTOTYP(static int remtxt, (char **) );
103_PROTOTYP(VOID rmsg, (void) );
104_PROTOTYP(static int remcfm, (void) );
105
106#ifndef NOPUSH
107extern int nopush;
108#endif /* NOPUSH */
109
110int mdmsav = -1;                        /* Save modem type around network */
111
112extern xx_strp xxstring;
113
114extern int remfile, rempipe, remappd; /* REMOTE output redirection */
115extern char * remdest;
116
117#ifdef CK_TMPDIR
118char * dldir = NULL;
119#endif /* CK_TMPDIR */
120
121extern struct ck_p ptab[];
122extern int protocol;
123
124extern int success, nfilp, fmask, fncnv, frecl, binary, warn, msgflg, quiet;
125extern int cmask, maxrps, wslotr, bigsbsiz, bigrbsiz, urpsiz, rpsiz, spsiz;
126extern int spsizr, spsizf, maxsps, spmax, pflag, bctr, npad, timef, timint;
127extern int pkttim, rtimo, local, nfils, displa, atcapr, nettype, escape;
128extern int mdmtyp, duplex, dfloc, network, cdtimo, fncact, mypadn, autoflow;
129extern int tnlm, sosi, tlevel, lf_opts, backgrd, flow, fdispla, b_save, f_save;
130extern int fnrpath, fnspath, debses, parity, pktpaus, ttnproto, ckxech;
131extern int x_ifnum;
132extern int
133  atenci, atenco, atdati, atdato, atleni, atleno, atblki, atblko,
134  attypi, attypo, atsidi, atsido, atsysi, atsyso, atdisi, atdiso;
135extern char psave[];                    /* For saving & restoring prompt */
136
137#ifdef OS2
138#ifdef NT
139#define stricmp _stricmp
140extern int tt_attr_bug;
141#endif /* NT */
142extern int tt_rows[], tt_cols[];
143extern int tt_cols_usr;
144extern int tt_szchng[VNUM];
145int tt_modechg = 1;
146extern struct _vtG G[4], *GL, *GR, *GNOW, *SSGL;
147struct _vtG savedG[4];
148extern int priority;
149extern bool send_c1;
150int send_c1_usr = FALSE;
151extern int sgrcolors;
152#else
153extern int tt_rows, tt_cols;
154#endif /*  OS2 */
155
156#ifdef STRATUS
157extern int atfrmi, atfrmo, atcrei, atcreo, atacti, atacto;
158#endif /* STRATUS */
159
160extern int tt_escape;
161extern long speed;
162
163extern CHAR
164  feol, sstate, eol, seol, stchr, mystch, mypadc, padch, ctlq, myctlq;
165
166extern char *cmarg, *cmarg2, *dftty;
167
168extern char *tp, *lp;                   /* Temporary buffer & pointers */
169#ifndef NOFRILLS
170extern char optbuf[];                   /* Buffer for MAIL or PRINT options */
171extern int rprintf;                     /* REMOTE PRINT flag */
172#endif /* NOFRILLS */
173extern char ttname[];
174
175int tttapi = 0;                         /* is Line TAPI? */
176struct keytab * tapilinetab = NULL;
177int ntapiline = 0;
178
179#ifdef NETCONN                          /* Network items */
180
181#ifdef ANYX25
182extern int revcall, closgr, cudata, nx25, npadx3;
183extern char udata[];
184extern CHAR padparms[];
185extern struct keytab x25tab[], padx3tab[];
186#endif /* ANYX25 */
187
188#ifdef OS2
189#ifndef NT
190extern bool ttslip,ttppp;
191#endif /* NT */
192#endif /* OS2 */
193#ifdef NPIPE
194extern char pipename[];
195#endif /* NPIPE */
196
197#ifdef TCPSOCKET
198#ifdef TNCODE
199extern int tn_init;
200#endif /* TNCODE */
201_PROTOTYP( int tn_snaws, (void) );
202#ifdef RLOGCODE
203_PROTOTYP( int rlog_naws, (void) );
204#endif /* RLOGCODE */
205extern int nawsflg;
206
207extern int me_binary, u_binary;
208#endif /* TCPSOCKET */
209
210#ifdef SUPERLAT
211extern char slat_pwd[18];
212#endif /* SUPERLAT */
213
214#endif /* NETCONN */
215
216#ifdef COMMENT
217#ifndef NOSETKEY
218extern KEY *keymap;
219#ifndef OS2
220#define mapkey(x) keymap[x]
221#endif /* OS2 */
222extern MACRO *macrotab;
223_PROTOTYP( VOID shostrdef, (CHAR *) );
224#ifndef NOKVERBS
225extern struct keytab kverbs[];
226extern int nkverbs;
227#endif /* NOKVERBS */
228#endif /* NOSETKEY */
229#else
230#ifndef NOSETKEY
231extern KEY *keymap;
232extern MACRO *macrotab;
233_PROTOTYP( VOID shostrdef, (CHAR *) );
234#ifndef NOKVERBS
235extern struct keytab kverbs[];
236extern int nkverbs;
237#endif /* NOKVERBS */
238#endif /* NOSETKEY */
239#endif /* COMMENT */
240
241/* Keyword tables ... */
242
243extern struct keytab onoff[], filtab[], rltab[];
244extern int nrlt;
245 
246struct keytab fttab[] = {               /* File types for SET FILE TYPE */
247    "ascii",     XYFT_B, CM_INV,
248#ifdef VMS
249    "b",         XYFT_B, CM_INV|CM_ABR,
250#endif /* VMS */
251    "binary",    XYFT_B, 0,
252#ifdef VMS
253    "block",     XYFT_I, CM_INV,
254    "image",     XYFT_I, 0,
255#endif /* VMS */
256#ifdef CK_LABELED
257    "labeled",   XYFT_L, 0,
258#endif /* CK_LABELED */
259#ifdef MAC
260    "macbinary", XYFT_M, 0,
261#endif /* MAC */
262    "text",      XYFT_T, 0
263};
264int nfttyp = (sizeof(fttab) / sizeof(struct keytab));
265
266static struct keytab rfttab[] = {       /* File types for REMOTE SET FILE */
267    "ascii",     XYFT_B, CM_INV,
268    "binary",    XYFT_B, 0,
269#ifdef VMS
270    "labeled",   XYFT_L, 0,
271#else
272#ifdef OS2
273    "labeled",   XYFT_L, 0,
274#endif /* OS2 */
275#endif /* VMS */
276    "text",      XYFT_T, 0
277};
278static int nrfttyp = (sizeof(rfttab) / sizeof(struct keytab));
279
280extern char uidbuf[];
281static int uidflag = 0;
282
283#ifndef NOSPL
284
285int query = 0;                          /* Global flag for QUERY active */
286
287static struct keytab vartyp[] = {       /* Variable types for REMOTE QUERY */
288    "global", (int) 'G', CM_INV,
289    "kermit", (int) 'K', 0,
290    "system", (int) 'S', 0,
291    "user",   (int) 'G', 0
292};
293static int nvartyp = (sizeof(vartyp) / sizeof(struct keytab));
294#endif /* NOSPL */
295
296#ifdef CK_TIMERS
297static struct keytab timotab[] = {      /* Timer types */
298    "dynamic", 1, 0,
299    "fixed",   0, 0
300};
301#endif /* CK_TIMERS */
302
303#ifdef DCMDBUF
304extern char *atxbuf, *atmbuf;                   /* Atom buffer */
305extern char *cmdbuf;                    /* Command buffer */
306extern char *line, *tmpbuf;             /* Character buffers for anything */
307extern int *intime;                     /* INPUT TIMEOUT */
308
309#else  /* Not DCMDBUF ... */
310
311extern char atxbuf[], atmbuf[];         /* Atom buffer */
312extern char cmdbuf[];                   /* Command buffer */
313extern char line[], tmpbuf[];           /* Character buffer for anything */
314extern int intime[];
315
316#endif /* DCMDBUF */
317
318#ifndef NOCSETS
319extern struct keytab fcstab[];          /* For SET FILE CHARACTER-SET */
320extern struct keytab ttcstab[];
321extern int nfilc, fcharset, tcharset, ntermc, tcsr, tcsl;
322#ifdef OS2
323_PROTOTYP( int os2setcp, (int) );
324_PROTOTYP( int os2getcp, (void) );
325_PROTOTYP( void os2debugoff, (void) );
326#endif /* OS2 */
327#endif /* NOCSETS */
328
329#ifndef NOSPL
330extern int cmdlvl;                      /* Overall command level */
331#ifdef DCMDBUF
332extern int *inpcas;                     /* INPUT CASE setting on cmd stack */
333#else
334extern int inpcas[];
335#endif /* DCMDBUF */
336#endif /* NOSPL */
337
338#ifdef CK_CURSES
339#ifndef VMS
340#ifndef COHERENT
341_PROTOTYP(int tgetent,(char *, char *));
342#endif /* COHERENT */
343#else
344#ifdef __DECC
345_PROTOTYP(int tgetent,(char *, char *));
346#endif /* __DECC */
347#endif /* VMS */
348#endif /* CK_CURSES */
349
350#ifndef NOXMIT
351#define XMITF 0                         /* SET TRANSMIT values */
352#define XMITL 1                         /* (Local to this module) */
353#define XMITP 2
354#define XMITE 3
355#define XMITX 4
356#define XMITS 5
357#define XMITW 6
358
359#define XMBUFL 50
360extern int xmitf, xmitl, xmitp, xmitx, xmits, xmitw;
361char xmitbuf[XMBUFL+1] = { NUL };       /* TRANSMIT eof string */
362
363struct keytab xmitab[] = {              /* SET TRANSMIT */
364    "echo",     XMITX, 0,
365    "eof",      XMITE, 0,
366    "fill",     XMITF, 0,
367    "linefeed", XMITL, 0,
368    "locking-shift", XMITS, 0,
369    "pause",    XMITW, 0,
370    "prompt",   XMITP, 0
371};
372int nxmit = (sizeof(xmitab) / sizeof(struct keytab));
373#endif /* NOXMIT */
374
375/* For SET FILE COLLISION */
376/* Some of the following may be possible for some C-Kermit implementations */
377/* but not others.  Those that are not possible for your implementation */
378/* should be ifdef'd out. */
379
380struct keytab colxtab[] = { /* SET FILE COLLISION options */
381#ifndef MAC
382    "append",    XYFX_A, 0,  /* append to old file */
383#endif /* MAC */
384#ifdef COMMENT
385    "ask",       XYFX_Q, 0,  /* ask what to do (not implemented) */
386#endif
387    "backup",    XYFX_B, 0,  /* rename old file */
388#ifndef MAC
389    /* This crashes Mac Kermit. */
390    "discard",   XYFX_D, 0,  /* don't accept new file */
391    "no-supersede", XYFX_D, CM_INV, /* ditto (MSK compatibility) */
392#endif /* MAC */
393    "overwrite", XYFX_X, 0,  /* overwrite the old file == file warning off */
394    "rename",    XYFX_R, 0   /* rename the incoming file == file warning on */
395#ifndef MAC
396    /* This crashes Mac Kermit. */
397,   "update",    XYFX_U, 0  /* replace if newer */
398#endif /* MAC */
399};
400int ncolx = (sizeof(colxtab) / sizeof(struct keytab));
401
402static struct keytab rfiltab[] = {      /* for REMOTE SET FILE */
403    "collision",     XYFILX, 0,
404    "names",         XYFILN, 0,
405    "record-length", XYFILR, 0,
406    "type",          XYFILT, 0
407};
408int nrfilp = (sizeof(rfiltab) / sizeof(struct keytab));
409
410struct keytab eoftab[] = {              /* File eof delimiters */
411    "cr",        XYFA_C, 0,
412    "crlf",      XYFA_2, 0,
413    "lf",        XYFA_L, 0
414};
415static int neoftab = (sizeof(eoftab) / sizeof(struct keytab));
416
417struct keytab fntab[] = {               /* File naming */
418    "converted", XYFN_C, 0,
419    "literal",   XYFN_L, 0
420};
421int nfntab = (sizeof(fntab) / sizeof(struct keytab));
422
423#ifndef NOLOCAL
424/* Terminal parameters table */
425static struct keytab trmtab[] = {
426#ifdef OS2
427    "answerback",    XYTANS, 0,
428#endif /* OS2 */
429#ifdef CK_APC
430    "apc",           XYTAPC, 0,
431#endif /* CK_APC */
432#ifdef OS2
433    "arrow-keys",    XYTARR, 0,
434#endif /* OS2 */
435#ifdef NT
436    "attr",          XYTATTR, CM_INV|CM_ABR,
437    "attr-bug",      XYTATTBUG, CM_INV,
438#endif /* NT */
439#ifdef OS2
440    "attribute",     XYTATTR, 0,
441#endif /* OS2 */
442#ifdef CK_APC
443#ifdef CK_AUTODL
444   "autodownload",   XYTAUTODL, 0,
445#endif /* CK_AUTODL */
446#endif /* CK_APC */
447#ifdef OS2
448    "bell",          XYTBEL, CM_INV,
449#endif /* OS2 */
450    "bytesize",      XYTBYT, 0,
451#ifndef NOCSETS
452#ifndef KUI
453#ifdef OS2
454    "character-set", XYTCS,  CM_INV,
455#else /* OS2 */
456    "character-set", XYTCS,  0,
457#endif /* OS2 */
458#endif /* KUI */
459#endif /* NOCSETS */
460#ifdef OS2
461    "code-page",     XYTCPG, 0,
462    "color",         XYTCOL, 0,
463    "controls",      XYTCTRL, 0,
464#endif /* OS2 */
465    "cr-display",    XYTCRD, 0,
466#ifdef OS2
467    "cursor",        XYTCUR, 0,
468#endif /* OS2 */
469    "debug",         XYTDEB, 0,
470    "echo",          XYTEC,  0,
471    "escape-character", XYTESC, 0,
472#ifdef OS2
473#ifdef PCFONTS
474    "font",          XYTFON, 0,
475#endif /* PCFONTS */
476#endif /* OS2 */
477    "height",        XYTHIG, 0,
478#ifdef OS2
479#ifdef COMMENT
480    /* not needed anymore -- 5a(191) new screen handler mechanism */
481    "hide-cursor",   XYTHCU, 0,
482#endif /* COMMENT */
483    "key",           XYTKEY, 0,
484    "keypad-mode",   XYTKPD, 0,
485#endif /* OS2 */
486#ifndef NOCSETS
487#ifdef OS2
488    "local-character-set", XYTLCS,  0,
489#else
490    "local-character-set", XYTLCS,  CM_INV,
491#endif /* OS2 */
492#endif /* NOCSETS */
493    "locking-shift", XYTSO,  0,
494#ifdef OS2MOUSE
495    "mouse",         XYTMOU, CM_INV,
496#endif /* OS2MOUSE */
497    "newline-mode",  XYTNL,  0,
498#ifdef OS2
499    "output-pacing", XYTPAC, 0,
500#ifndef NOCSETS
501#ifdef OS2
502    "remote-character-set", XYTRCS,  0,
503#else
504    "remote-character-set", XYTRCS,  CM_INV,
505#endif /* OS2 */
506#endif /* NOCSETS */
507    "roll-mode",     XYTROL, 0,
508    "screen-update", XYTUPD, 0,
509    "scrollback",    XYSCRS, 0,
510    "send-data",     XYTSEND, 0,
511    "send-end-of-block", XYTSEOB, 0,
512    "sgr-colors",    XYTSGRC, 0,
513    "statusline",    XYTSTAT, 0,
514    "transmit-timeout", XYTCTS, 0,
515    "type",          XYTTYP, 0,
516#else
517    "type",          XYTTYP, CM_INV,
518#endif /* OS2 */
519
520#ifdef OS2
521#ifndef NOCSETS
522#ifdef CKOUNI
523    "unicode",       XYTUNI, CM_INV,
524#endif /* CKOUNI */
525#endif /* NOCSETS */
526#ifdef NT
527    "video-change",  XYTVCH, 0,
528#endif /* NT */
529#endif /* OS2 */
530    "width",         XYTWID, 0,
531#ifdef OS2
532    "wrap",          XYTWRP, 0,
533#endif /* OS2 */
534    "", 0, 0
535};
536int ntrm = (sizeof(trmtab) / sizeof(struct keytab)) - 1;
537
538#ifdef OS2
539struct keytab termctrl[] = {    /* SET TERM CONTROLS */
540    "7",        7, 0,
541    "8",        8, 0
542};
543int ntermctrl = (sizeof(termctrl) / sizeof(struct keytab));
544
545struct keytab rolltab[] = {   /* Set TERM Roll Options */
546    "insert",    TTR_INSERT, 0,
547    "off",       TTR_OVER,   CM_INV,
548    "on",        TTR_INSERT, CM_INV,
549    "overwrite", TTR_OVER,   0
550};
551int nroll = (sizeof(rolltab) / sizeof(struct keytab));
552
553#define TT_GR_ALL 4
554#define TT_GR_G0  0
555#define TT_GR_G1  1
556#define TT_GR_G2  2
557#define TT_GR_G3  3
558struct keytab graphsettab[] = {  /* DEC VT Graphic Sets */
559    "all",   TT_GR_ALL, 0,
560    "g0",    TT_GR_G0,  0,
561    "g1",    TT_GR_G1,  0,
562    "g2",    TT_GR_G2,  0,
563    "g3",    TT_GR_G3,  0
564};
565int ngraphset = (sizeof(graphsettab) / sizeof(struct keytab));
566
567#endif /* OS2 */
568
569struct keytab crdtab[] = {              /* Carriage-return display */
570    "crlf",        1, 0,
571    "normal",      0, 0
572};
573extern int tt_crd;                      /* Carriage-return display variable */
574
575#ifdef CK_APC
576extern int apcstatus, apcactive;
577static struct keytab apctab[] = {       /* Terminal APC parameters */
578    "off",       APC_OFF,  0,
579    "on",        APC_ON,   0,
580    "unchecked", APC_UNCH, 0
581};
582#endif /* CK_APC */
583#endif /* NOLOCAL */
584
585extern int autodl;
586
587#ifdef OS2
588/*
589  OS/2 serial communication devices.
590*/
591struct keytab os2devtab[] = {
592    "1",    1, CM_INV,                  /* Invisible synonyms, like */
593    "2",    2, CM_INV,                  /* "set port 1" */
594    "3",    3, CM_INV,
595    "4",    4, CM_INV,
596    "5",    5, CM_INV,
597    "6",    6, CM_INV,
598    "7",    7, CM_INV,
599    "8",    8, CM_INV,
600    "com1", 1, 0,                       /* Real device names */
601    "com2", 2, 0,
602    "com3", 3, 0,
603    "com4", 4, 0,
604    "com5", 5, 0,
605    "com6", 6, 0,
606    "com7", 7, 0,
607    "com8", 8, 0
608#ifdef OS2ONLY
609   ,"slipcom1", 1, 0,          /* For use with SLIP driver */
610    "slipcom2", 2, 0,
611    "slipcom3", 3, 0,          /* shared access            */
612    "slipcom4", 4, 0,
613    "slipcom5", 5, 0,
614    "slipcom6", 6, 0,
615    "slipcom7", 7, 0,
616    "slipcom8", 8, 0,
617    "pppcom1", 1, 0,          /* For use with PPP driver */
618    "pppcom2", 2, 0,
619    "pppcom3", 3, 0,          /* shared access            */
620    "pppcom4", 4, 0,
621    "pppcom5", 5, 0,
622    "pppcom6", 6, 0,
623    "pppcom7", 7, 0,
624    "pppcom8", 8, 0
625#endif /* OS2ONLY */
626};
627int nos2dev = (sizeof(os2devtab) / sizeof(struct keytab));
628
629#ifdef OS2ONLY
630struct keytab os2ppptab[] = {
631    "0",    0, CM_INV,
632    "1",    1, CM_INV,                  /* Invisible synonyms, like */
633    "2",    2, CM_INV,                  /* "set port 1" */
634    "3",    3, CM_INV,
635    "4",    4, CM_INV,
636    "5",    5, CM_INV,
637    "6",    6, CM_INV,
638    "7",    7, CM_INV,
639    "8",    8, CM_INV,
640    "9",    9, CM_INV,
641    "ppp0", 0, 0,
642    "ppp1", 1, 0,          /* For use with PPP driver */
643    "ppp2", 2, 0,
644    "ppp3", 3, 0,          /* shared access            */
645    "ppp4", 4, 0,
646    "ppp5", 5, 0,
647    "ppp6", 6, 0,
648    "ppp7", 7, 0,
649    "ppp8", 8, 0,
650    "ppp9", 9, 0
651};
652int nos2ppp = (sizeof(os2ppptab) / sizeof(struct keytab));
653#endif /* OS2ONLY */
654
655/*
656  Terminal parameters that can be set by SET commands.
657  Used by the ck?con.c terminal emulator code. 
658  For now, only used for #ifdef OS2.  Should add these for Macintosh.
659*/
660int tt_arrow = TTK_NORM;                /* Arrow key mode: normal (cursor) */
661int tt_keypad = TTK_NORM;               /* Keypad mode: normal (numeric) */
662int tt_shift_keypad = 0;                /* Keypad Shift mode: Off */
663int tt_wrap = 1;                        /* Terminal wrap, 1 = On */
664int tt_type = TT_VT320;                 /* Terminal type, initially VT320 */
665int tt_type_mode = TT_VT320;            /* Terminal type set by host command */
666int tt_cursor = 0;                      /* Terminal cursor, 0 = Underline */
667int tt_cursor_usr = 0;                  /* Users Terminal cursor type */
668int tt_answer = 0;                      /* Terminal answerback (disabled) */
669int tt_scrsize[VNUM] = {512,512,512,1}; /* Terminal scrollback buffer size */
670int tt_bell = XYB_AUD | XYB_SYS;        /* Bell (system sounds) */
671int tt_roll[VNUM] = {1,1,1,1};          /* Terminal roll (on) */
672int tt_pacing = 0;                      /* Terminal output-pacing (none) */
673int tt_inpacing = 0;                    /* Terminal input-pacing (none) */
674#ifdef COMMENT
675int tt_hide = 0;                        /* Terminal hide-cursor (off) */
676#endif /* COMMENT */
677int tt_ctstmo = 15;                     /* Terminal transmit-timeout */
678int tt_codepage = -1;                   /* Terminal code-page */
679int tt_update = 100;                    /* Terminal screen-update interval */
680int tt_updmode = TTU_FAST;              /* Terminal screen-update mode FAST */
681extern int updmode;
682int tt_font = TTF_ROM;                  /* Terminal screen font */
683#ifndef KUI
684int tt_status = 1;                      /* Terminal status line displayed */
685int tt_status_usr = 1;
686#else  /* KUI */
687int tt_status = 0;                      /* Terminal status line displayed */
688int tt_status_usr = 0;
689#endif /* KUI */
690#ifdef CKOUNI
691int tt_unicode = 1;                     /* Use Unicode if possible */
692#endif /* CKOUNI */
693int tt_senddata = 0;                    /* Let host read terminal data */
694extern int wy_blockend;                 /* Terminal Send Data EOB type */
695
696extern unsigned char colornormal, colorselect,
697colorunderline, colorstatus, colorhelp, colorborder,
698colorgraphic, colordebug, colorreverse;
699
700extern int trueblink, trueunderline, truereverse;
701
702extern int bgi, fgi;
703extern int scrninitialized[];
704
705struct keytab beltab[] = {              /* Terminal bell mode */
706    "audible", XYB_AUD, 0,
707    "none",    XYB_NONE, 0,
708    "visible", XYB_VIS, 0
709};
710int nbeltab = sizeof(beltab)/sizeof(struct keytab);
711
712struct keytab audibletab[] = {          /* Terminal Bell Audible mode */
713    "beep",          XYB_BEEP, 0,       /* Values ORd with bell mode */
714    "system-sounds", XYB_SYS, 0   
715};
716int naudibletab = sizeof(audibletab)/sizeof(struct keytab);
717
718struct keytab akmtab[] = {              /* Arrow key mode */
719    "application", TTK_APPL, 0,
720    "cursor",      TTK_NORM, 0
721};
722struct keytab kpmtab[] = {              /* Keypad mode */
723    "application", TTK_APPL, 0,
724    "numeric",     TTK_NORM, 0
725};
726
727struct keytab ttcolmodetab[] = {
728    "current-color", 0, 0,
729    "default-color",  1, 0
730};
731int ncolmode = sizeof(ttcolmodetab)/sizeof(struct keytab);
732
733#define TTCOLNOR  0
734#define TTCOLREV  1
735#define TTCOLUND  2
736#define TTCOLSTA  3
737#define TTCOLHLP  4
738#define TTCOLBOR  5
739#define TTCOLSEL  6
740#define TTCOLDEB  7
741#define TTCOLGRP  8
742
743#define TTCOLRES  10
744#define TTCOLERA  11
745
746struct keytab ttycoltab[] = {                   /* Terminal Screen coloring */
747    "border",             TTCOLBOR, 0,          /* Screen border color */
748    "debug-terminal",     TTCOLDEB, 0,          /* Debug color */
749    "erase",              TTCOLERA, 0,          /* Erase mode */
750    "graphic",            TTCOLGRP, 0,          /* Graphic Color */
751    "help-text",          TTCOLHLP, 0,          /* Help screens */
752    "normal",             TTCOLNOR, CM_INV,     /* Normal screen text */
753    "reset-on-esc[0m",    TTCOLRES, 0,          /* Reset on ESC [ 0 m */
754    "reverse-video",      TTCOLREV, 0,          /* Reverse video */
755    "status-line",        TTCOLSTA, 0,          /* Status line */
756    "selection",          TTCOLSEL, 0,          /* Selection color */
757    "terminal-screen",    TTCOLNOR, 0,          /* Better name than "normal" */
758    "underlined-text",    TTCOLUND, 0           /* Underlined text */
759};
760int ncolors = (sizeof(ttycoltab) / sizeof(struct keytab));
761
762#define TTATTBLI 0
763#define TTATTREV 1
764#define TTATTUND 2
765
766struct keytab ttyattrtab[] = {
767    "blink",    TTATTBLI, 0,
768    "reverse",  TTATTREV, 0,
769    "underline",TTATTUND, 0
770};
771int nattrib = (sizeof(ttyattrtab) / sizeof(struct keytab));
772
773struct keytab ttyseobtab[] = {
774    "crlf_etx",  1, 0,
775    "us_cr",     0, 0
776};
777
778struct keytab ttyclrtab[] = {           /* Colors */
779    "black",       0, 0,
780    "blue",        1, 0,
781    "brown",       6, 0,
782    "cyan",        3, 0,
783    "darkgray",    8, CM_INV,
784    "dgray",       8, 0,
785    "green",       2, 0,
786    "lblue",       9, CM_INV,
787    "lcyan",      11, CM_INV,
788    "lgray",       7, CM_INV,
789    "lgreen",     10, CM_INV,
790    "lightblue",   9, 0,
791    "lightcyan",  11, 0,
792    "lightgray",   7, 0,
793    "lightgreen", 10, 0,
794    "lightmagenta",13,0,
795    "lightred",   12, 0,
796    "lmagenta",   13, CM_INV,
797    "lred",       12, CM_INV,
798    "magenta",     5, 0,
799    "red",         4, 0,
800    "white",      15, 0,
801    "yellow",     14, 0
802};
803int nclrs = (sizeof (ttyclrtab) / sizeof (struct keytab));
804
805struct keytab ttycurtab[] = {
806    "full",        TTC_BLOCK, 0,
807    "half",        TTC_HALF,  0,
808    "underline",   TTC_ULINE, 0
809};
810int ncursors = 3;
811
812struct keytab ttyptab[] = {
813    "ansi-bbs", TT_ANSI,    0,          /* ANSI.SYS (BBS) */
814    "at386",    TT_AT386,   0,          /* Unixware ANSI */
815    "avatar/0+", TT_ANSI,   0,          /* AVATAR/0+ */
816    "dg200",    TT_DG200,   0,          /* Data General DASHER 200 */
817    "dg210",    TT_DG200,   0,          /* Data General DASHER 210 */
818    "h19",      TT_H19,     CM_INV,     /* Heath-19 */
819    "heath19",  TT_H19,     0,          /* Heath-19 */
820    "hp2621",   TT_HP2621,  0,          /* HP 2621A */
821    "hz1500",   TT_HZL1500, 0,          /* Hazeltine 1500 */
822#ifdef COMMENT
823    "ibm",      TT_IBM,     CM_INV,     /* IBM 3101-xx,3161 */
824#endif /* COMMENT */
825    "scoansi",  TT_SCOANSI, 0,          /* SCO ANSI */
826/*
827  The idea of NONE is to let the console driver handle the escape sequences,
828  which, in theory at least, would give not only ANSI emulation, but also any
829  other kind of emulation that might be provided by alternative console
830  drivers, if any existed.
831
832  For this to work, ckocon.c would need to be modified to make higher-level
833  calls, like VioWrtTTY(), DosWrite(), or (simply) write(), rather than
834  VioWrt*Cell() and similar, and it would also have to give up its rollback
835  feature, and its status line and help screens would also have to be
836  forgotten or else done in an ANSI way.
837
838  As matters stand, we already have perfectly good ANSI emulation built in,
839  and there are no alternative console drivers available, so there is no point
840  in having a terminal type of NONE, so it is commented out.  However, should
841  you uncomment it, it will work like a "glass tty" -- no escape sequence
842  interpretation at all; somewhat similar to debug mode, except without the
843  debugging (no highlighting of control chars or escape sequences); help
844  screens, status line, and rollback will still work.
845*/
846#ifdef OS2PM
847#ifdef COMMENT
848    "tek4014", TT_TEK40, 0,
849#endif /* COMMENT */
850#endif /* OS2PM */
851    "tty",     TT_NONE,  0,
852    "tvi910+", TT_TVI910, 0,
853    "tvi925",  TT_TVI925, 0,
854    "tvi950",  TT_TVI950, 0,
855    "vc404",   TT_VC4404, 0,
856    "vc4404",  TT_VC4404, CM_INV,
857    "vt100",   TT_VT100, 0,
858    "vt102",   TT_VT102, 0,
859    "vt220",   TT_VT220, 0,
860    "vt320",   TT_VT320, 0,
861    "vt52",    TT_VT52,  0,
862    "wy30",    TT_WY30,  0,
863    "wy370",   TT_WY370, 0,
864    "wy50",    TT_WY50,  0,
865    "wy60",    TT_WY60,  0,
866    "wyse30",  TT_WY30,  CM_INV,
867    "wyse370", TT_WY370, CM_INV,
868    "wyse50",  TT_WY50,  CM_INV,
869    "wyse60",  TT_WY60,  CM_INV
870};
871int nttyp = (sizeof(ttyptab) / sizeof(struct keytab));
872
873struct keytab ttkeytab[] = {
874    "ansi-bbs",  TT_ANSI,    0,         /* ANSI.SYS (BBS) */
875    "at386",     TT_AT386,   0,         /* Unixware ANSI */
876    "avatar/0+", TT_ANSI,   0,          /* AVATAR/0+ */
877    "dg200",     TT_DG200,   0,         /* Data General DASHER 200 */
878    "dg210",     TT_DG200,   0,         /* Data General DASHER 210 */
879    "emacs",     TT_MAX+1,   0,         /* Emacs mode */
880    "h19",       TT_H19,     CM_INV,    /* Heath-19 */
881    "heath19",   TT_H19,     0,         /* Heath-19 */
882    "hebrew",    TT_MAX+2,   0,         /* Hebrew mode */
883    "hp2621",    TT_HP2621,  0,         /* HP 2621A */
884    "hz1500",    TT_HZL1500, 0,         /* Hazeltine 1500 */
885#ifdef COMMENT
886    "ibm",       TT_IBM,     CM_INV,    /* IBM 3101-xx,3161 */
887#endif /* COMMENT */
888    "russian",   TT_MAX+3,   0,         /* Russian mode */
889    "scoansi",   TT_SCOANSI, 0,         /* SCO ANSI */
890#ifdef OS2PM
891#ifdef COMMENT
892    "tek4014", TT_TEK40, 0,
893#endif /* COMMENT */
894#endif /* OS2PM */
895    "tty",     TT_NONE,  0,
896    "tvi910+", TT_TVI910, 0,
897    "tvi925",  TT_TVI925, 0,
898    "tvi950",  TT_TVI950, 0,
899    "vc404",   TT_VC4404, 0,
900    "vc4404",  TT_VC4404, CM_INV,
901    "vt100",   TT_VT100, 0,
902    "vt102",   TT_VT102, 0,
903    "vt220",   TT_VT220, 0,
904    "vt320",   TT_VT320, 0,
905    "vt52",    TT_VT52,  0,
906    "wy30",    TT_WY30,  0,
907    "wy370",   TT_WY370, 0,
908    "wy50",    TT_WY50,  0,
909    "wy60",    TT_WY60,  0,
910    "wyse30",  TT_WY30,  CM_INV,
911    "wyse370", TT_WY370, CM_INV,
912    "wyse50",  TT_WY50,  CM_INV,
913    "wyse60",  TT_WY60,  CM_INV
914};
915int nttkey = (sizeof(ttkeytab) / sizeof(struct keytab));
916
917struct keytab prtytab[] = { /* OS/2 Priority Levels */
918    "foreground-server", XYP_SRV, 0,
919    "idle",              XYP_IDLE, CM_INV,
920    "regular",           XYP_REG, 0,
921    "time-critical",     XYP_RTP, 0
922};
923int nprty = (sizeof(prtytab) / sizeof(struct keytab));
924#endif /* OS2 */
925
926#ifdef NT
927struct keytab win95tab[] = { /* Win95 work-arounds */
928    "alt-gr",                XYWAGR, 0,
929    "keyboard-translation",  XYWKEY, 0,
930    "overlapped-io",         XYWOIO, 0
931};
932int nwin95 = (sizeof(win95tab) / sizeof(struct keytab));
933#endif /* NT */
934
935#ifdef OS2MOUSE
936extern int wideresult;
937int tt_mouse = 1;                       /* Terminal mouse on/off */
938
939struct keytab mousetab[] = {            /* Mouse items */
940    "activate", XYM_ON,    0,
941    "button",   XYM_BUTTON, 0,
942    "clear",    XYM_CLEAR, 0
943};
944int nmtab = (sizeof(mousetab)/sizeof(struct keytab));
945
946struct keytab mousebuttontab[] = {      /* event button */
947    "one",           XYM_B1, CM_INV,
948    "three",         XYM_B3, CM_INV,
949    "two",           XYM_B2, CM_INV,
950    "1",             XYM_B1, 0,
951    "2",             XYM_B2, 0,
952    "3",             XYM_B3, 0
953};
954int nmbtab = (sizeof(mousebuttontab) / sizeof(struct keytab));
955
956struct keytab mousemodtab[] = {         /* event button key modifier */
957    "alt",              XYM_ALT,   0,
958    "alt-shift",        XYM_SHIFT|XYM_ALT, 0,
959    "ctrl",             XYM_CTRL,  0,
960    "ctrl-alt",         XYM_CTRL|XYM_ALT, 0,
961    "ctrl-alt-shift",   XYM_CTRL|XYM_SHIFT|XYM_ALT, 0,
962    "ctrl-shift",       XYM_CTRL|XYM_SHIFT, 0,
963    "none",             0, 0,
964    "shift",            XYM_SHIFT, 0
965};
966int nmmtab = (sizeof(mousemodtab) / sizeof(struct keytab));
967
968struct keytab mclicktab[] = {           /* event button click modifier */
969    "click",        XYM_C1,  0,
970    "drag",         XYM_DRAG, 0,
971    "double-click", XYM_C2,  0
972};
973int nmctab = (sizeof(mclicktab) / sizeof(struct keytab));
974
975#ifndef NOKVERBS
976extern int nkverbs;
977extern struct keytab kverbs[];
978#endif /* NOKVERBS */
979#endif /* OS2MOUSE */
980
981/* #ifdef VMS */
982struct keytab fbtab[] = {               /* Binary record types for VMS */
983    "fixed",     XYFT_B, 0,             /* Fixed is normal for binary */
984    "undefined", XYFT_U, 0              /* Undefined if they ask for it */
985};
986int nfbtyp = (sizeof(fbtab) / sizeof(struct keytab));
987/* #endif */
988
989#ifdef VMS
990struct keytab lbltab[] = {              /* Labeled File info */
991    "acl",         LBL_ACL, 0,
992    "backup-date", LBL_BCK, 0,
993    "name",        LBL_NAM, 0,
994    "owner",       LBL_OWN, 0,
995    "path",        LBL_PTH, 0
996};
997int nlblp = (sizeof(lbltab) / sizeof(struct keytab));
998#else
999#ifdef OS2
1000struct keytab lbltab[] = {              /* Labeled File info */
1001    "archive",   LBL_ARC, 0,
1002    "extended",  LBL_EXT, 0,
1003    "hidden",    LBL_HID, 0,
1004    "read-only", LBL_RO,  0,
1005    "system",    LBL_SYS, 0
1006};
1007int nlblp = (sizeof(lbltab) / sizeof(struct keytab));
1008#endif /* OS2 */
1009#endif /* VMS */
1010
1011#ifdef CK_CURSES
1012#ifdef CK_PCT_BAR
1013static struct keytab fdftab[] = {       /* SET FILE DISPLAY FULL options */
1014    "thermometer", 1, 0,
1015    "no-thermometer", 0, 0
1016};
1017extern int thermometer;
1018#endif /* CK_PCT_BAR */
1019#endif /* CK_CURSES */
1020
1021static struct keytab fdtab[] = {        /* SET FILE DISPLAY options */
1022#ifdef MAC                              /* Macintosh */
1023    "fullscreen", XYFD_R, 0,            /* Full-screen but not curses */
1024    "none",   XYFD_N, 0,
1025    "off",    XYFD_N, CM_INV,
1026    "on",     XYFD_R, CM_INV,
1027    "quiet",  XYFD_N, CM_INV
1028
1029#else                                   /* Not Mac */
1030    "crt", XYFD_S, 0,                   /* CRT display */
1031#ifdef CK_CURSES
1032#ifdef COMMENT
1033    "curses",     XYFD_C, CM_INV,       /* Full-screen, curses */
1034#endif /* COMMENT */
1035    "fullscreen", XYFD_C, 0,            /* Full-screen, whatever the method */
1036#endif /* CK_CURSES */
1037    "none",   XYFD_N, 0,                /* No display */
1038    "off",    XYFD_N, CM_INV,           /* Ditto */
1039    "on",     XYFD_R, CM_INV,           /* On = Serial */
1040    "quiet",  XYFD_N, CM_INV,           /* No display */
1041    "serial", XYFD_R, 0                 /* Serial */
1042#endif /* MAC */
1043};
1044int nfdtab = (sizeof(fdtab) / sizeof(struct keytab));
1045
1046struct keytab rsrtab[] = {              /* For REMOTE SET RECEIVE */
1047    "packet-length", XYLEN, 0,
1048    "timeout", XYTIMO, 0
1049};
1050int nrsrtab = (sizeof(rsrtab) / sizeof(struct keytab));
1051
1052/* Send/Receive Parameters */
1053 
1054struct keytab srtab[] = {
1055    "control-prefix", XYQCTL, 0,
1056    "end-of-packet", XYEOL, 0,
1057    "packet-length", XYLEN, 0,
1058    "pad-character", XYPADC, 0,
1059    "padding", XYNPAD, 0,
1060    "pathnames", XYFPATH, 0,
1061    "pause", XYPAUS, 0,
1062    "quote", XYQCTL, CM_INV,            /* = CONTROL-PREFIX */
1063    "start-of-packet", XYMARK, 0,
1064    "timeout", XYTIMO, 0
1065};
1066int nsrtab = (sizeof(srtab) / sizeof(struct keytab));
1067
1068/* REMOTE SET */
1069
1070struct keytab rmstab[] = {
1071    "attributes",  XYATTR, 0,
1072    "block-check", XYCHKT, 0,
1073    "file",        XYFILE, 0,
1074    "incomplete",  XYIFD,  0,
1075    "receive",     XYRECV, 0,
1076    "retry",       XYRETR, 0,
1077    "server",      XYSERV, 0,
1078    "transfer",    XYXFER, 0,
1079    "window",      XYWIND, 0
1080};
1081int nrms = (sizeof(rmstab) / sizeof(struct keytab));
1082
1083struct keytab attrtab[] = {
1084#ifdef STRATUS
1085    "account",       AT_ACCT, 0,
1086#endif /* STRATUS */
1087    "all",           AT_XALL, 0,
1088#ifdef COMMENT
1089    "blocksize",     AT_BLKS, 0,        /* not used */
1090#endif /* COMMENT */
1091#ifndef NOCSETS
1092    "character-set", AT_ENCO, 0,
1093#endif /* NOCSETS */
1094#ifdef STRATUS
1095    "creator",       AT_CREA, 0,
1096#endif /* STRATUS */
1097    "date",          AT_DATE, 0,
1098    "disposition",   AT_DISP, 0,
1099    "encoding",      AT_ENCO, CM_INV,
1100#ifdef STRATUS
1101    "format",        AT_RECF, 0,
1102#endif /* STRATUS */
1103    "length",        AT_LENK, 0,
1104    "off",           AT_ALLN, 0,
1105    "on",            AT_ALLY, 0,
1106#ifdef COMMENT
1107    "os-specific",   AT_SYSP, 0,        /* not used by UNIX or VMS */
1108#endif /* COMMENT */
1109    "system-id",     AT_SYSI, 0,
1110    "type",          AT_FTYP, 0
1111};
1112int natr = (sizeof(attrtab) / sizeof(struct keytab)); /* how many attributes */
1113
1114#ifndef NOSPL
1115extern int indef, inecho, insilence, inbufsize;
1116extern char * inpbuf, * inpbp;
1117struct keytab inptab[] = {              /* SET INPUT parameters */
1118    "buffer-length",   IN_BUF, 0,
1119    "case",            IN_CAS, 0,
1120    "default-timeout", IN_DEF, CM_INV,  /* There is no default timeout */
1121    "echo",            IN_ECH, 0,
1122#ifdef OS2
1123    "pacing",          IN_PAC, CM_INV,
1124#endif /* OS2 */
1125    "silence",         IN_SIL, 0,
1126    "timeout-action",  IN_TIM, 0
1127};
1128int ninp = (sizeof(inptab) / sizeof(struct keytab));
1129
1130struct keytab intimt[] = {              /* SET INPUT TIMEOUT parameters */
1131    "proceed", 0, 0,                    /* 0 = proceed */
1132    "quit",    1, 0                     /* 1 = quit */
1133};
1134
1135struct keytab incast[] = {              /* SET INPUT CASE parameters */
1136    "ignore",  0, 0,                    /* 0 = ignore */
1137    "observe", 1, 0                     /* 1 = observe */
1138};
1139#endif /* NOSPL */
1140
1141struct keytab nabltab[] = {             /* For any command that needs */
1142    "disabled", 0, 0,                   /* these keywords... */
1143    "enabled",  1, 0
1144};
1145
1146#ifdef OS2
1147struct keytab msktab[] = { /* SET MS-DOS KERMIT compatibilities */
1148#ifdef COMMENT
1149    "color", MSK_COLOR,  0,
1150#endif /* COMMENT */
1151    "keycodes", MSK_KEYS, 0
1152};
1153int nmsk = (sizeof(msktab) / sizeof(struct keytab));
1154
1155struct keytab scrnupd[] = { /* SET TERMINAL SCREEN-UPDATE */
1156    "fast", TTU_FAST,  0,         
1157    "smooth", TTU_SMOOTH, 0       
1158};
1159int nscrnupd = (sizeof(scrnupd) / sizeof(struct keytab));
1160
1161struct keytab termfont[] = { /* SET TERMINAL FONT */
1162#ifdef COMMENT
1163    "cp111", TTF_111, 0,
1164    "cp112", TTF_112, 0,
1165    "cp113", TTF_113, 0,
1166#endif /* COMMENT */
1167    "cp437", TTF_437, 0,
1168    "cp850", TTF_850, 0,
1169#ifdef COMMENT
1170    "cp851", TTF_851, 0,
1171#endif /* COMMENT */
1172    "cp852", TTF_852, 0,
1173#ifdef COMMENT
1174    "cp853", TTF_853, 0,
1175    "cp860", TTF_860, 0,
1176    "cp861", TTF_861, 0,
1177#endif /* COMMENT */
1178    "cp862", TTF_862, 0,
1179#ifdef COMMENT
1180    "cp863", TTF_863, 0,
1181    "cp864", TTF_864, 0,
1182    "cp865", TTF_865, 0,
1183#endif /* COMMENT */
1184    "cp866", TTF_866, 0,
1185#ifdef COMMENT
1186    "cp880", TTF_880, 0,
1187    "cp881", TTF_881, 0,
1188    "cp882", TTF_882, 0,
1189    "cp883", TTF_883, 0,
1190    "cp884", TTF_884, 0,
1191    "cp885", TTF_885, 0,
1192#endif /* COMMENT */
1193    "default", TTF_ROM, 0
1194};
1195int ntermfont = (sizeof(termfont) / sizeof(struct keytab));
1196
1197struct keytab anbktab[] = {             /* For any command that needs */
1198    "message", 2, 0,                    /* these keywords... */
1199    "off",     0, 0,                   
1200    "on",      1, 0,
1201    "unsafe-messag0", 99, CM_INV,
1202    "unsafe-message", 3,  CM_INV
1203};
1204int nansbk = (sizeof(anbktab) / sizeof(struct keytab));
1205
1206#endif /* OS2 */
1207
1208
1209/* The following routines broken out of doprm() to give compilers a break. */
1210
1211/*  S E T O N  --  Parse on/off (default on), set parameter to result  */
1212 
1213int
1214seton(prm) int *prm; {
1215    int x, y;
1216    if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
1217    if ((x = cmcfm()) < 0) return(x);
1218    *prm = y;
1219    return(1);
1220}
1221 
1222/*  S E T N U M  --  Set parameter to result of cmnum() parse.  */
1223/*
1224 Call with pointer to integer variable to be set,
1225   x = number from cnum parse, y = return code from cmnum,
1226   max = maximum value to accept, -1 if no maximum.
1227 Returns -9 on failure, after printing a message, or 1 on success.
1228*/
1229int
1230setnum(prm,x,y,max) int x, y, *prm, max; {
1231    extern int cmflgs;
1232    debug(F101,"setnum","",y);
1233    if (y == -3) {
1234        printf("\n?Value required\n");
1235        return(-9);
1236    }
1237    if (y == -2) {
1238        printf("%s?Not a number: %s\n",cmflgs == 1 ? "" : "\n", atxbuf);
1239        return(-9);
1240    }
1241    if (y < 0) return(y);
1242    if (max > -1 && x > max) {
1243        printf("?Sorry, %d is the maximum\n",max);
1244        return(-9);
1245    }
1246    if ((y = cmcfm()) < 0) return(y);
1247    *prm = x;
1248    return(1);
1249}
1250 
1251/*  S E T C C  --  Set parameter var to an ASCII control character value.  */
1252/*
1253  Parses a number, or a literal control character, or a caret (^) followed
1254  by an ASCII character whose value is 63-95 or 97-122, then gets confirmation,
1255  then sets the parameter to the code value of the character given.  If there
1256  are any parse errors, they are returned, otherwise on success 1 is returned.
1257*/
1258int
1259setcc(dflt,var) char *dflt; int *var; {
1260    int x, y;
1261    unsigned int c;
1262    char *hlpmsg = "Control character,\n\
1263 numeric ASCII value,\n\
1264 or in ^X notation,\n\
1265 or preceded by a backslash and entered literally";
1266   
1267    /* This is a hack to turn off complaints from expression evaluator. */
1268    x_ifnum = 1;
1269    y = cmnum(hlpmsg, dflt, 10, &x, xxstring); /* Parse a number */
1270    x_ifnum = 0;                               /* Allow complaints again */
1271    if (y < 0) {                        /* Parse failed */
1272        if (y != -2)                    /* Reparse needed or somesuch */
1273          return(y);                    /* Pass failure back up the chain */
1274    }
1275    /* Did they type a real control character? */
1276
1277    for (c = strlen(atmbuf) - 1; c > 0; c--) /* Trim */
1278      if (atmbuf[c] == SP) atmbuf[c] = NUL;
1279
1280    if (y < 0) {                        /* It was not a number */
1281        if ((c = atmbuf[0]) && !atmbuf[1]) { /* Was it a literal Ctrl char? */
1282            if ((c > 037) && (c != 0177)) {
1283                printf("\n?Not a control character - %d\n",c);
1284                return(-9);
1285            } else {
1286                if ((y = cmcfm()) < 0)  /* Confirm */
1287                  return(y);
1288                *var = c;               /* Set the variable */
1289                return(1);
1290            }
1291        } else if (atmbuf[0] == '^' && !atmbuf[2]) { /* Or ^X notation? */
1292            c = atmbuf[1];
1293            if (islower((char) c))      /* Uppercase lowercase letters */
1294              c = toupper(c);
1295            if (c > 62 && c < 96) {     /* Check range */
1296                if ((y = cmcfm()) < 0)
1297                  return(y);
1298                *var = ctl(c);          /* OK */
1299                return(1);
1300            } else {
1301                printf("?Not a control character - %s\n", atmbuf);
1302                return(-9);
1303            }
1304        } else {                        /* Something illegal was typed */
1305            printf("?Invalid - %s\n", atmbuf);
1306            return(-9);
1307        }
1308    }
1309    if ((x > 037) && (x != 0177)) {     /* They typed a number */
1310        printf("\n?Not in ASCII control range - %d\n",x);
1311        return(-9);
1312    }
1313    if ((y = cmcfm()) < 0)              /* In range, confirm */
1314      return(y);
1315    *var = x;                           /* Set variable */
1316    return(1);
1317}
1318
1319int
1320doxdis() {
1321    int x, y, z;
1322    char *s;
1323
1324    if ((x = cmkey(fdtab,nfdtab,"file transfer display style","",
1325                   xxstring)) < 0)
1326      return(x);
1327#ifdef CK_PCT_BAR
1328    if ((y = cmkey(fdftab,2,"","thermometer",xxstring)) < 0)
1329      return(y);
1330    thermometer = y;
1331#endif /* CK_PCT_BAR */
1332    if ((z = cmcfm()) < 0) return(z);
1333#ifdef CK_CURSES
1334    if (x == XYFD_C) {                  /* FULLSCREEN */
1335#ifndef MYCURSES
1336        extern char * trmbuf;           /* Real curses */
1337        int z;
1338        s = getenv("TERM");
1339        if (!s) s = "";
1340#ifndef COHERENT
1341        if (*s)
1342          z = tgetent(trmbuf,s);
1343        else
1344          z = 0;
1345        debug(F111,"SET tgetent",s,z);
1346        if (z < 1) {
1347#ifdef VMS
1348            printf("Sorry, terminal type not supported: \"%s\"\n",s);
1349#else
1350            printf("Sorry, terminal type unknown: \"%s\"\n",s);
1351#endif /* VMS */
1352            return(success = 0);
1353        }
1354#endif /* COHERENT */
1355#endif /* MYCURSES */
1356        line[0] = '\0';                 /* (What's this for?) */
1357    }
1358#endif /* CK_CURSES */
1359    fdispla = x;                        /* It's OK. */
1360    return(success = 1);
1361}
1362
1363int
1364setfil(rmsflg) int rmsflg; {
1365    if (rmsflg) {
1366        if ((y = cmkey(rfiltab,nrfilp,"Remote file parameter","",
1367                       xxstring)) < 0) {
1368            if (y == -3) {
1369                printf("?Remote file parameter required\n");
1370                return(-9);
1371            } else return(y);
1372        }
1373    } else {
1374        if ((y = cmkey(filtab,nfilp,"File parameter","",xxstring)) < 0)
1375          return(y);
1376    }
1377    switch (y) {
1378#ifdef COMMENT                          /* Not needed */
1379      case XYFILB:                      /* Blocksize */
1380        sprintf(tmpbuf,"%d",DBLKSIZ);
1381        if ((y = cmnum("file block size",tmpbuf,10,&z,xxstring)) < 0)
1382          return(y);
1383        if ((x = cmcfm()) < 0) return(x);
1384        if (rmsflg) {
1385            sprintf(tmpbuf,"%d",z);
1386            sstate = setgen('S', "311", tmpbuf, "");
1387            return((int) sstate);
1388        } else {
1389            fblksiz = z;
1390            return(success = 1);
1391        }
1392#endif /* COMMENT */
1393
1394      case XYFILS:                      /* Byte size */
1395        if ((y = cmnum("file byte size (7 or 8)","8",10,&z,xxstring)) < 0)
1396          return(y);
1397        if (z != 7 && z != 8) {
1398            printf("\n?The choices are 7 and 8\n");
1399            return(0);
1400        }
1401        if ((y = cmcfm()) < 0) return(y);
1402        if (z == 7) fmask = 0177;
1403        else if (z == 8) fmask = 0377;
1404        return(success = 1);
1405
1406#ifndef NOCSETS
1407      case XYFILC:                      /* Character set */
1408        if ((x = cmkey(fcstab,nfilc,"local file code","ascii", xxstring)) < 0)
1409          return(x);
1410        if ((z = cmcfm()) < 0) return(z);
1411        fcharset = x;
1412#ifndef MAC
1413        if (tcharset == TC_TRANSP) {    /* Automatically pick XFER CHAR */
1414            if (fcharset == FC_USASCII ||
1415                fcharset == FC_UKASCII ||
1416                fcharset == FC_DUASCII ||
1417                fcharset == FC_FIASCII ||
1418                fcharset == FC_FRASCII ||
1419                fcharset == FC_FCASCII ||
1420                fcharset == FC_GEASCII ||
1421                fcharset == FC_ITASCII ||
1422                fcharset == FC_NOASCII ||
1423                fcharset == FC_POASCII ||
1424                fcharset == FC_SPASCII ||
1425                fcharset == FC_SWASCII ||
1426                fcharset == FC_CHASCII
1427                )
1428              tcharset = TC_1LATIN;
1429            else if (fcharset == FC_1LATIN ||
1430                     fcharset == FC_DECMCS ||
1431                     fcharset == FC_NEXT   ||
1432                     fcharset == FC_CP437  ||
1433                     fcharset == FC_CP850  ||
1434                     fcharset == FC_APPQD  ||
1435                     fcharset == FC_DGMCS  ||
1436                     fcharset == FC_HPR8
1437                     )
1438              tcharset = TC_1LATIN;
1439#ifndef NOLATIN2
1440            else if (fcharset == FC_HUASCII ||
1441                     fcharset == FC_2LATIN  ||
1442                     fcharset == FC_CP852
1443                     )
1444              tcharset = TC_2LATIN;
1445#endif /* NOLATIN2 */
1446#ifndef NOCYRIL
1447            else if (fcharset == FC_CYRILL ||
1448                     fcharset == FC_CP866  ||
1449                     fcharset == FC_KOI7   ||
1450                     fcharset == FC_KOI8
1451                     )
1452              tcharset = TC_CYRILL;
1453#endif /* NOCYRIL */
1454#ifndef NOKANJI
1455            else if (fcharset == FC_JIS7  ||
1456                     fcharset == FC_SHJIS ||
1457                     fcharset == FC_JEUC  ||
1458                     fcharset == FC_JDEC
1459                     )
1460              tcharset = TC_JEUC;
1461#endif /* NOKANJI */
1462#ifndef NOHEBREW
1463            else if (fcharset == FC_HE7 ||
1464                     fcharset == FC_HEBREW ||
1465                     fcharset == FC_CP862
1466                     )
1467              tcharset = TC_HEBREW;
1468#endif /* NOKANJI */
1469        }
1470#endif /* MAC */
1471        return(success = 1);
1472#endif /* NOCSETS */
1473
1474      case XYFILD:                      /* Display */
1475        return(doxdis());
1476
1477      case XYFILA:                      /* End-of-line */
1478#ifdef NLCHAR
1479        s = "";
1480        if (NLCHAR == 015)
1481          s = "cr";
1482        else if (NLCHAR == 012)
1483          s = "lf";
1484        if ((x = cmkey(eoftab, neoftab,
1485                       "local text-file line terminator",s,xxstring)) < 0)
1486          return(x);
1487#else
1488        if ((x = cmkey(eoftab, neoftab,
1489                       "local text-file line terminator","crlf",xxstring)) < 0)
1490          return(x);
1491#endif /* NLCHAR */
1492        if ((z = cmcfm()) < 0) return(z);
1493        feol = (CHAR) x;
1494        return(success = 1);
1495
1496      case XYFILN:                      /* Names */
1497        if ((x = cmkey(fntab,nfntab,"how to handle filenames","converted",
1498                       xxstring)) < 0)
1499          return(x);
1500        if ((z = cmcfm()) < 0) return(z);
1501        if (rmsflg) {
1502            sprintf(tmpbuf,"%d",1 - x);
1503            sstate = setgen('S', "301", tmpbuf, "");
1504            return((int) sstate);
1505        } else {
1506            ptab[protocol].fncn = x;    /* Set structure */
1507            fncnv = x;                  /* Set variable */
1508            f_save = x;                 /* Set and set "permanent" variable */
1509            return(success = 1);
1510        }
1511
1512      case XYFILR:                      /* Record length */
1513        sprintf(tmpbuf,"%d",DLRECL);
1514        if ((y = cmnum("file record length",tmpbuf,10,&z,xxstring)) < 0)
1515          return(y);
1516        if ((x = cmcfm()) < 0) return(x);
1517        if (rmsflg) {
1518            sprintf(tmpbuf,"%d",z);
1519            sstate = setgen('S', "312", tmpbuf, "");
1520            return((int) sstate);
1521        } else {
1522            frecl = z;
1523            return(success = 1);
1524        }
1525
1526#ifdef COMMENT
1527      case XYFILO:                      /* Organization */
1528        if ((x = cmkey(forgtab,nforg,"file organization","sequential",
1529                       xxstring)) < 0)
1530          return(x);
1531        if ((y = cmcfm()) < 0) return(y);
1532        if (rmsflg) {
1533            sprintf(tmpbuf,"%d",x);
1534            sstate = setgen('S', "314", tmpbuf, "");
1535            return((int) sstate);
1536        } else {
1537            forg = x;
1538            return(success = 1);
1539        }       
1540#endif /* COMMENT */
1541
1542#ifdef COMMENT                          /* Not needed */
1543      case XYFILF:                      /* Format */
1544        if ((x = cmkey(frectab,nfrec,"file record format","stream",
1545                       xxstring)) < 0)
1546          return(x);
1547        if ((y = cmcfm()) < 0) return(y);
1548        if (rmsflg) {
1549            sprintf(tmpbuf,"%d",x);
1550            sstate = setgen('S', "313", tmpbuf, "");
1551            return((int) sstate);
1552        } else {
1553            frecfm = x;
1554            return(success = 1);
1555        }
1556#endif /* COMMENT */
1557
1558#ifdef COMMENT
1559      case XYFILP:                      /* Printer carriage control */
1560        if ((x = cmkey(fcctab,nfcc,"file carriage control","newline",
1561                       xxstring)) < 0)
1562          return(x);
1563        if ((y = cmcfm()) < 0) return(y);
1564        if (rmsflg) {
1565            sprintf(tmpbuf,"%d",x);
1566            sstate = setgen('S', "315", tmpbuf, "");
1567            return((int) sstate);
1568        } else {
1569            fcctrl = x;
1570            return(success = 1);
1571        }       
1572#endif /* COMMENT */
1573
1574      case XYFILT:                      /* Type */
1575        if ((x = cmkey(rmsflg ? rfttab  : fttab,
1576                       rmsflg ? nrfttyp : nfttyp,
1577                       "type of file transfer","text",xxstring)) < 0)
1578          return(x);
1579
1580#ifdef VMS
1581        /* Allow VMS users to choose record format for binary files */
1582        if ((x == XYFT_B) && (rmsflg == 0)) {
1583            if ((x = cmkey(fbtab,nfbtyp,"VMS record format","fixed",
1584                           xxstring)) < 0)
1585              return(x);
1586        }
1587#endif /* VMS */
1588        if ((y = cmcfm()) < 0) return(y);
1589        binary = x;
1590        b_save = x;
1591#ifdef MAC
1592        (void) mac_setfildflg(binary);
1593#endif /* MAC */
1594        if (rmsflg) {
1595            char buf[4];                /* Allow for LABELED in VMS & OS/2 */
1596            sprintf(buf,"%d",x);
1597            sstate = setgen('S', "300", buf, "");
1598            return((int) sstate);
1599        } else {
1600            return(success = 1);
1601        }
1602
1603      case XYFILX:                      /* Collision Action */
1604        if ((x = cmkey(colxtab,ncolx,"Filename collision action","backup",
1605                       xxstring)) < 0)
1606          return(x);
1607        if ((y = cmcfm()) < 0) return(y);
1608        fncact = x;
1609        ptab[protocol].fnca = x;
1610        if (rmsflg) {
1611            sprintf(tmpbuf,"%d",fncact);
1612            sstate = setgen('S', "302", tmpbuf, "");
1613            return((int) sstate);
1614        } else {
1615            if (fncact == XYFX_R) warn = 1; /* SET FILE WARNING implications */
1616            if (fncact == XYFX_X) warn = 0; /* ... */
1617            return(success = 1);
1618        }
1619
1620      case XYFILW:                      /* Warning/Write-Protect */
1621        if ((x = seton(&warn)) < 0) return(x);
1622        if (warn)
1623          fncact = XYFX_R;
1624        else
1625          fncact = XYFX_X;
1626        return(success = 1);
1627
1628#ifdef CK_LABELED
1629      case XYFILL:                      /* LABELED FILE parameters */
1630        if ((x = cmkey(lbltab,nlblp,"Labeled file feature","",
1631                       xxstring)) < 0)
1632          return(x);
1633        if ((success = seton(&y)) < 0)
1634          return(success);
1635        if (y)                          /* Set or reset the selected bit */
1636          lf_opts |= x;                 /* in the options bitmask. */
1637        else
1638          lf_opts &= ~x;
1639        return(success);
1640#endif /* CK_LABELED */
1641
1642      case XYFILI:                      /* INCOMPLETE */
1643        return(doprm(XYIFD,rmsflg));
1644
1645#ifdef CK_TMPDIR
1646      case XYFILG: {                    /* Download directory */
1647          int x;
1648          char *s;
1649#ifdef ZFNQFP
1650          struct zfnfp * fnp;
1651#endif /* ZFNQFP */
1652#ifdef MAC
1653          char temp[34];
1654#endif /* MAC */
1655
1656#ifdef GEMDOS
1657          if ((x = cmdir("Name of local directory, or carriage return",
1658                         "",&s,
1659                         NULL)) < 0 ) {
1660              if (x != -3)
1661                return(x);
1662          }
1663#else
1664#ifdef OS2
1665          if ((x = cmdir("Name of PC disk and/or directory,\n\
1666       or press the Enter key to use current directory",
1667                         "",&s,xxstring)) < 0 ) {
1668              if (x != -3)
1669                return(x);
1670          }
1671#else
1672#ifdef MAC
1673          strncpy(temp,homdir,32);
1674          x = strlen(temp);
1675          if (x > 0) if (temp[x-1] != ':') { temp[x] = ':'; temp[x+1] = NUL; }
1676          if ((x = cmtxt("Name of Macintosh volume and/or folder,\n\
1677 or press the Return key for the desktop on the boot disk",
1678                         temp,&s, xxstring)) < 0 )
1679            return(x);
1680#else
1681          if ((x = cmdir("Name of local directory, or carriage return",
1682                         "", &s, xxstring)) < 0 ) {
1683              if (x != -3)
1684                return(x);
1685          }
1686#endif /* MAC */
1687#endif /* OS2 */
1688#endif /* GEMDOS */
1689          debug(F110,"download dir",s,0);
1690
1691#ifndef MAC
1692          if (x == 2) {
1693              printf("?Wildcards not allowed in directory name\n");
1694              return(-9);
1695          }
1696#endif /* MAC */
1697
1698#ifdef ZFNQFP
1699          if (fnp = zfnqfp(s,TMPBUFSIZ - 1,tmpbuf)) {
1700              if (fnp->fpath)
1701                if ((int) strlen(fnp->fpath) > 0)
1702                  s = fnp->fpath;
1703          }
1704          debug(F110,"download zfnqfp",s,0);
1705#endif /* ZFNQFP */
1706
1707          strcpy(line,s);               /* Make a safe copy */
1708          s = line;
1709#ifndef MAC
1710          if ((x = cmcfm()) < 0)        /* Get confirmation */
1711            return(x);
1712#endif /* MAC */
1713
1714          x = strlen(line);
1715
1716#ifdef datageneral
1717          if (line[x-1] == ':')         /* homdir ends in colon, */
1718            line[x-1] = NUL;            /* and "dir" doesn't like that... */
1719#endif /* datageneral */
1720         
1721          if (dldir)
1722            free(dldir);
1723          dldir = NULL;
1724
1725          if (x && (dldir = malloc(x + 1)))
1726            strcpy(dldir, line);
1727
1728          return(success = 1);
1729      }
1730#endif /* CK_TMPDIR */
1731      case XYFILY:
1732        return(setdest());
1733
1734      default:
1735        printf("?unexpected file parameter\n");
1736        return(-2);
1737    }
1738}
1739
1740#ifdef OS2
1741/* MS-DOS KERMIT compatibility modes */
1742int
1743setmsk() {
1744    if ((y = cmkey(msktab,nmsk,"MS-DOS Kermit compatibility mode",
1745                    "keycodes",xxstring)) < 0) return(y);
1746
1747    switch ( y ) {
1748#ifdef COMMENT
1749      case MSK_COLOR:
1750        return(seton(&mskcolors));
1751#endif /* COMMENT */
1752      case MSK_KEYS:
1753        return(seton(&mskkeys));
1754      default:                          /* Shouldn't get here. */
1755        return(-2);
1756    }
1757}
1758#endif
1759
1760#ifndef NOLOCAL
1761int
1762settrm() {
1763    int i = 0;
1764#ifdef OS2
1765    extern int colorreset, erasemode;
1766#endif /* OS2 */
1767
1768    if ((y = cmkey(trmtab,ntrm,"", "",xxstring)) < 0) return(y);
1769#ifdef MAC
1770    printf("\n?Sorry, not implemented yet.  Please use the Settings menu.\n");
1771    return(-9);
1772#else
1773    switch (y) {
1774      case XYTBYT:                      /* SET TERMINAL BYTESIZE */
1775        if ((y = cmnum("bytesize for terminal connection","8",10,&x,
1776                       xxstring)) < 0)
1777          return(y);
1778        if (x != 7 && x != 8) {
1779            printf("\n?The choices are 7 and 8\n");
1780            return(success = 0);
1781        }
1782        if ((y = cmcfm()) < 0) return(y);
1783        if (x == 7) cmask = 0177;
1784        else if (x == 8) {
1785            cmask = 0377;
1786            parity = 0;
1787        }
1788        return(success = 1);
1789
1790      case XYTSO:                       /* SET TERMINAL LOCKING-SHIFT */
1791        return(seton(&sosi));
1792
1793      case XYTNL:                       /* SET TERMINAL NEWLINE-MODE */
1794        return(seton(&tnlm));
1795
1796#ifdef OS2
1797      case XYTCOL:
1798        if ((x = cmkey(ttycoltab,ncolors,"","terminal",xxstring)) < 0)
1799          return(x);
1800        else if (x == TTCOLRES) {
1801            if ((y = cmkey(ttcolmodetab,ncolmode,
1802                           "","default-color",xxstring)) < 0)
1803              return(y);
1804            if ((z = cmcfm()) < 0)
1805              return(z);
1806            colorreset = y;
1807            return(success = 1);
1808        } else if (x == TTCOLERA) {
1809            if ((y = cmkey(ttcolmodetab,ncolmode,"",
1810                           "current-color",xxstring)) < 0)
1811              return(y);
1812            if ((z = cmcfm()) < 0)
1813              return(z);
1814            erasemode = y;
1815            return(success=1);
1816        } else {                        /* No parse error */
1817            int fg = 0, bg = 0;
1818            fg = cmkey(ttyclrtab, nclrs,
1819                       (x == TTCOLBOR ?
1820                        "color for screen border" :
1821                        "foreground color and then background color"),
1822                       "lgray", xxstring);
1823            if (fg < 0)
1824              return(fg);
1825            if (x != TTCOLBOR) {
1826                if ((bg = cmkey(ttyclrtab,nclrs,
1827                                "background color","blue",xxstring)) < 0)
1828                  return(bg);
1829            }
1830            if ((y = cmcfm()) < 0)
1831              return(y);
1832            switch (x) {
1833              case TTCOLNOR:
1834                colornormal = fg | bg << 4;
1835                fgi = fg & 0x08;
1836                bgi = bg & 0x08;
1837                break;
1838              case TTCOLREV:
1839                colorreverse = fg | bg << 4;
1840                break;
1841              case TTCOLUND:   
1842                colorunderline = fg | bg << 4;
1843                break;
1844              case TTCOLGRP:
1845                colorgraphic = fg | bg << 4;
1846                break;
1847              case TTCOLDEB:
1848                colordebug = fg | bg << 4;
1849                break;
1850              case TTCOLSTA:
1851                colorstatus = fg | bg << 4;
1852                break;
1853              case TTCOLHLP:
1854                colorhelp = fg | bg << 4;
1855                break;
1856              case TTCOLBOR:
1857                colorborder = fg;
1858                break;
1859              case TTCOLSEL:
1860                colorselect = fg | bg << 4;
1861                break;
1862              default:
1863                printf("%s - invalid\n",cmdbuf);
1864                return(-9);
1865                break;
1866            }
1867            scrninitialized[VTERM] = 0;
1868            VscrnInit(VTERM);
1869        }
1870        return(success = 1);
1871
1872      case XYTCUR:                      /* SET TERMINAL CURSOR */
1873        if ((x = cmkey(ttycurtab,ncursors,"","underline",xxstring)) < 0)
1874          return(x);
1875        if ((y = cmcfm()) < 0) return(y);
1876        tt_cursor = tt_cursor_usr = x;
1877        return(success = 1);
1878#endif /* OS2 */
1879
1880      case XYTTYP:                      /* SET TERMINAL TYPE */
1881#ifdef OS2
1882        if ((x = cmkey(ttyptab,nttyp,"","vt320",xxstring)) < 0)
1883          return(x);
1884        if ((y = cmcfm()) < 0)
1885          return(y);
1886        settermtype(x,1);
1887        return(success=1);
1888#else  /* Not OS2 */
1889        printf(
1890"\n Sorry, this version of C-Kermit does not support the SET TERMINAL TYPE\n");
1891        printf(
1892" command.  Type \"help set terminal\" for further information.\n");
1893#endif /* OS2 */
1894        return(success = 0);
1895
1896#ifdef OS2
1897      case XYTARR:                      /* SET TERMINAL ARROW-KEYS */
1898        if ((x = cmkey(akmtab,2,"","",xxstring)) < 0) return(x);
1899        if ((y = cmcfm()) < 0) return(y);
1900        tt_arrow = x;                   /* TTK_NORM / TTK_APPL; see ckuusr.h */
1901        return(success = 1);
1902
1903      case XYTKPD:                      /* SET TERMINAL KEYPAD-MODE */
1904        if ((x = cmkey(kpmtab,2,"","",xxstring)) < 0) return(x);
1905        if ((y = cmcfm()) < 0) return(y);
1906        tt_keypad = x;                  /* TTK_NORM / TTK_APPL; see ckuusr.h */
1907        return(success = 1);
1908
1909      case XYTWRP:                      /* SET TERMINAL WRAP */
1910        return(seton(&tt_wrap));
1911
1912      case XYSCRS:
1913        if ((y = cmnum("CONNECT scrollback buffer size, lines","2000",10,&x,
1914                       xxstring)) < 0)
1915          return(y);
1916        /* The max number of lines is the RAM  */
1917        /* we can actually dedicate to a       */
1918        /* scrollback buffer given the maximum */
1919        /* process memory space of 512MB       */
1920        if (x < 256 || x > 2000000L) {
1921            printf("\n?The size must be between 256 and 2,000,000.\n");
1922            return(success = 0);
1923        }
1924        if ((y = cmcfm()) < 0) return(y);
1925#ifndef VSCRNINIT
1926        if ( (ULONG) x < VscrnGetBufferSize(VTERM) ) {
1927            printf("\nWarning: the scrollback buffer will be emptied on the");
1928            printf(" next CONNECT,\n");
1929            printf("unless the buffer is restored to %d lines.\n",
1930                   VscrnGetBufferSize(VTERM));
1931        }
1932#endif /* VSCRNINIT */
1933        tt_scrsize[VTERM] = x;
1934#ifdef VSCRNINIT
1935        VscrnInit(VTERM);
1936#endif /* VSCRNINIT */
1937        return(success = 1);
1938#endif /* OS2 */
1939
1940#ifndef NOCSETS
1941#ifndef KUI
1942      case XYTCS:                       /* SET TERMINAL CHARACTER-SET */
1943          /* set terminal character-set <remote> <local> */
1944        if ((x = cmkey(
1945#ifdef CKOUNI
1946                       txrtab,ntxrtab,
1947#else /* CKOUNI */
1948                       ttcstab,ntermc,
1949#endif /* CKOUNI */
1950                       "remote terminal character-set","",xxstring)) < 0)
1951          return(x);
1952        if (x == FC_TRANSP) {           /* TRANSPARENT? */
1953            if ((x = cmcfm()) < 0) return(x); /* Confirm the command */
1954#ifdef CKOUNI
1955            tcsr = tcsl = TX_ASCII;     /* Make them both the same */
1956#else /* CKOUNI */
1957            tcsr = tcsl = FC_USASCII;
1958#endif /* CKOUNI */
1959#ifdef OS2
1960            y = os2getcp();             /* Default is current code page */
1961            switch (y) {
1962#ifdef CKOUNI
1963            case 437: tcsr = tcsl = TX_CP437; break;
1964            case 850: tcsr = tcsl = TX_CP850; break;
1965            case 852: tcsr = tcsl = TX_CP852; break;
1966            case 857: tcsr = tcsl = TX_CP857; break;
1967            case 862: tcsr = tcsl = TX_CP862; break;
1968            case 866: tcsr = tcsl = TX_CP866; break;
1969            case 869: tcsr = tcsl = TX_CP869; break;
1970#else /* CKOUNI */
1971            case 437: tcsr = tcsl = FC_CP437; break;
1972            case 850: tcsr = tcsl = FC_CP850; break;
1973            case 852: tcsr = tcsl = FC_CP852; break;
1974            case 862: tcsr = tcsl = FC_CP862; break;
1975            case 866: tcsr = tcsl = FC_CP866; break;
1976#endif /* CKOUNI */
1977            }
1978            for (i = 0; i < 4; i++) {
1979#ifdef CKOUNI
1980                G[i].def_designation = G[i].designation = TX_TRANSP;
1981#else /* CKOUNI */
1982                G[i].def_designation = G[i].designation = FC_TRANSP;
1983#endif /* CKOUNI */
1984                G[i].init = FALSE;
1985                G[i].size = G[i].def_size = cs96;
1986                G[i].c1 = G[i].def_c1 = FALSE;
1987                G[i].national = FALSE;
1988                G[i].rtoi = NULL;
1989                G[i].itol = NULL;
1990                G[i].ltoi = NULL;
1991                G[i].itor = NULL;
1992            }
1993#endif /* OS2 */
1994            return(success = 1);
1995        }
1996
1997/* Not transparent, so get local set to translate it into */
1998
1999        s = "";
2000#ifdef OS2
2001        y = os2getcp();                 /* Default is current code page */
2002        switch (y) {
2003           case 437: s = "cp437"; break;
2004           case 850: s = "cp850"; break;
2005           case 852: s = "cp852"; break;
2006           case 862: s = "cp862"; break;
2007           case 866: s = "cp866"; break;
2008         }
2009#ifdef OS2ONLY
2010/*
2011   If the user has loaded a font with SET TERMINAL FONT then we want
2012   to change the default code page to the font that was loaded.
2013*/
2014        if (tt_font != TTF_ROM) {
2015            for (y = 0; y < ntermfont; y++ ) {
2016                if (termfont[y].kwval == tt_font) {
2017                    s = termfont[y].kwd;
2018                    break;
2019                }
2020            }
2021        }
2022#endif /* OS2ONLY */
2023#else
2024                                        /* Make current file char set */
2025        for (y = 0; y <= nfilc; y++)    /* be the default... */
2026          if (fcstab[y].kwval == fcharset) {
2027              s = fcstab[y].kwd;
2028              break;
2029          }
2030#endif /* OS2 */
2031
2032        if ((y = cmkey(
2033#ifdef CKOUNI
2034                       txrtab,ntxrtab,
2035#else /* CKOUNI */
2036                       fcstab,nfilc,
2037#endif /* CKOUNI */
2038                       "local character-set",s,xxstring)) < 0)
2039          return(y);
2040
2041#ifdef OS2
2042        if ((z = cmkey(graphsettab,ngraphset,
2043                       "DEC VT intermediate graphic set","all",xxstring)) < 0)
2044          return(z);
2045        {
2046            int eol;
2047            if ((eol = cmcfm()) < 0)
2048              return(eol); /* Confirm the command */
2049        }
2050        tcsr = x;                       /* Remote character set */
2051        tcsl = y;                       /* Local character set */
2052        if (z == TT_GR_ALL) {
2053            int i;
2054            for (i = 0; i < 4; i++) {
2055                G[i].def_designation = G[i].designation = x;
2056                G[i].init = TRUE;
2057                switch (cs_size(x)) {   /* 94, 96, or 128 */
2058                  case 128:
2059                  case 96:
2060                    G[i].size = G[i].def_size = cs96;
2061                    break;
2062                  case 94:
2063                    G[i].size = G[i].def_size = cs94;
2064                    break;
2065                  default:
2066                    G[i].size = G[i].def_size = csmb;
2067                    break;
2068                }
2069                G[i].c1 = G[i].def_c1 = x != tcsl && cs_is_std(x);
2070                G[i].national = cs_is_nrc(x);
2071            }
2072            if (!cs_is_nrc(x)) {
2073                G[0].designation = G[0].def_designation = FC_USASCII;
2074                G[0].size = G[0].def_size = cs94;
2075            }
2076        } else {                        /* Specific Gn */
2077            G[z].def_designation = G[z].designation = x;
2078            G[z].init = TRUE;
2079            switch (cs_size(x)) {       /* 94, 96, or 128 */
2080              case 128:
2081              case 96:
2082                G[i].size = G[i].def_size = cs96;
2083                break;
2084              case 94:
2085                G[i].size = G[i].def_size = cs94;
2086                break;
2087              default:
2088                G[i].size = G[i].def_size = csmb;
2089                break;
2090            }
2091            G[i].c1 = G[i].def_c1 = x != tcsl && cs_is_std(x);
2092            G[i].national = cs_is_nrc(x);
2093        }
2094#else /* not OS2 */
2095        if ((z = cmcfm()) < 0) return(z); /* Confirm the command */
2096        tcsr = x;                       /* Remote character set */
2097        tcsl = y;                       /* Local character set */
2098#endif /* OS2 */
2099        return(success = 1);
2100#endif /* CKOUNI */
2101#endif /* NOCSETS */
2102
2103#ifndef NOCSETS
2104      case XYTLCS:                      /* SET TERMINAL LOCAL-CHARACTER-SET */
2105        /* set terminal character-set <local> */
2106        s = "";
2107#ifdef OS2
2108        y = os2getcp();                 /* Default is current code page */
2109        switch (y) {
2110           case 437: s = "cp437"; break;
2111           case 850: s = "cp850"; break;
2112           case 852: s = "cp852"; break;
2113           case 862: s = "cp862"; break;
2114           case 866: s = "cp866"; break;
2115         }
2116#ifdef OS2ONLY
2117/*
2118   If the user has loaded a font with SET TERMINAL FONT then we want
2119   to change the default code page to the font that was loaded.
2120*/
2121        if (tt_font != TTF_ROM) {
2122            for (y = 0; y < ntermfont; y++ ) {
2123                if (termfont[y].kwval == tt_font) {
2124                    s = termfont[y].kwd;
2125                    break;
2126                }
2127            }
2128        }
2129#endif /* OS2ONLY */
2130#else /* OS2 */
2131                                        /* Make current file char set */
2132        for (y = 0; y <= nfilc; y++)    /* be the default... */
2133          if (fcstab[y].kwval == fcharset) {
2134              s = fcstab[y].kwd;
2135              break;
2136          }
2137#endif /* OS2 */
2138        if ((y = cmkey(
2139#ifdef CKOUNI
2140                       txrtab,ntxrtab,
2141#else /* CKOUNI */
2142                       fcstab,nfilc,
2143#endif /* CKOUNI */
2144                       "local character-set",s,xxstring)) < 0)
2145          return(y);
2146
2147#ifdef OS2
2148        if ((z = cmcfm()) < 0) return(z); /* Confirm the command */
2149        tcsl = y;                       /* Local character set */
2150        {
2151            int i;
2152            for (i = 0; i < 4; i++) {
2153                G[i].init = TRUE;
2154                x = G[i].designation;
2155                G[i].c1 = (x != tcsl) && cs_is_std(x);
2156                x = G[i].def_designation;
2157                G[i].def_c1 = (x != tcsl) && cs_is_std(x);
2158            }
2159        }
2160#else /* not OS2 */
2161        if ((z = cmcfm()) < 0) return(z); /* Confirm the command */
2162        tcsl = y;                       /* Local character set */
2163#endif /* OS2 */
2164        return(success = 1);
2165#endif /* NOCSETS */
2166
2167#ifndef NOCSETS
2168#ifdef CKOUNI
2169      case XYTUNI: /* SET TERMINAL UNICODE */
2170        return(success = seton(&tt_unicode));
2171#endif /* CKOUNI */
2172      case XYTRCS:                      /* SET TERMINAL REMOTE-CHARACTER-SET */
2173        /* set terminal character-set <remote> <Graphic-set> */
2174        if ((x = cmkey(
2175#ifdef CKOUNI
2176                txrtab, ntxrtab,
2177#else /* CKOUNI */
2178                ttcstab,ntermc,
2179#endif /* CKOUNI */
2180                       "remote terminal character-set","",xxstring)) < 0)
2181          return(x);
2182#ifndef KUI
2183        /* KUI can't have a Transparent Character Set */
2184#ifdef CKOUNI
2185        if (x == TX_TRANSP)
2186#else /* CKOUNI */
2187        if (x == FC_TRANSP)
2188#endif /* CKOUNI */
2189          {                             /* TRANSPARENT? */
2190              if ((x = cmcfm()) < 0)    /* Confirm the command */
2191                return(x);
2192              tcsr = tcsl;              /* Make both sets the same */
2193#ifdef OS2
2194#ifdef CKOUNI
2195              if (!cs_is_nrc(tcsl)) {
2196                  G[0].def_designation = G[i].designation = TX_ASCII;
2197                  G[0].init = TRUE;
2198                  G[0].def_c1 = G[i].c1 = FALSE;
2199                  G[0].size = cs94;
2200                  G[0].national = FALSE;
2201              }
2202              for (i = cs_is_nrc(tcsl) ? 0 : 1; i < 4; i++) {
2203                  G[i].def_designation = G[i].designation = tcsl;
2204                  G[i].init = TRUE;
2205                  G[i].def_c1 = G[i].c1 = FALSE;
2206                  switch (cs_size(G[i].designation)) { /* 94, 96, or 128 */
2207                    case 128:
2208                    case 96:
2209                      G[i].size = G[i].def_size = cs96;
2210                      break;
2211                    case 94:
2212                      G[i].size = G[i].def_size = cs94;
2213                      break;
2214                    default:
2215                      G[i].size = G[i].def_size = csmb;
2216                      break;
2217                  }
2218                  G[i].national = cs_is_nrc(x);
2219              }
2220#else /* CKOUNI */
2221              for (i = 0; i < 4; i++) {
2222                  G[i].def_designation = G[i].designation = FC_TRANSP;
2223                  G[i].init = FALSE;
2224                  G[i].size = G[i].def_size = cs96;
2225                  G[i].c1 = G[i].def_c1 = FALSE;
2226                  G[i].rtoi = NULL;
2227                  G[i].itol = NULL;
2228                  G[i].ltoi = NULL;
2229                  G[i].itor = NULL;
2230                  G[i].national = FALSE;
2231              }
2232#endif /* CKOUNI */
2233#endif /* OS2 */
2234              return(success = 1);
2235          }
2236#endif /* KUI */
2237#ifdef OS2
2238        if ((z = cmkey(graphsettab,ngraphset,
2239                       "DEC VT intermediate graphic set","all",xxstring)) < 0)
2240          return(z);
2241        {
2242            int eol;
2243            if ((eol = cmcfm()) < 0)    /* Confirm the command */
2244              return(eol);
2245        }
2246        tcsr = x;                       /* Remote character set */
2247        if (z == TT_GR_ALL) {
2248            int i;
2249            for (i = 0; i < 4; i++) {
2250                G[i].def_designation = G[i].designation = x;
2251                G[i].init = TRUE;
2252                switch (cs_size(x)) {   /* 94, 96, or 128 */
2253                  case 128:
2254                  case 96:
2255                    G[i].size = G[i].def_size = cs96;
2256                    break;
2257                  case 94:
2258                    G[i].size = G[i].def_size = cs94;
2259                    break;
2260                  default:
2261                    G[i].size = G[i].def_size = csmb;
2262                    break;
2263                }
2264                G[i].c1 = G[i].def_c1 = x != tcsl && cs_is_std(x);
2265                G[i].national = cs_is_nrc(x);
2266            }
2267            if (!cs_is_nrc(x)) {
2268                G[0].designation = G[0].def_designation = FC_USASCII;
2269                G[0].size = G[0].def_size = cs94;
2270            }
2271        } else {                        /* Specific Gn */
2272            G[z].def_designation = G[z].designation = x;
2273            G[z].init = TRUE;
2274            switch (cs_size(x)) {       /* 94, 96, or 128 */
2275              case 128:
2276              case 96:
2277                G[i].size = G[i].def_size = cs96;
2278                break;
2279              case 94:
2280                G[i].size = G[i].def_size = cs94;
2281                break;
2282              default:
2283                G[i].size = G[i].def_size = csmb;
2284                break;
2285            }
2286            G[z].c1 = G[z].def_c1 = x != tcsl && cs_is_std(x);
2287            G[z].national = cs_is_nrc(x);
2288        }
2289#else /* not OS2 */
2290        if ((z = cmcfm()) < 0) return(z); /* Confirm the command */
2291        tcsr = x;                       /* Remote character set */
2292#endif /* OS2 */
2293        return(success = 1);
2294#endif /* NOCSETS */
2295
2296      case XYTEC:                       /* SET TERMINAL ECHO */
2297        if ((x = cmkey(rltab,nrlt,"which side echos during CONNECT",
2298                       "remote", xxstring)) < 0) return(x);
2299        if ((y = cmcfm()) < 0) return(y);
2300        duplex = x;
2301        return(success = 1);
2302
2303      case XYTESC:                      /* SET TERM ESC */
2304        if ((x = cmkey(nabltab,2,"","enabled",xxstring)) < 0)
2305          return(x);
2306        if ((y = cmcfm()) < 0) return(y);
2307        tt_escape = x;
2308        return(1);
2309
2310      case XYTCRD:                      /* SET TERMINAL CR-DISPLAY */
2311        if ((x = cmkey(crdtab,2,"", "normal", xxstring)) < 0) return(x);
2312        if ((y = cmcfm()) < 0) return(y);
2313        tt_crd = x;
2314        return(success = 1);
2315
2316#ifdef OS2
2317      case XYTANS: {                    /* SET TERMINAL ANSWERBACK */
2318/*
2319  NOTE: We let them enable and disable the answerback sequence, but we
2320  do NOT let them change it, and we definitely do not let the host set it.
2321  This is a security feature.
2322
2323  As of 1.1.8 we allow the SET TERM ANSWERBACK MESSAGE <string> to be
2324  used just as MS-DOS Kermit does.  C0 and C1 controls as well as DEL
2325  are not allowed to be used as characters.  They are translated to
2326  underscore.  This may not be set by APC.
2327*/
2328          if ((x = cmkey(anbktab,nansbk,"", "off", xxstring)) < 0)
2329            return(x);
2330          if (x < 2) {
2331              if ((y = cmcfm()) < 0)
2332                return(y);
2333              tt_answer = x;
2334              return(success = 1);
2335          } else if ( x == 2 || x == 3) {
2336              int len = 0;
2337              extern int safeanswerbk;
2338              extern char useranswerbk[];
2339              if ((y = cmtxt("Answerback extension","",&s,xxstring)) < 0)
2340                return(y);
2341              if (apcactive == APC_LOCAL ||
2342                  (apcactive == APC_REMOTE && apcstatus != APC_UNCH))
2343                return(success = 0);
2344              len = strlen(s);
2345              if (x == 2) {
2346                  /* Safe Answerback's don't have C0/C1 chars */
2347                  for (z = 0; z < len; z++) {
2348                      if ((s[z] & 0x7F) <= SP || (s[z] & 0x7F) == DEL)
2349                        useranswerbk[z] = '_';
2350                      else
2351                        useranswerbk[z] = s[z];
2352                  }
2353                  useranswerbk[z] = '\0';
2354                  safeanswerbk = 1 ;    /* TRUE */
2355              } else {
2356                  strncpy( useranswerbk, s, 65 );
2357                  useranswerbk[65] = '\0';
2358                  safeanswerbk = 0;     /* FALSE */
2359              }
2360              updanswerbk();
2361              return(success = 1);
2362          } else
2363            return(success = 0);
2364      }
2365#endif /* OS2 */
2366
2367#ifdef CK_APC
2368      case XYTAPC:
2369        if ((y = cmkey(apctab,3,"application program command execution","",
2370                       xxstring)) < 0)
2371          return(y);
2372        if ((x = cmcfm()) < 0)
2373          return(x);
2374        if (apcactive == APC_LOCAL ||
2375            (apcactive == APC_REMOTE && apcstatus != APC_UNCH))
2376          return(success = 0);
2377        apcstatus = y; 
2378        return(success = 1);
2379
2380#ifdef CK_AUTODL
2381  case XYTAUTODL:
2382    return(success = seton(&autodl));   /* AUTODOWNLOAD ON, OFF */   
2383#endif /* CK_AUTODL */
2384#endif /* CK_APC */
2385
2386#ifdef OS2
2387      case XYTBEL:
2388        return(success = setbell());
2389#endif /* OS2 */
2390
2391      case XYTDEB:                      /* TERMINAL DEBUG */
2392        x = debses;                     /* What it was before */
2393        y = seton(&debses);             /* Go parse ON or OFF */
2394#ifdef OS2
2395        if (y > 0)                      /* Command succeeded? */
2396          if ((x != 0) && (debses == 0)) /* It was on and we turned it off? */
2397            os2debugoff();              /* Fix OS/2 coloration */
2398#endif /* OS2 */
2399        return(y);
2400
2401#ifdef OS2
2402      case XYTROL:                      /* SET TERMINAL ROLL */
2403        if ((y = cmkey(rolltab,nroll,"scrollback mode","insert",xxstring))<0)
2404            return(y);
2405        if ((x = cmcfm()) < 0) return(x);
2406        tt_roll[VTERM] = y;
2407        return(success = 1);
2408
2409      case XYTCTS:                      /* SET TERMINAL TRANSMIT-TIMEOUT */
2410        y = cmnum("Maximum seconds to allow CTS off during CONNECT",
2411                  "5",10,&x,xxstring);
2412        return(setnum(&tt_ctstmo,x,y,10000));
2413
2414      case XYTCPG: {                    /* SET TERMINAL CODE-PAGE */
2415        int i;
2416        int cp = -1;
2417        y = cmnum("PC code page to use during terminal emulation",
2418                  "850",10,&x,xxstring);
2419        if ((x = setnum(&cp,x,y,2000)) < 0) return(x);
2420        if (os2setcp(cp) != 1) {
2421#ifdef NT
2422            if (isWin95())
2423              printf(
2424                 "Sorry, Windows 95 does not support code page switching\n");
2425            else
2426#endif /* NT */
2427              printf(
2428                 "Sorry, %d is not a valid code page for this system.\n",cp);
2429            return(-9);
2430        }
2431    /* Force the terminal character-sets conversions to be updated */
2432        for ( i = 0; i < 4; i++ )
2433          G[i].init = TRUE;
2434        return(1);
2435    }
2436
2437#ifdef  COMMENT
2438      case XYTHCU:                      /* SET TERMINAL HIDE-CURSOR */
2439        return(seton(&tt_hide));
2440#endif /* COMMENT */
2441
2442      case XYTPAC:                      /* SET TERMINAL OUTPUT-PACING */
2443        y = cmnum(
2444           "Pause between sending each character during CONNECT, milliseconds",
2445                  "-1",10,&x,xxstring);
2446        return(setnum(&tt_pacing,x,y,10000));
2447
2448#ifdef OS2MOUSE
2449      case XYTMOU: {                    /* SET TERMINAL MOUSE */
2450          int old_mou = tt_mouse;
2451          seton(&tt_mouse);
2452          if ( tt_mouse != old_mou )
2453            if ( tt_mouse )
2454              os2_mouseon();
2455            else
2456              os2_mouseoff();
2457          return(1);
2458      }
2459#endif /* OS2MOUSE */
2460#endif /* OS2 */
2461
2462      case XYTWID: {
2463          if ((y = cmnum(
2464#ifdef OS2
2465                         "number of columns in display window during CONNECT",
2466#else
2467                         "number of columns on your screen",
2468#endif /* OS2 */
2469                         "80",10,&x,xxstring)) < 0)
2470            return(y);
2471          if ((y = cmcfm()) < 0) return(y);
2472#ifdef OS2
2473          if (x % 2) {
2474              printf("\n?The width must be an even value\n.");
2475              return(success = 0);
2476          }
2477
2478          if ( IsOS2FullScreen() ) {
2479              if ( x != 40 && x != 80 && x != 132 ) {
2480                  printf("\n?The width must be 40, 80,");
2481#ifdef NT
2482                  printf(" or 132 under Windows 95.\n.");
2483#else /* NT */
2484                  printf(" or 132 in a Full Screen session.\n.");
2485#endif /* NT */
2486                  return(success = 0);
2487              }
2488          } else {
2489              if ( !IsWARPed() && x != 80 ) {
2490                  printf("\n?OS/2 version is pre-WARP: the width must equal ");
2491                  printf("80 in a Windowed Session\n.");
2492                  return(success = 0);
2493                }
2494              if (x < 20 || x > MAXTERMCOL ) {
2495                  printf(
2496                    "\n?The width must be between 20 and %d\n.",MAXTERMCOL);
2497                  return(success = 0);
2498              }
2499          }
2500          if (x > 8192/(tt_rows[VTERM]+1)) {
2501              printf(
2502"\n?The max screen area is 8192 cells: %d(rows) x %d(cols) = %d cells.\n",
2503                     tt_rows[VTERM]+1,x,x*(tt_rows[VTERM]+1));
2504              return(success = 0);
2505          }
2506          tt_cols[VTERM] = x;
2507          tt_cols_usr = x;
2508#ifdef VSCRNINIT
2509          VscrnSetWidth( VTERM, x);
2510#ifdef TCPSOCKET
2511          if (nawsflg) {
2512              tn_snaws();
2513#ifdef RLOGCODE
2514              rlog_naws();
2515#endif /* RLOGCODE */
2516          }
2517#endif /* TCPSOCKET */
2518#else /* VSCRNINIT */
2519          VscrnSetWidth( VTERM, -1);
2520#endif /* VSCRNINIT */
2521/*
2522   We do not set tt_szchng here because that would result in the screen buffer
2523   being reallocated and the screen cleared.  But that is not necessary when
2524   only the screen width is being changed since the buffer allocates the full
2525   width
2526*/
2527#else  /* Not OS/2 */
2528          tt_cols = x;
2529#endif /* OS2 */
2530          return(success = 1);
2531      }
2532
2533      case XYTHIG:
2534        if ((y = cmnum(
2535#ifdef OS2
2536"number of rows in display window during CONNECT, not including status line",
2537#else
2538"number of rows on your screen",
2539#endif /* OS2 */
2540                       "24",10,&x,xxstring)) < 0)
2541          return(y);
2542        if ((y = cmcfm()) < 0) return(y);
2543
2544#ifdef OS2
2545        if (IsOS2FullScreen()) {
2546            if (tt_status && x != 24 && x != 42 && x != 49 && x != 59) {
2547                printf("\n?The height must be 24, 42, 49");
2548#ifdef NT
2549                printf(" or 59 under Windows 95.\n.");
2550#else /* NT */
2551                printf(" or 59 in a Full Screen session.\n.");
2552#endif /* NT */
2553                return(success = 0);
2554            } else if (!tt_status &&
2555                       x != 25 &&
2556                       x != 43 &&
2557                       x != 50 &&
2558                       x != 60) {
2559                printf("\n?The height must be 25, 43, 50");
2560#ifdef NT
2561                printf(" or 60 under Windows 95.\n.");
2562#else /* NT */
2563                printf(" or 60 in a Full Screen session.\n.");
2564#endif /* NT */
2565                return(success = 0);
2566            }
2567        } else {
2568            if (x < 8 || x > MAXTERMROW ) {
2569                printf("\n?The height must be between 8 and %d\n.",MAXTERMROW);
2570                return(success = 0);
2571            }
2572        }
2573        if (x > 8192/tt_cols[VTERM]) {
2574            printf(
2575"\n?The max screen area is 8192 cells: %d(rows) x %d(cols) = %d cells.\n",
2576                   x,tt_cols[VTERM],x*tt_cols[VTERM]);
2577            return(success = 0);
2578        }
2579#ifdef VSCRNINIT
2580        tt_szchng[VTERM] = 1;
2581        tt_rows[VTERM] = x;
2582        VscrnInit( VTERM );             /* Height set here */
2583#ifdef TCPSOCKET
2584        if (nawsflg){
2585            tn_snaws();
2586#ifdef RLOGCODE
2587            rlog_naws();
2588#endif /* RLOGCODE */
2589        }
2590#endif /* TCPSOCKET */
2591#else /* VSCRNINIT */
2592        tt_rows[VTERM] = x;
2593        VscrnSetHeight( VTERM, -1 );
2594        tt_szchng[VTERM] = 1;
2595#endif /* VSCRNINIT */
2596#else  /* Not OS/2 */
2597        tt_rows = x;
2598#endif /* OS2 */
2599        return(success = 1);
2600
2601#ifdef OS2
2602    case XYTUPD: {
2603        int mode, delay;
2604        if ((mode = cmkey(scrnupd,nscrnupd,"","fast",xxstring)) < 0) {
2605            return(mode);
2606        } else {
2607            y = cmnum(
2608            "Pause between FAST screen updates in CONNECT mode, milliseconds",
2609                      "100",10,&x,xxstring
2610                      );
2611            if (x < 0 || x > 1000 ) {
2612                printf(
2613            "\n?The update rate must be between 0 and 1000 milliseconds.\n"
2614                       );
2615                return(success = 0);
2616            }
2617            if ((y = cmcfm()) < 0) return(y);
2618
2619            updmode = tt_updmode = mode;
2620            return(setnum(&tt_update,x,y,10000));
2621        }
2622    }
2623    case XYTCTRL:
2624          if ((x = cmkey(termctrl,ntermctrl,"","7",xxstring)) < 0) {
2625              return(x);
2626          } else {
2627              if ((y = cmcfm()) < 0)
2628                  return(y);
2629              switch ( x ) {
2630              case 8:
2631                  send_c1 = send_c1_usr = TRUE;
2632                  break;
2633              case 7:
2634              default:
2635                  send_c1 = send_c1_usr = FALSE;
2636                  break;
2637              }
2638          }       
2639          return(success = TRUE);
2640          break;
2641
2642#ifdef PCFONTS
2643      case XYTFON:
2644        if ( !IsOS2FullScreen() ) {
2645            printf(
2646        "\n?SET TERMINAL FONT is only supported in Full Screen sessions.\n");
2647            return(success = FALSE);
2648        }
2649
2650        if ((x = cmkey(termfont,ntermfont,"","default",xxstring)) < 0) {
2651            return(x);
2652        } else {
2653            if ((y = cmcfm()) < 0) return(y);
2654            if ( !os2LoadPCFonts() ) {
2655                tt_font = x;
2656                return(success = TRUE);
2657            } else {
2658                printf(
2659      "\n?PCFONTS.DLL is not available in CKERMIT executable directory.\n");
2660                return(success = FALSE);
2661            }
2662        }
2663        break;
2664#endif /* PCFONTS */
2665      case XYTVCH:
2666        if ((x = cmkey(nabltab,2,"","enabled",xxstring)) < 0)
2667          return(x);
2668        if ((y = cmcfm()) < 0) return(y);
2669        tt_modechg = x;
2670        return(1);
2671
2672      case XYTSTAT: {
2673          extern int marginbot;
2674          if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
2675          if ((x = cmcfm()) < 0) return(x);
2676          if (y != tt_status || y != tt_status_usr) {
2677              /* Might need to fixup the margins */
2678              if ( marginbot == VscrnGetHeight(VTERM)-(tt_status?1:0) )
2679                if (y) {
2680                    marginbot--;
2681                } else {
2682                    marginbot++;
2683                }
2684              tt_status_usr = tt_status = y;
2685              if (y) {
2686#ifdef VSCRNINIT
2687                    tt_szchng[VTERM] = 2;
2688                    tt_rows[VTERM]--;
2689                    VscrnInit(VTERM);  /* Height set here */
2690#ifdef TCPSOCKET
2691                    if (nawsflg) {
2692                        tn_snaws();
2693#ifdef RLOGCODE
2694                        rlog_naws();
2695#endif /* RLOGCODE */
2696                    }
2697#endif /* TCPSOCKET */
2698#else /* VSCRNINIT */
2699                    tt_rows[VTERM]--;
2700                    VscrnSetHeight(VTERM, -1);
2701                    tt_szchng[VTERM] = 1;
2702#endif /* VSCRNINIT */
2703              } else {
2704#ifdef VSCRNINIT
2705                    tt_szchng[VTERM] = 1;
2706                    tt_rows[VTERM]++;
2707                    VscrnInit(VTERM);  /* Height set here */
2708#ifdef TCPSOCKET
2709                    if (nawsflg){
2710                        tn_snaws();
2711#ifdef RLOGCODE
2712                        rlog_naws();
2713#endif /* RLOGCODE */
2714                    }
2715#endif /* TCPSOCKET */
2716#else /* VSCRNINIT */
2717                    tt_rows[VTERM]++;
2718                    VscrnSetHeight(VTERM, -1);
2719                    tt_szchng[VTERM] = 1;
2720#endif /* VSCRNINIT */
2721              }
2722          }
2723          return(1);
2724      }
2725#endif /* OS2 */
2726
2727#ifdef NT       
2728      case XYTATTBUG:
2729        if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
2730        if ((x = cmcfm()) < 0) return(x);
2731        tt_attr_bug = y;
2732        return(1);
2733#endif /* NT */
2734
2735#ifdef OS2
2736      case XYTSGRC:
2737        if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
2738        if ((x = cmcfm()) < 0) return(x);
2739        sgrcolors = y;
2740        return(1);
2741
2742      case XYTSEND:
2743          if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
2744          if ((x = cmcfm()) < 0) return(x);
2745          tt_senddata = y;
2746          return(1);
2747
2748      case XYTSEOB:
2749          if ((y = cmkey(ttyseobtab,2,"","us_cr",xxstring)) < 0) return(y);
2750          if ((x = cmcfm()) < 0) return(x);
2751          wy_blockend = y;
2752          return(1);
2753
2754      case XYTATTR:
2755        if ((x = cmkey(ttyattrtab,nattrib,"","underline",xxstring)) < 0)
2756          return(x);
2757        switch ( x ) {
2758          case TTATTBLI:
2759            if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
2760            if ((x = cmcfm()) < 0) return(x);
2761            trueblink = y;
2762#ifndef KUI
2763            if ( !trueblink && trueunderline ) {
2764                trueunderline = 0;
2765                printf("\nWarning: Underline being simulated by color.");
2766            }
2767
2768#endif /* KUI */
2769            break;
2770          case TTATTREV:
2771            if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
2772            if ((x = cmcfm()) < 0) return(x);
2773            truereverse = y;
2774            break;
2775          case TTATTUND:
2776            if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
2777            if ((x = cmcfm()) < 0) return(x);
2778            trueunderline = y;
2779#ifndef KUI
2780            if ( !trueblink && trueunderline ) {
2781                trueblink = 1;
2782                printf("\nWarning: True blink mode is active.");
2783            }
2784#endif /* KUI */
2785            break;
2786        }
2787        return(1);
2788
2789      case XYTKEY: {                    /* SET TERMINAL KEY */
2790          int t, x, y;
2791          int clear = 0, deflt = 0;
2792          int flag = 0;
2793          int kc;                       /* Key code */
2794          char *s = NULL;               /* Key binding */
2795#ifndef NOKVERBS
2796          char *p = NULL;               /* Worker */
2797#endif /* NOKVERBS */
2798          con_event defevt;
2799          extern int os2gks;
2800          extern int mskkeys;
2801          extern int initvik;
2802
2803          if ((t = cmkey(ttkeytab,nttkey,"","",xxstring)) < 0)
2804            return(t);
2805          x_ifnum = 1;
2806          y = cmnum("numeric key code, or the words CLEAR or DEFAULT,",
2807                   "",10,&kc,xxstring);
2808          x_ifnum = 0;
2809          if (y < 0) {
2810              debug(F111,"SET KEY",atmbuf,y);
2811              if (y == -2) {            /* Not a valid number */
2812                  /* Check for SET TERM KEY <term> CLEAR */
2813                  if ((y = strlen(atmbuf)) < 0)
2814                    return(-2);
2815                  if (!xxstrcmp(atmbuf,"clear",y))
2816                    clear = 1;
2817                  else if (!xxstrcmp(atmbuf,"default",y))
2818                    deflt = 1;
2819                  else
2820                    return(-2);
2821                  if ((x = cmcfm()) < 0)
2822                    return(x);
2823                  if (clear)
2824                    clearkeymap(t);
2825                  if (deflt)
2826                    defaultkeymap(t);
2827                  initvik = 1;          /* Update the VIK table */
2828                  return(1);
2829              } else if (y == -3) {     /* SET TERM KEY <terminal> <Return> */
2830                  /* Prompt for a keystroke */
2831                  printf(" Press key to be defined: ");
2832                  conbin((char)escape); /* Put terminal in binary mode */
2833                  os2gks = 0;           /* Turn off Kverb preprocessing */
2834                  kc = congks(0);       /* Get character or scan code */
2835                  os2gks = 1;           /* Turn on Kverb preprocessing */
2836                  concb((char)escape);  /* Restore terminal to cbreak mode */
2837                  if (kc < 0) {         /* Check for error */
2838                      printf("?Error reading key\n");
2839                      return(0);
2840                  }
2841                  shokeycode(kc);       /* Show current definition */
2842                  flag = 1;             /* Remember it's a multiline command */
2843            } else                      /* Error */
2844              return(y);
2845          }
2846
2847    /* Normal SET TERMINAL KEY <terminal> <scancode> <value> command... */
2848
2849          if (mskkeys)
2850            kc = msktock(kc);
2851
2852          if (kc < 0 || kc >= KMSIZE) {
2853              printf("?key code must be between 0 and %d\n", KMSIZE - 1);
2854              return(-9);
2855          }
2856          if (kc == escape) {
2857              printf("Sorry, %d is the CONNECT-mode escape character\n",kc);
2858              return(-9);
2859          }
2860          wideresult = -1;
2861          if (flag) {
2862              cmsavp(psave,PROMPTL);
2863              cmsetp(" Enter new definition: ");
2864              cmini(ckxech);
2865          }
2866        def_again:
2867          if (flag) prompt(NULL);
2868          if ((y = cmtxt("key definition,\n\
2869or Ctrl-C to cancel this command,\n\
2870or Enter to restore default definition",
2871                         "",&s,NULL)) < 0) {
2872              if (flag)                 /* Handle parse errors */
2873                goto def_again;
2874              else
2875                return(y);
2876          }
2877          s = brstrip(s);
2878#ifndef NOKVERBS
2879          p = s;                        /* Save this place */
2880#endif /* NOKVERBS */
2881/*
2882  If the definition included any \Kverbs, quote the backslash so the \Kverb
2883  will still be in the definition when the key is pressed.  We don't do this
2884  in zzstring(), because \Kverbs are valid only in this context and nowhere
2885  else.
2886
2887  We use this code active for all versions that support SET KEY, even if they
2888  don't support \Kverbs, because otherwise \K would behave differently for
2889  different versions.
2890*/
2891          for (x = 0, y = 0; s[x]; x++, y++) { /* Convert \K to \\K */
2892              if ((x > 0) &&
2893                  (s[x] == 'K' || s[x] == 'k')
2894                  ) {                   /* Have K */
2895 
2896                  if ((x == 1 && s[x-1] == CMDQ) ||
2897                      (x > 1 && s[x-1] == CMDQ && s[x-2] != CMDQ)) {
2898                      line[y++] = CMDQ; /* Make it \\K */
2899                  }
2900                  if (x > 1 && s[x-1] == '{' && s[x-2] == CMDQ) {
2901                      line[y-1] = CMDQ; /* Have \{K */
2902                      line[y++] = '{';  /* Make it \\{K */
2903                  }
2904              }
2905              line[y] = s[x];
2906          }
2907          line[y++] = NUL;              /* Terminate */
2908          s = line + y + 1;             /* Point to after it */
2909          x = LINBUFSIZ - (int) strlen(line) - 1; /* Get remaining space */
2910          if ((x < (LINBUFSIZ / 2)) ||
2911              (zzstring(line, &s, &x) < 0)) { /* Expand variables, etc. */
2912              printf("?Key definition too long\n");
2913              if (flag) cmsetp(psave);
2914              return(-9);
2915          }
2916          s = line + y + 1;             /* Point to result. */
2917
2918#ifndef NOKVERBS
2919/*
2920  Special case: see if the definition starts with a \Kverb.
2921  If it does, point to it with p, otherwise set p to NULL.
2922*/
2923          p = s;
2924          if (*p++ == CMDQ) {
2925              if (*p == '{') p++;
2926              p = (*p == 'k' || *p == 'K') ? p + 1 : NULL;
2927          }
2928#endif /* NOKVERBS */
2929
2930          switch (strlen(s)) {          /* Action depends on length */
2931            case 0:                     /* Clear individual key def */
2932              deletekeymap(t,kc);
2933              break;
2934            case 1:
2935              defevt.type = key;        /* Single character */
2936              defevt.key.scancode = *s;
2937              break;
2938            default:                    /* Character string */
2939#ifndef NOKVERBS
2940              if (p) {
2941                  y = xlookup(kverbs,p,nkverbs,&x); /* Look it up */
2942                  /* Need exact match */
2943                  debug(F101,"set key kverb lookup",0,y);
2944                  if (y > -1) {
2945                      defevt.type = kverb;
2946                      defevt.kverb.id = y;
2947                      break;
2948                  }
2949              }
2950#endif /* NOKVERBS */
2951              defevt.type = macro;
2952              defevt.macro.string = (char *) malloc(strlen(s)+1);
2953              if (defevt.macro.string)
2954                strcpy(defevt.macro.string, s);
2955              break;
2956          }
2957          insertkeymap(t, kc, defevt);
2958          if (flag)
2959            cmsetp(psave);
2960          initvik = 1;                  /* Update VIK table */
2961          return(1);
2962      }
2963#endif /* OS2 */
2964
2965      default:                          /* Shouldn't get here. */
2966        return(-2);
2967    }
2968#endif /* MAC */
2969#ifdef COMMENT
2970    /*
2971      This was supposed to shut up picky compilers but instead it makes
2972      most compilers complain about "statement not reached".
2973    */
2974    return(-2);
2975#endif /* COMMENT */
2976#ifdef OS2
2977return(-2);
2978#endif /* OS2 */
2979}
2980
2981#ifdef OS2
2982int
2983settitle(void) {
2984    extern char usertitle[];
2985    if ((y = cmtxt("title text","",&s,xxstring)) < 0)
2986      return(y);
2987    strncpy(usertitle,s,63);
2988    return(1);
2989}
2990
2991static struct keytab dialertab[] = {    /* K95 Dialer types */
2992    "backspace",        0, 0,
2993    "enter",            1, 0
2994};
2995static int ndialer = 2;
2996
2997int
2998setdialer(void) {
2999    int t, x, y;
3000    int clear = 0, deflt = 0;
3001    int kc;                             /* Key code */
3002    char *s = NULL;                     /* Key binding */
3003#ifndef NOKVERBS
3004    char *p = NULL;                     /* Worker */
3005#endif /* NOKVERBS */
3006    con_event defevt;
3007    extern int os2gks;
3008    extern int mskkeys;
3009    extern int initvik;
3010
3011    if (( x = cmkey(dialertab, ndialer,
3012                    "Kermit-95 dialer work-arounds",
3013                    "", xxstring)) < 0 )
3014      return(x);
3015    switch (x) {
3016      case 0:                           /* Backspace */
3017        kc = 264;
3018        break;
3019      case 1:                           /* Enter */
3020        kc = 269;
3021        break;
3022      default:
3023        printf("Illegal value in setdialer()\n");
3024        return(-9);
3025    }
3026    if ((y = cmtxt("Key definition","",&s,xxstring)) < 0)
3027      return(y);
3028
3029    s = brstrip(s);
3030#ifndef NOKVERBS
3031    p = s;                              /* Save this place */
3032#endif /* NOKVERBS */
3033/*
3034  If the definition included any \Kverbs, quote the backslash so the \Kverb
3035  will still be in the definition when the key is pressed.  We don't do this
3036  in zzstring(), because \Kverbs are valid only in this context and nowhere
3037  else.
3038
3039  We use this code active for all versions that support SET KEY, even if they
3040  don't support \Kverbs, because otherwise \K would behave differently for
3041  different versions.
3042*/
3043    for (x = 0, y = 0; s[x]; x++, y++) { /* Convert \K to \\K */
3044        if ((x > 0) &&
3045            (s[x] == 'K' || s[x] == 'k')
3046            ) {                         /* Have K */
3047 
3048            if ((x == 1 && s[x-1] == CMDQ) ||
3049                (x > 1 && s[x-1] == CMDQ && s[x-2] != CMDQ)) {
3050                line[y++] = CMDQ;       /* Make it \\K */
3051            }
3052            if (x > 1 && s[x-1] == '{' && s[x-2] == CMDQ) {
3053                line[y-1] = CMDQ;       /* Have \{K */
3054                line[y++] = '{';        /* Make it \\{K */
3055            }
3056        }
3057        line[y] = s[x];
3058    }
3059    line[y++] = NUL;                    /* Terminate */
3060    s = line + y + 1;                   /* Point to after it */
3061    x = LINBUFSIZ - (int) strlen(line) - 1; /* Calculate remaining space */
3062    if ((x < (LINBUFSIZ / 2)) ||
3063        (zzstring(line, &s, &x) < 0)) { /* Expand variables, etc. */
3064        printf("?Key definition too long\n");
3065        return(-9);
3066    }
3067    s = line + y + 1;                   /* Point to result. */
3068
3069#ifndef NOKVERBS
3070/*
3071  Special case: see if the definition starts with a \Kverb.
3072  If it does, point to it with p, otherwise set p to NULL.
3073*/
3074    p = s;
3075    if (*p++ == CMDQ) {
3076        if (*p == '{') p++;
3077        p = (*p == 'k' || *p == 'K') ? p + 1 : NULL;
3078    }
3079#endif /* NOKVERBS */
3080
3081    /* Now reprogram the default value for all terminal types */
3082    /* remember to treat Wyse and Televideo terminals special */
3083    /* because of their use of Kverbs for Backspace and Enter */
3084    for (t = 0; t <= TT_MAX; t++) {
3085        if (ISWY50(t) || ISTVI(t)) {
3086            extern char * udkfkeys[] ;
3087            if (kc == 264) {            /* \Kwybs or \Ktvibs */
3088                if (udkfkeys[32])
3089                  free(udkfkeys[32]);
3090                udkfkeys[32] = strdup(s);
3091            }   
3092            if (kc == 269) {            /* \Kwyenter and \Kwyreturn */
3093                if (udkfkeys[39])       /* \Ktvienter and \Ktvireturn */
3094                  free(udkfkeys[39]);
3095                udkfkeys[39] = strdup(s);
3096                if (udkfkeys[49])
3097                  free(udkfkeys[49]);
3098                udkfkeys[49] = strdup(s);
3099            }
3100        } else {
3101            switch (strlen(s)) {        /* Action depends on length */
3102              case 0:                   /* Clear individual key def */
3103                deletekeymap(t,kc);
3104                break;
3105              case 1:
3106                defevt.type = key;      /* Single character */
3107                defevt.key.scancode = *s;
3108                break;
3109              default:                  /* Character string */
3110#ifndef NOKVERBS
3111                if (p) {
3112                    y = xlookup(kverbs,p,nkverbs,&x); /* Look it up */
3113                    /* Exact match req'd */
3114                    debug(F101,"set key kverb lookup",0,y);
3115                    if (y > -1) {
3116                        defevt.type = kverb;
3117                        defevt.kverb.id = y;
3118                        break;
3119                    }
3120                }
3121#endif /* NOKVERBS */
3122                defevt.type = macro;
3123                defevt.macro.string = (char *) malloc(strlen(s)+1);
3124                if (defevt.macro.string)
3125                  strcpy(defevt.macro.string, s);
3126                break;
3127            }
3128            insertkeymap( t, kc, defevt ) ;
3129            initvik = 1;                /* Update VIK table */
3130        }
3131    }
3132    return(1);
3133}
3134#endif /* OS2 */
3135
3136#ifdef NT
3137CHAR (*win95kcs)(CHAR) = NULL;
3138int win95altgr = 0;
3139int win95kl2 = 0;
3140
3141extern CHAR (*xlr[MAXTCSETS+1][MAXFCSETS+1])(CHAR);
3142extern struct keytab tcstab[];
3143extern int ntcs;
3144extern int maxow, owwait;               /* Overlapped I/O variables */
3145
3146int
3147setwin95( void ) {
3148    int x, y, z;
3149
3150    if (( y = cmkey(win95tab, nwin95,
3151                    "Windows 95 specific work-arounds",
3152                    "keyboard-translation",
3153                    xxstring)) < 0 )
3154        return (y);
3155    switch ( y ) {
3156      case XYWAGR:
3157        if ((y = cmkey(onoff,2,"Right-Alt is Alt-Gr","off",xxstring)) < 0)
3158          return(y);
3159        if ((x = cmcfm()) < 0) return(x);
3160        win95altgr = y;
3161        return(1);
3162
3163      case XYWOIO:
3164        if ((y = cmkey(onoff,2,"Use Overlapped I/O","off",xxstring)) < 0)
3165          return(y);
3166        if ( y ) {
3167            if ((x = cmnum("Num of max I/O requests","1",10,&z,xxstring)) < 0)
3168              return(x);
3169            if ( z < 1 || z > 5 ) {
3170                printf("?max I/O requests must be between 1 and 5.\n");
3171                return(-9);
3172            }
3173        } else
3174          z = 1;
3175        if ((x = cmcfm()) < 0) return(x);
3176        owwait = !y;
3177        maxow = z;
3178        return(1);
3179
3180      case XYWKEY:
3181        if (( z = cmkey(tcstab, ntcs,
3182                         "Keyboard Character Set",
3183                         "latin1-iso",
3184                         xxstring)) < 0 )
3185            return (z);
3186        if ((x = cmcfm()) < 0)
3187          return(x);
3188
3189        win95kl2 = (z == TC_2LATIN);
3190
3191        if ( z == TC_TRANSP )
3192          win95kcs = NULL;
3193        else
3194          win95kcs = xlr[z][tcsl];
3195        return(1);
3196
3197      default:
3198        printf("Illegal value in setwin95()\n");
3199        return(-9);
3200    }
3201}
3202#endif /* NT */
3203
3204#ifdef OS2
3205int
3206setprty (
3207#ifdef CK_ANSIC
3208    void
3209#endif /* CK_ANSIC */
3210/* setprty */ ) {
3211    int x, y, z;
3212
3213    if (( y = cmkey(prtytab, nprty,
3214                    "priority level of terminal and communication threads",
3215                    "foreground-server",
3216                    xxstring)) < 0 )
3217      return (y);
3218
3219    if ((x = cmcfm()) < 0)
3220      return (x);
3221    priority = y;
3222    return(TRUE);
3223}
3224
3225int
3226setbell(
3227#ifdef CK_ANSIC
3228    void
3229#endif /* CK_ANSIC */
3230 /* setbell */ ) {
3231    int z, y, x;
3232
3233    if ((y = cmkey(beltab,nbeltab,
3234        "how console and terminal bells should\nbe generated",
3235        "audible",xxstring)) < 0)
3236          return(y);
3237
3238    switch ( y ) {
3239        case XYB_NONE:
3240        case XYB_VIS:
3241            if ((x = cmcfm()) < 0)
3242                return(x);
3243            tt_bell = y;
3244            break;
3245
3246        case XYB_AUD:
3247            if ((x = cmkey(audibletab, naudibletab,
3248             "how audible console and terminal\nbells should be generated",
3249                "beep",xxstring))<0)
3250                return(x);
3251            if ((z = cmcfm()) < 0)
3252                return(z);
3253            tt_bell = y | x;
3254            break;
3255        }
3256        return(1);
3257    }
3258#endif /* OS2 */
3259
3260#ifdef OS2MOUSE
3261int
3262setmou(
3263#ifdef CK_ANSIC
3264       void
3265#endif /* CK_ANSIC */
3266 /* setmou */ ) {
3267    extern int initvik;
3268    int button = 0, event = 0;
3269    char * p;
3270
3271    if ((y = cmkey(mousetab,nmtab,"","",xxstring)) < 0)
3272      return(y);
3273
3274    if (y == XYM_ON) {                  /* MOUSE ACTIVATION */
3275        int old_mou = tt_mouse;
3276        seton(&tt_mouse);
3277        if ( tt_mouse != old_mou )
3278          if ( tt_mouse )
3279            os2_mouseon();
3280          else
3281            os2_mouseoff();
3282        return(1);
3283    }
3284
3285    if (y == XYM_CLEAR) {               /* Reset Mouse Defaults */
3286        mousemapinit(-1,-1);
3287        initvik = 1;                    /* Update VIK Table */
3288        return 1;
3289    }
3290    if (y != XYM_BUTTON) {              /* Shouldn't happen. */
3291        printf("Internal parsing error\n");
3292        return(-9);
3293    }
3294
3295    /* MOUSE EVENT ... */
3296
3297    if ((button = cmkey(mousebuttontab,nmbtab,
3298                        "Button number, one of the following","1",
3299                        xxstring)) < 0)
3300      return(button);
3301
3302    if ((y =  cmkey(mousemodtab,nmmtab,
3303                    "Keyboard modifier, one of the following",
3304                    "none",xxstring)) < 0)
3305      return(y);
3306
3307    event |= y;                         /* OR in the bits */
3308
3309    if ((y =  cmkey(mclicktab,nmctab,"","click",xxstring)) < 0)
3310      return(y);
3311
3312    /* Two bits are assigned, if neither are set then it is button one */
3313
3314    event |= y;                 /* OR in the bit */
3315
3316    wideresult = -1;
3317
3318    if ((y = cmtxt("definition,\n\
3319or Ctrl-C to cancel this command,\n\
3320or Enter to restore default definition",
3321                   "",&s,NULL)) < 0) {
3322        return(y);
3323    }
3324    s = brstrip(s);
3325    p = s;                              /* Save this place */
3326/*
3327  If the definition included any \Kverbs, quote the backslash so the \Kverb
3328  will still be in the definition when the key is pressed.  We don't do this
3329  in zzstring(), because \Kverbs are valid only in this context and nowhere
3330  else.  This code copied from SET KEY, q.v. for addt'l commentary.
3331*/
3332    for (x = 0, y = 0; s[x]; x++, y++) { /* Convert \K to \\K */
3333        if ((x > 0) &&
3334            (s[x] == 'K' || s[x] == 'k')
3335            ) {                         /* Have K */
3336           
3337            if ((x == 1 && s[x-1] == CMDQ) ||
3338                (x > 1 && s[x-1] == CMDQ && s[x-2] != CMDQ)) {
3339                line[y++] = CMDQ;       /* Make it \\K */
3340            }
3341            if (x > 1 && s[x-1] == '{' && s[x-2] == CMDQ) {
3342                line[y-1] = CMDQ;       /* Have \{K */
3343                line[y++] = '{';        /* Make it \\{K */
3344            }
3345        }
3346        line[y] = s[x];
3347    }
3348    line[y++] = NUL;                    /* Terminate */
3349    s = line + y + 1;                   /* Point to after it */
3350    x = LINBUFSIZ - (int) strlen(line) - 1; /* Calculate remaining space */
3351    if ((x < (LINBUFSIZ / 2)) ||
3352        (zzstring(line, &s, &x) < 0)) { /* Expand variables, etc. */
3353        printf("?Key definition too long\n");
3354        return(-9);
3355    }
3356    s = line + y + 1;                   /* Point to result. */
3357
3358#ifndef NOKVERBS
3359/*
3360  Special case: see if the definition starts with a \Kverb.
3361  If it does, point to it with p, otherwise set p to NULL.
3362*/
3363    p = s;
3364    if (*p++ == CMDQ) {
3365        if (*p == '{') p++;
3366        p = (*p == 'k' || *p == 'K') ? p + 1 : NULL;
3367    }
3368#else
3369    p = NULL;
3370#endif /* NOKVERBS */
3371
3372    /* free the old definition if necessary */
3373    if (mousemap[button][event].type == macro) {
3374        free( mousemap[button][event].macro.string);
3375        mousemap[button][event].macro.string = NULL;
3376    }
3377    switch (strlen(s)) {                /* Action depends on length */
3378      case 0:                           /* Reset to default binding */
3379        mousemapinit( button, event );
3380        break;
3381      case 1:                           /* Single character */
3382            mousemap[button][event].type = key;
3383        mousemap[button][event].key.scancode = *s;
3384        break;
3385      default:                          /* Character string */
3386#ifndef NOKVERBS
3387        if (p) {
3388            y = xlookup(kverbs,p,nkverbs,&x); /* Look it up */
3389            debug(F101,"set mouse kverb lookup",0,y); /* need exact match */
3390            if (y > -1) {
3391            /* Assign the kverb to the event */
3392            mousemap[button][event].type = kverb;
3393            mousemap[button][event].kverb.id = F_KVERB | y;
3394            break;
3395            }
3396        }
3397#endif /* NOKVERBS */
3398
3399       /* Otherwise, it's a macro, so assign the macro to the event */
3400       mousemap[button][event].type = macro;
3401       mousemap[button][event].macro.string = (MACRO) malloc(strlen(s)+1);
3402       if (mousemap[button][event].macro.string)
3403         strcpy((char *) mousemap[button][event].macro.string, s);
3404        break;
3405    }
3406    initvik = 1;                        /* Update VIK Table */
3407    return(1);
3408}
3409#endif /* OS2MOUSE */
3410#endif /* NOLOCAL */
3411
3412int                                     /* SET SEND/RECEIVE */
3413setsr(xx, rmsflg) int xx; int rmsflg; {
3414    if (xx == XYRECV)
3415      strcpy(line,"Parameter for inbound packets");
3416    else
3417      strcpy(line,"Parameter for outbound packets");
3418 
3419    if (rmsflg) {
3420        if ((y = cmkey(rsrtab,nrsrtab,line,"",xxstring)) < 0) {
3421            if (y == -3) {
3422                printf("?Remote receive parameter required\n");
3423                return(-9);
3424            } else return(y);
3425        }
3426    } else {
3427        if ((y = cmkey(srtab,nsrtab,line,"",xxstring)) < 0) return(y);
3428    }
3429    switch (y) {
3430      case XYQCTL:                      /* CONTROL-PREFIX */
3431        if ((x = cmnum("ASCII value of control prefix","",10,&y,xxstring)) < 0)
3432          return(x);
3433        if ((x = cmcfm()) < 0) return(x);
3434        if ((y > 32 && y < 63) || (y > 95 && y < 127)) {
3435            if (xx == XYRECV)
3436              ctlq = (CHAR) y;          /* RECEIVE prefix, use with caution! */
3437            else
3438              myctlq = (CHAR) y;        /* SEND prefix, OK to change */
3439            return(success = 1);
3440        } else {
3441            printf("?Illegal value for prefix character\n");
3442            return(-9);
3443        }
3444
3445      case XYEOL:
3446        if ((y = setcc("13",&z)) < 0)
3447            return(y);
3448        if (z > 31) {
3449            printf("Sorry, the legal values are 0-31\n");
3450            return(-9);
3451        }
3452        if (xx == XYRECV)
3453          eol = (CHAR) z;
3454        else
3455          seol = (CHAR) z;
3456        return(success = y);
3457 
3458      case XYLEN:
3459        y = cmnum("Maximum number of characters in a packet","90",10,&x,
3460                  xxstring);
3461        if (xx == XYRECV) {             /* Receive... */
3462            if ((y = setnum(&z,x,y,maxrps)) < 0)
3463              return(y);
3464            if (z < 10) {
3465                printf("Sorry, 10 is the minimum\n");
3466                return(-9);
3467            }
3468            if (rmsflg) {
3469                tp = tmpbuf;
3470                sprintf(tp,"%d",z);
3471                sstate = setgen('S', "401", tp, "");
3472                return((int) sstate);
3473            } else {
3474                if (protocol == PROTO_K) {
3475                    if (z > MAXRP) z = MAXRP;
3476                    y = adjpkl(z,wslotr,bigrbsiz);
3477                    if (y != z) {
3478                        urpsiz = y;
3479                        if (
3480#ifndef NOSPL
3481                            cmdlvl == 0
3482#else
3483                            tlevel < 0
3484#endif /* NOSPL */
3485                            )
3486                          if (msgflg) printf(
3487" Adjusting receive packet-length to %d for %d window slots\n",
3488                                             y, wslotr);
3489                    }
3490                    urpsiz = y;
3491                    ptab[protocol].rpktlen = urpsiz;
3492                    rpsiz =  (y > 94) ? 94 : y;
3493                } else {
3494#ifdef CK_XYZ
3495                    if (protocol == PROTO_X && z != 128 && z != 1024) {
3496                        printf("Sorry, bad packet length for XMODEM.\n");
3497                        printf("Please use 128 or 1024.\n");
3498                        return(-9);
3499                    }
3500#endif /* CK_XYZ */
3501                    urpsiz = rpsiz = z;
3502                }
3503            }
3504        } else {                        /* Send... */
3505            if ((y = setnum(&z,x,y,maxsps)) < 0)
3506              return(y);
3507            if (z < 10) {
3508                printf("Sorry, 10 is the minimum\n");
3509                return(-9);
3510            }
3511            if (protocol == PROTO_K) {
3512                if (z > MAXSP) z = MAXSP;
3513                spsiz = z;              /* Set it */
3514                y = adjpkl(spsiz,wslotr,bigsbsiz);
3515                if (y != spsiz &&
3516#ifndef NOSPL
3517                    cmdlvl == 0
3518#else
3519                    tlevel < 0
3520#endif /* NOSPL */
3521                    )
3522                  if (msgflg)
3523                    printf("Adjusting packet size to %d for %d window slots\n",
3524                           y,wslotr);
3525            } else
3526              y = z;
3527#ifdef CK_XYZ
3528            if (protocol == PROTO_X && z != 128 && z != 1024) {
3529                printf("Sorry, bad packet length for XMODEM.\n");
3530                printf("Please use 128 or 1024.\n");
3531                return(-9);
3532            }
3533#endif /* CK_XYZ */
3534            spsiz = spmax = spsizr = y; /* Set it and flag that it was set */
3535            spsizf = 1;                 /* to allow overriding Send-Init. */
3536            ptab[protocol].spktflg = spsizf;
3537            ptab[protocol].spktlen = spsiz;
3538        }
3539        if (pflag && protocol == PROTO_K &&
3540#ifndef NOSPL
3541            cmdlvl == 0
3542#else
3543            tlevel < 0
3544#endif /* NOSPL */
3545            ) {
3546            if (z > 94 && msgflg) {
3547                /* printf("Extended-length packets requested.\n"); */
3548                if (bctr < 2 && z > 200) printf("\
3549Remember to SET BLOCK 2 or 3 for long packets.\n");
3550            }
3551            if (speed <= 0L) speed = ttgspd();
3552#ifdef COMMENT
3553/*
3554  Kermit does this now itself.
3555*/
3556            if (speed <= 0L && z > 200 && msgflg) {
3557                printf("\
3558Make sure your timeout interval is long enough for %d-byte packets.\n",z);
3559            }
3560#endif /* COMMENT */
3561        }
3562        return(success = y);
3563
3564      case XYMARK:
3565#ifdef DOOMSDAY
3566/*
3567  Printable start-of-packet works for UNIX and VMS only!
3568*/
3569        x_ifnum = 1;
3570        y = cmnum("Code for packet-start character","1",10,&x,xxstring);
3571        x_ifnum = 0;
3572        if ((y = setnum(&z,x,y,126)) < 0) return(y);
3573#else
3574        if ((y = setcc("1",&z)) < 0)
3575            return(y);
3576#endif /* DOOMSDAY */
3577        if (xx == XYRECV)
3578          stchr = (CHAR) z;
3579        else
3580          mystch = (CHAR) z;
3581        return(success = y);
3582
3583      case XYNPAD:                      /* PADDING */
3584        y = cmnum("How many padding characters for inbound packets","0",10,&x,
3585                  xxstring);
3586        if ((y = setnum(&z,x,y,94)) < 0) return(y);
3587        if (xx == XYRECV)
3588          mypadn = (CHAR) z;
3589        else
3590          npad = (CHAR) z;
3591        return(success = y);
3592 
3593      case XYPADC:                      /* PAD-CHARACTER */
3594        if ((y = setcc("0",&z)) < 0) return(y);
3595        if (xx == XYRECV) mypadc = z; else padch = z;
3596        return(success = y);
3597 
3598      case XYTIMO:                      /* TIMEOUT */
3599        if (xx == XYRECV) {
3600            char buf[16];               /* Construct default */
3601            sprintf(buf,"%d",URTIME);
3602            y = cmnum("Packet timeout interval",buf,10,&x,xxstring);
3603            if ((y = setnum(&z,x,y,94)) < 0) return(y);
3604
3605            if (rmsflg) {               /* REMOTE SET RECEIVE TIMEOUT */
3606                tp = tmpbuf;            /*   Tell Kermit server what */
3607                sprintf(tp,"%d",z);     /*   timeout to ask me to use. */
3608                sstate = setgen('S', "402", tp, "");
3609                return((int) sstate);
3610            } else {                    /* SET RECEIVE TIMEOUT */
3611                pkttim = z;             /*   Value to put in my negotiation */
3612            }                           /*   packet for other Kermit to use */
3613
3614        } else {                        /* SET SEND TIMEOUT */
3615#ifdef CK_TIMERS
3616            extern int rttflg, mintime, maxtime;
3617            int tmin, tmax;
3618#endif /* CK_TIMERS */
3619            y = cmnum("Packet timeout interval","",10,&x,xxstring);
3620            if (y == -3) {              /* They cancelled a previous */
3621                x = DMYTIM;             /* SET SEND command, so restore */
3622                y = 0;                  /* the default */
3623                timef = 0;              /* and turn off the override flag */
3624            }
3625#ifdef CK_TIMERS           
3626            if (y < 0) return(y);
3627            if (x < 0) {
3628                printf("?Out of range - %d\n",x);
3629                return(-9);
3630            }
3631            if ((z = cmkey(timotab,2,"","dynamic",xxstring)) < 0) return(z);
3632            if (z) {
3633                if ((y = cmnum("Minimum timeout to allow",
3634                               "1",10,&tmin,xxstring)) < 0)
3635                  return(y);
3636                if (tmin < 1) {
3637                    printf("?Out of range - %d\n",x);
3638                    return(-9);
3639                }
3640                if ((y = cmnum("Maximum timeout to allow",
3641                               "0",10,&tmax,xxstring)) < 0)
3642                  return(y);
3643                /* 0 means let Kermit choose, < 0 means no maximum */
3644            }
3645            if ((y = cmcfm()) < 0)
3646              return(y);
3647            rttflg = z;                 /* Round-trip timer flag */
3648            z = x;
3649#else
3650            if ((y = setnum(&z,x,y,94)) < 0)
3651              return(y);
3652#endif /* CK_TIMERS */
3653            timef = 1;                  /* Turn on the override flag */
3654            timint = rtimo = z;         /* Override value for me to use */
3655            if (rttflg) {               /* Lower and upper bounds */
3656                mintime = tmin;
3657                maxtime = tmax;
3658            }
3659        }
3660        return(success = 1);
3661
3662      case XYFPATH:                     /* PATHNAMES */
3663        if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
3664        if ((x = cmcfm()) < 0) return(x);
3665        if (xx == XYRECV) {             /* SET RECEIVE PATHNAMES */
3666            fnrpath = 1 - y;            /* OFF (with their heads!), ON */
3667            ptab[protocol].fnrp = fnrpath;
3668        } else {                        /* SET SEND PATHNAMES */
3669            fnspath = 1 - y;            /* OFF, ON */
3670            ptab[protocol].fnsp = fnspath;
3671        }
3672        return(success = 1);            /* Note: 0 = ON, 1 = OFF */
3673        /* In other words, ON = leave pathnames ON, OFF = take them off. */
3674
3675      case XYPAUS:                      /* SET SEND/RECEIVE PAUSE */
3676        y = cmnum("Milliseconds to pause between packets","0",10,&x,xxstring);
3677        if ((y = setnum(&z,x,y,15000)) < 0)
3678          return(y);
3679        pktpaus = z;
3680        return(success = 1);
3681
3682      default:
3683        return(-2);
3684    }                                   /* End of SET SEND/RECEIVE... */
3685}
3686
3687#ifndef NOXMIT
3688int
3689setxmit() {
3690    if ((y = cmkey(xmitab,nxmit,"","",xxstring)) < 0) return(y);
3691    switch (y) {
3692      case XMITE:                       /* EOF */
3693        y = cmtxt("Characters to send at end of file,\n\
3694 Use backslash codes for control characters","",&s,xxstring);
3695        if (y < 0) return(y);
3696        if ((int)strlen(s) > XMBUFL) {
3697            printf("?Too many characters, %d maximum\n",XMBUFL);
3698            return(-2);
3699        }
3700        strcpy(xmitbuf,s);
3701        return(success = 1);
3702
3703      case XMITF:                       /* Fill */
3704        y = cmnum("Numeric code for blank-line fill character","0",10,&x,
3705                  xxstring);
3706        if ((y = setnum(&z,x,y,127)) < 0) return(y);
3707        xmitf = z;
3708        return(success = 1);
3709      case XMITL:                       /* Linefeed */
3710        return(seton(&xmitl));
3711      case XMITS:                       /* Locking-Shift */
3712        return(seton(&xmits));
3713      case XMITP:                       /* Prompt */
3714        y = cmnum("Numeric code for host's prompt character, 0 for none",
3715                  "10",10,&x,xxstring);
3716        if ((y = setnum(&z,x,y,127)) < 0) return(y);
3717        xmitp = z;
3718        return(success = 1);
3719      case XMITX:                       /* Echo */
3720        return(seton(&xmitx));
3721      case XMITW:                       /* Pause */
3722        y = cmnum("Number of milliseconds to pause between binary characters\n\
3723or text lines during transmission","0",10,&x,xxstring);
3724        if ((y = setnum(&z,x,y,1000)) < 0) return(y);
3725        xmitw = z;
3726        return(success = 1);
3727      default:
3728        return(-2);
3729    }
3730}
3731#endif /* NOXMIT */
3732
3733/*  D O R M T  --  Do a remote command  */
3734 
3735VOID
3736rmsg() {
3737    if (pflag)
3738      printf(
3739#ifdef CK_NEED_SIG
3740       " Type your escape character, %s, followed by X or E to cancel.\n",
3741       dbchr(escape)
3742#else
3743       " Press the X or E key to cancel.\n"
3744#endif /* CK_NEED_SIG */
3745      );
3746}
3747
3748/*  R E M C F M  --  Confirm a REMOTE command  */
3749/*
3750  Like cmcfm(), but allows for a redirection indicator on the end,
3751  like "> filename" or "| command".  Returns what cmcfm() would have
3752  returned: -1 if reparse needed, etc etc blah blah.  On success,
3753  returns 1 with:
3754
3755    char * remdest containing the name of the file or command.
3756    int remfile set to 1 if there is to be any redirection.
3757    int rempipe set to 1 if remdest is a command, 0 if it is a file.
3758*/
3759static int
3760remcfm() {
3761    int x;
3762    char *s;
3763    char c;
3764
3765    remfile = 0;
3766    rempipe = 0;
3767    if ((x = cmtxt(
3768             "> filename, | command,\n\
3769or type carriage return to confirm the command",
3770                   "",&s,xxstring)) < 0)
3771      return(x);
3772    if (remdest) {
3773        free(remdest);
3774        remdest = NULL;
3775    }
3776    if (!*s)                            /* No redirection indicator */
3777      return(1);
3778    c = *s;                             /* We have something */
3779    if (c != '>' && c != '|') {         /* Is it > or | ? */
3780        printf("?Not confirmed\n");     /* No */
3781        return(-9);
3782    }
3783    s++;                                /* See what follows */
3784    if (c == '>' && *s == '>') {        /* Allow for ">>" too */
3785        s++;
3786        remappd = 1;                    /* Append to output file */
3787    }
3788    while (*s == SP || *s == HT) s++;   /* Strip intervening whitespace */
3789    if (!*s) {
3790        printf("?%s missing\n", c == '>' ? "Filename" : "Command");
3791        return(-9);
3792    }
3793    if (c == '>' && zchko(s) < 0) {     /* Check accessibility */
3794        printf("?Access denied - %s\n", s);
3795        return(-9);
3796    }
3797    remfile = 1;                        /* Set global results */
3798    rempipe = (c == '|');
3799    makestr(&remdest,s);
3800#ifndef NODEBUG
3801    if (deblog) {
3802        debug(F101,"remcfm remfile","",remfile);
3803        debug(F101,"remcfm remappd","",remappd);
3804        debug(F101,"remcfm rempipe","",rempipe);
3805        debug(F110,"remcfm remdest",remdest, 0);
3806    }
3807#endif /* NODEBUG */
3808    return(1);
3809}
3810
3811/*  R E M T X T  --  Like remcfm()...  */
3812/*
3813   ... but for REMOTE commands that end with cmtxt().
3814   Here we must decipher braces to discover whether the trailing
3815   redirection indicator is intended for local use, or to be sent out
3816   to the server, as in:
3817
3818     remote host blah blah > file                 This end
3819     remote host { blah blah } > file             This end
3820     remote host { blah blah > file }             That end
3821     remote host { blah blah > file } > file      Both ends
3822
3823   Pipes too:
3824
3825     remote host blah blah | cmd                  This end
3826     remote host { blah blah } | cmd              This end
3827     remote host { blah blah | cmd }              That end
3828     remote host { blah blah | cmd } | cmd        Both ends
3829
3830   Or both:
3831
3832     remote host blah blah | cmd > file           This end, etc etc...
3833
3834   Note: this really only makes sense for REMOTE HOST, but why be picky?
3835   Call after calling cmtxt(), with pointer to string that cmtxt() parsed,
3836   as in "remtxt(&s);".
3837
3838   Returns:
3839    1 on success with braces & redirection things removed & pointer updated,
3840   -9 on failure (bad indirection), after printing error message.
3841*/
3842static int
3843remtxt(p) char ** p; {
3844    int i, x, bpos, ppos;
3845    char c, *s, *q;
3846
3847    remfile = 0;                        /* Initialize global results */
3848    rempipe = 0;
3849    remappd = 0;
3850    if (remdest) {
3851        free(remdest);
3852        remdest = NULL;
3853    }
3854    s = *p;
3855    if (!*s)                            /* No redirection indicator */
3856      return(1);                        /* Done */
3857
3858    bpos = -1;                          /* Position of > (bracket) */
3859    ppos = -1;                          /* Position of | (pipe) */
3860    x = strlen(s);                      /* Length of cmtxt() string */
3861
3862    for (i = x-1; i >= 0; i--) {        /* Search right to left. */
3863        c = s[i];
3864        if (c == '}')                   /* Break on first right brace */
3865          break;                        /* Don't look at contents of braces */
3866        else if (c == '>')              /* Record position of > */
3867          bpos = i;
3868        else if (c == '|')              /* and of | */
3869          ppos = i;
3870    }
3871    if (bpos < 0 && ppos < 0) {         /* No redirectors. */
3872        s = brstrip(s);                 /* Remove outer braces if any. */
3873        *p = s;                         /* Point to result */
3874        return(1);                      /* and return. */
3875    }   
3876    remfile = 1;                        /* It's | or > */
3877    i = -1;                             /* Get leftmost symbol */
3878    if (bpos > -1)                      /* Bracket */
3879      i = bpos;
3880    if (ppos > -1 && ppos < bpos) {     /* or pipe */
3881        i = ppos;
3882        rempipe = 1;
3883    }
3884    c = s[i];                           /* Copy of symbol */
3885
3886    if (c == '>' && s[i+1] == '>')      /* ">>" for append? */
3887      remappd = 1;                     /* It's not just a flag it's a number */
3888
3889    q = s + i + 1 + remappd;            /* Point past symbol in string */
3890    while (*q == SP || *q == HT) q++;   /* and any intervening whitespace */
3891    if (!*q) {
3892        printf("?%s missing\n", c == '>' ? "Filename" : "Command");
3893        return(-9);
3894    }
3895    if (c == '>' && zchko(q) < 0) {     /* (Doesn't work for | cmd > file) */
3896        printf("?Access denied - %s\n", q);
3897        return(-9);
3898    }
3899    makestr(&remdest,q);                /* Create the destination string */
3900    q = s + i - 1;                      /* Point before symbol */
3901    while (q > s && (*q == SP || *q == HT)) /* Strip trailing whitespace */
3902      q--;
3903    *(q+1) = NUL;                       /* Terminate the string. */
3904    s = brstrip(s);                     /* Remove any braces */
3905    *p = s;                             /* Set return value */
3906
3907#ifndef NODEBUG
3908    if (deblog) {
3909        debug(F101,"remtxt remfile","",remfile);
3910        debug(F101,"remtxt remappd","",remappd);
3911        debug(F101,"remtxt rempipe","",rempipe);
3912        debug(F110,"remtxt remdest",remdest, 0);
3913        debug(F110,"remtxt command",s,0);
3914    }
3915#endif /* NODEBUG */
3916
3917    return(1);
3918}
3919
3920int
3921dormt(xx) int xx; {                     /* REMOTE commands */
3922    int x, y, retcode;
3923    char *s, sbuf[50], *s2;
3924 
3925    remfile = 0;                        /* Clear these */
3926    rempipe = 0;
3927    remappd = 0;
3928
3929    if (xx < 0) return(xx);             /* REMOTE what? */
3930
3931    if (xx == XZSET) {                  /* REMOTE SET */
3932        if ((y = cmkey(rmstab,nrms,"","",xxstring)) < 0) {
3933            if (y == -3) {
3934                printf("?Parameter name required\n");
3935                return(-9);
3936            } else return(y);
3937        }
3938        return(doprm(y,1));
3939    }
3940
3941    switch (xx) {                       /* Others... */
3942 
3943      case XZCWD:                       /* CWD (CD) */
3944        if ((x = cmtxt("Remote directory name","",&s,xxstring)) < 0)
3945          return(x);
3946        if ((x = remtxt(&s)) < 0)
3947          return(x);
3948        debug(F111,"XZCWD: ",s,x);
3949        *sbuf = NUL;
3950        s2 = sbuf;
3951/*
3952  The following is commented out because since the disappearance of the
3953  DECSYSTEM-20 from the planet, no known computer requires a password for
3954  changing directory.
3955*/
3956#ifdef DIRPWDPR
3957        if (*s != NUL) {                /* If directory name given, */
3958                                        /* get password on separate line. */
3959            if (tlevel > -1) {          /* From take file... */
3960 
3961                if (fgets(sbuf,50,tfile[tlevel]) == NULL)
3962                  fatal("take file ends prematurely in 'remote cwd'");
3963                debug(F110," pswd from take file",s2,0);
3964                for (x = (int)strlen(sbuf);
3965                     x > 0 && (sbuf[x-1] == NL || sbuf[x-1] == CR);
3966                     x--)
3967                  sbuf[x-1] = '\0';
3968 
3969            } else {                    /* From terminal... */
3970 
3971                printf(" Password: ");  /* get a password */
3972                while (
3973#ifdef OS2
3974                       ((x = is_a_tty(0) ? coninc(0) : /* with no echo ... */
3975                         getchar()) != NL) && (x != CR)
3976#else
3977                       ((x = getchar()) != NL) && (x != CR)
3978#endif /* OS2 */
3979                       ) {
3980                    if ((x &= 0177) == '?') {
3981                        printf("? Password of remote directory\n Password: ");
3982                        s2 = sbuf;
3983                        *sbuf = NUL;
3984                    } else if (x == ESC) /* Mini command line editor... */
3985                      bleep(BP_WARN);
3986                    else if (x == BS || x == 0177)
3987                      s2--;
3988                    else if (x == 025) {        /* Ctrl-U */
3989                        s2 = sbuf;
3990                        *sbuf = NUL;
3991                    } else
3992                      *s2++ = x;
3993                }
3994                *s2 = NUL;
3995                putchar('\n');
3996            }
3997            s2 = sbuf;
3998        } else s2 = "";
3999#endif /* DIRPWDPR */
4000
4001        debug(F110," password",s2,0);
4002        sstate = setgen('C',s,s2,"");
4003        retcode = 0;
4004        break;
4005
4006      case XZDEL:                               /* Delete */
4007        if ((x = cmtxt("Name of remote file(s) to delete",
4008                       "",&s,xxstring)) < 0) {
4009            if (x == -3) {
4010                printf("?Name of remote file(s) required\n");
4011                return(-9);
4012            } else return(x);
4013        }
4014        if ((x = remtxt(&s)) < 0)
4015          return(x);
4016        if (local) ttflui();            /* If local, flush tty input buffer */
4017        retcode = sstate = rfilop(s,'E');
4018        break;
4019 
4020      case XZDIR:                       /* Directory */
4021        if ((x = cmtxt("Remote directory or file specification","",&s,
4022                       xxstring)) < 0)
4023          return(x);
4024        if ((x = remtxt(&s)) < 0)
4025          return(x);
4026        if (local) ttflui();            /* If local, flush tty input buffer */
4027        rmsg();
4028        retcode = sstate = setgen('D',s,"","");
4029        break;
4030 
4031      case XZHLP:                       /* Help */
4032        if ((x = remcfm()) < 0) return(x);
4033        sstate = setgen('H',"","","");
4034        retcode = 0;
4035        break;
4036
4037#ifndef NOPUSH
4038/* Why is this ifdef'd? */
4039
4040      case XZHOS:                       /* Host */
4041        if (nopush) {
4042            if ((x = remcfm()) < 0) return(x);
4043            printf("?Not available - %s\n",cmdbuf);
4044            return(-2);
4045        }
4046        if ((x = cmtxt("Command for remote system","",&cmarg,xxstring)) < 0)
4047          return(x);
4048        if ((x = remtxt(&cmarg)) < 0)
4049          return(x);
4050        if ((y = (int)strlen(cmarg)) < 1)
4051          return(x);
4052        rmsg();
4053        retcode = sstate = 'c';
4054        break;
4055#endif /* NOPUSH */
4056
4057#ifndef NOFRILLS
4058      case XZKER:
4059        if ((x = cmtxt("Command for remote Kermit","",&cmarg,xxstring)) < 0)
4060          return(x);
4061        if ((x = remtxt(&cmarg)) < 0)
4062          return(x);
4063        if ((int)strlen(cmarg) < 1)  {
4064            if (x == -3) {
4065                printf("?Remote Kermit command required\n");
4066                return(-9);
4067            } else return(x);
4068        }
4069        retcode = sstate = 'k';
4070        rmsg();
4071        break;
4072
4073      case XZLGI: {                     /* Login */
4074          char *p1, *p2, *p3;
4075          if ((x = cmfld("User ID","",&s,xxstring)) < 0)
4076            return(x);
4077          if ((p1 = malloc((int)strlen(s) + 1)) == NULL) {
4078              printf("Internal error: malloc\n");
4079              return(-2);
4080          } else
4081            strcpy(p1,s);
4082          if ((x = cmfld("Password","",&s,xxstring)) < 0)
4083            return(x);
4084          if ((p2 = malloc((int)strlen(s) + 1)) == NULL) {
4085              printf("Internal error: malloc\n");
4086              return(-2);
4087          } else
4088            strcpy(p2,s);
4089          if ((x = cmtxt("Account or carriage return","",
4090                         &s,xxstring)) < 0 && x != -3)
4091            return(x);
4092          if ((x = remtxt(&s)) < 0)
4093            return(x);
4094          if ((p3 = malloc((int)strlen(s) + 1)) == NULL) {
4095              printf("Internal error: malloc\n");
4096              return(-2);
4097          } else
4098            strcpy(p3,s);
4099          sstate = setgen('I',p1,p2,p3);
4100          if (p3) { free(p3); p3 = NULL; }
4101          if (p2) { free(p2); p2 = NULL; }
4102          if (p1) { free(p1); p1 = NULL; }
4103          retcode = 0;
4104          break;
4105      }
4106
4107      case XZLGO:                       /* Logout */
4108        if ((x = remcfm()) < 0) return(x);
4109        sstate = setgen('I',"","","");
4110        retcode = 0;
4111        break;
4112
4113      case XZPRI:                       /* Print */
4114        if (!atdiso || !atcapr) {       /* Disposition attribute off? */
4115            printf("?Disposition Attribute is Off\n");
4116            return(-2);
4117        }
4118        cmarg = "";
4119        cmarg2 = "";
4120        if ((x = cmifi("Local file(s) to print on remote printer","",&s,&y,
4121                       xxstring)) < 0) {
4122            if (x == -3) {
4123                printf("?Name of local file(s) required\n");
4124                return(-9);
4125            }
4126            return(x);
4127        }
4128        strcpy(line,s);                 /* Make a safe copy of filename */
4129        *optbuf = NUL;                  /* Wipe out any old options */
4130        if ((x = cmtxt("Options for remote print command","",&s,xxstring)) < 0)
4131          return(x);
4132        if ((x = remtxt(&s)) < 0)
4133          return(x);
4134        strcpy(optbuf,s);               /* Make a safe copy of options */
4135        if ((int)strlen(optbuf) > 94) { /* Make sure this is legal */
4136            printf("?Option string too long\n");
4137            return(-9);
4138        }
4139        nfils = -1;                     /* Expand file list internally */
4140        cmarg = line;                   /* Point to file list. */
4141        rprintf = 1;                    /* REMOTE PRINT modifier for SEND */
4142        sstate = 's';                   /* Set start state to SEND */
4143        if (local) displa = 1;
4144        retcode = 0;
4145        break;
4146#endif /* NOFRILLS */
4147       
4148      case XZSPA:                       /* Space */
4149        if ((x = cmtxt("Confirm, or remote directory name",
4150                       "",&s,xxstring)) < 0)
4151          return(x);
4152        if ((x = remtxt(&s)) < 0)
4153          return(x);
4154        retcode = sstate = setgen('U',s,"","");
4155        break;
4156   
4157#ifndef NOFRILLS
4158      case XZTYP:                       /* Type */
4159        if ((x = cmtxt("Remote file specification","",&s,xxstring)) < 0)
4160          return(x);
4161        if ((int)strlen(s) < 1) {
4162            printf("?Remote filename required\n");
4163            return(-9);
4164        }
4165        if ((x = remtxt(&s)) < 0)
4166          return(x);
4167        rmsg();
4168        retcode = sstate = rfilop(s,'T');
4169        break;
4170#endif /* NOFRILLS */
4171 
4172#ifndef NOFRILLS
4173      case XZWHO:
4174        if ((x = cmtxt("Remote user name, or carriage return",
4175                       "",&s,xxstring)) < 0)
4176          return(x);
4177        if ((x = remtxt(&s)) < 0)
4178          return(x);
4179        retcode = sstate = setgen('W',s,"","");
4180        break;
4181#endif /* NOFRILLS */
4182 
4183      case XZPWD:                       /* PWD */
4184        if ((x = remcfm()) < 0) return(x);
4185        sstate = setgen('A',"","","");
4186        retcode = 0;
4187        break;
4188   
4189#ifndef NOSPL
4190      case XZQUE: {                     /* Query */
4191          char buf[2];
4192          extern char querybuf[], * qbufp;
4193          extern int qbufn;
4194          if ((y = cmkey(vartyp,nvartyp,"","",xxstring)) < 0)
4195            return(y);
4196          if ((x = cmtxt("Remote variable name","",&s,NULL)) < 0) /* No eval */
4197            return(x);
4198          if ((x = remtxt(&s)) < 0)
4199            return(x);
4200          query = 1;                    /* QUERY is active */
4201          qbufp = querybuf;             /* Initialize query response buffer */
4202          qbufn = 0;
4203          querybuf[0] = NUL;
4204          buf[0] = (char) (y & 127);
4205          buf[1] = NUL;
4206          retcode = sstate = setgen('V',"Q",(char *)buf,s);
4207          break;
4208      }
4209
4210      case XZASG: {                     /* Assign */
4211          char buf[VNAML];
4212          if ((y = cmfld("Remote variable name","",&s,NULL)) < 0) /* No eval */
4213            return(y);
4214          strcpy(buf,s);
4215          if ((x = cmtxt("Assignment for remote variable",
4216                   "",&s,xxstring)) < 0) /* Evaluate this one */
4217            return(x);
4218          if ((x = remtxt(&s)) < 0)
4219            return(x);
4220#ifdef COMMENT
4221/*
4222  Server commands can't be long packets.  In principle there's no reason
4223  why they shouldn't be, except that we don't know at this point if the
4224  server is capable of accepting long packets because we haven't started
4225  the protocol yet.  In practice, allowing a long packet here breaks a lot
4226  of assumptions, causes buffer overruns and crashes, etc.  To be fixed
4227  later.  (But since this is commented out, evidently I fixed it later...)
4228*/
4229          if ((int)strlen(s) > 85) {    /* Allow for encoding expansion */
4230              printf("?Sorry, value is too long - 85 characters max\n");
4231              return(-9);
4232          }
4233#endif /* COMMENT */
4234          retcode = sstate = setgen('V',"S",(char *)buf,s);
4235          break;
4236      }
4237#endif /* NOSPL */
4238
4239#ifndef MAXPATHLEN
4240#define MAXPATHLEN 256
4241#endif /* MAXPATHLEN */
4242
4243      case XZCPY: {                     /* Copy */
4244          char buf[MAXPATHLEN+1];
4245          buf[MAXPATHLEN] = '\0';
4246          if ((x = cmfld("Name of remote file to copy","",&s,xxstring)) < 0) {
4247              if (x == -3) {
4248                  printf("?Name of remote file required\n");
4249                  return(-9);
4250              }
4251              else
4252                return(x);
4253          }
4254          strncpy(buf,s,MAXPATHLEN);
4255          if ((x = cmfld("Name of remote destination file or directory",
4256                         "",&s, xxstring)) < 0) {
4257              if (x == -3) {
4258                  printf("?Name of remote file or directory required\n");
4259                  return(-9);
4260              } else return(x);
4261          }
4262          if ((x = remcfm()) < 0)
4263            return(x);
4264          if (local) ttflui();          /* If local, flush tty input buffer */
4265          retcode = sstate = setgen('K',buf,s,"");
4266          break;
4267      }
4268
4269      case XZREN: {                     /* Rename */
4270          char buf[MAXPATHLEN+1];
4271          buf[MAXPATHLEN] = '\0';
4272          if ((x = cmfld("Name of remote file to rename",
4273                         "",&s,xxstring)) < 0) {
4274              if (x == -3) {
4275                  printf("?Name of remote file required\n");
4276                  return(-9);
4277              } else return(x);
4278          }
4279          strncpy(buf,s,MAXPATHLEN);
4280          if ((x = cmfld("New name of remote file","",&s, xxstring)) < 0) {
4281              if (x == -3) {
4282                  printf("?Name of remote file required\n");
4283                  return(-9);
4284              } else return(x);
4285          }
4286          if ((x = remcfm()) < 0)
4287            return(x);
4288          if (local) ttflui();          /* If local, flush tty input buffer */
4289          retcode = sstate = setgen('R',buf,s,"");
4290          break;
4291      }
4292
4293      default:
4294        if ((x = remcfm()) < 0) return(x);
4295        printf("?Not implemented - %s\n",cmdbuf);
4296        return(-2);
4297    }
4298    if (local) ttflui();                /* If local, flush tty input buffer */
4299    return(retcode);
4300}
4301 
4302 
4303/*  R F I L O P  --  Remote File Operation  */
4304 
4305CHAR
4306#ifdef CK_ANSIC
4307rfilop(char * s, char t)
4308#else
4309rfilop(s,t) char *s, t;
4310#endif /* CK_ANSIC */
4311/* rfilop */ {
4312    if (*s == NUL) {
4313        printf("?File specification required\n");
4314        return((CHAR) 0);
4315    }
4316    debug(F111,"rfilop",s,t);
4317    return(setgen(t,s,"",""));
4318}
4319
4320#ifdef ANYX25
4321int
4322setx25() {
4323    if ((y = cmkey(x25tab,nx25,"X.25 call options","",xxstring)) < 0)
4324      return(y);
4325    switch (y) {
4326      case XYUDAT:
4327        if ((z = cmkey(onoff,2,"X.25 call user data","",xxstring))
4328            < 0) return(z);
4329        if (z == 0) {
4330            if ((z = cmcfm()) < 0) return(z);
4331            cudata = 0;             /* disable call user data */
4332            return (success = 1);
4333        }
4334        if ((x = cmtxt("X.25 call user data string","",&s,xxstring)) < 0)
4335          return(x);
4336        if ((int)strlen(s) == 0) {
4337            return (-3);
4338        } else if ((int)strlen(s) > MAXCUDATA) {
4339            printf("?The length must be > 0 and <= %d\n",MAXCUDATA);
4340            return(-2);
4341        }
4342        if ((y = cmcfm()) < 0) return(y);
4343        strcpy(udata,s);
4344        cudata = 1;                     /* X.25 call user data specified */
4345        return (success = 1);
4346      case XYCLOS:
4347        if ((z = cmkey(onoff,2,"X.25 closed user group call","",xxstring))
4348            < 0) return(z);
4349        if (z == 0) {
4350            if ((z = cmcfm()) < 0) return(z);
4351            closgr = -1;                /* disable closed user group */
4352            return (success = 1);
4353        }
4354        if ((y = cmnum("0 <= cug index >= 99","",10,&x,xxstring)) < 0)
4355          return(y);
4356        if (x < 0 || x > 99) {
4357            printf("?The choices are 0 <= cug index >= 99\n");
4358            return(-2);
4359        }
4360        if ((y = cmcfm()) < 0) return(y);
4361        closgr = x;                     /* closed user group selected */
4362        return (success = 1);
4363
4364      case XYREVC:
4365        if((z = cmkey(onoff,2,"X.25 reverse charge call","",xxstring)) < 0)
4366          return(z);
4367        if ((x = cmcfm()) < 0) return(x);
4368        revcall = z;
4369        return (success = 1);
4370    }
4371}
4372
4373int
4374setpadp() {
4375    if ((y = cmkey(padx3tab,npadx3,"PAD X.3 parameter name","",xxstring)) < 0)
4376      return(y);
4377    x = y;
4378    switch (x) {
4379      case PAD_BREAK_CHARACTER:
4380        if ((y = cmnum("PAD break character value","",10,&z,xxstring)) < 0)
4381          return(y);
4382        if ((y = cmcfm()) < 0) return(y);
4383        break;
4384      case PAD_ESCAPE:
4385        if ((y = cmnum("PAD escape","",10,&z,xxstring)) < 0) return(y);
4386        if (z != 0 && z != 1) {
4387            printf("?The choices are 0 or 1\n");
4388            return(-2);
4389        }
4390        if ((y = cmcfm()) < 0) return(y);
4391        break;
4392      case PAD_ECHO:
4393        if ((y = cmnum("PAD echo","",10,&z,xxstring)) < 0) return(y);
4394        if (z != 0 && z != 1) {
4395            printf("?The choices are 0 or 1\n");
4396            return(-2);
4397        }
4398        if ((y = cmcfm()) < 0) return(y);
4399        break;
4400      case PAD_DATA_FORWARD_CHAR:
4401        if ((y = cmnum("PAD data forward char","",10,&z,xxstring)) < 0)
4402          return(y);
4403        if (z != 0 && z != 2) {
4404            printf("?The choices are 0 or 2\n");
4405            return(-2);
4406        }
4407        if ((y = cmcfm()) < 0) return(y);
4408        break;
4409      case PAD_DATA_FORWARD_TIMEOUT:
4410        if ((y = cmnum("PAD data forward timeout","",10,&z,xxstring)) < 0)
4411            return(y);
4412        if (z < 0 || z > 255) {
4413            printf("?The choices are 0 or 1 <= timeout <= 255\n");
4414            return(-2);
4415        }
4416        if ((y = cmcfm()) < 0) return(y);
4417        break;
4418      case PAD_FLOW_CONTROL_BY_PAD:
4419        if ((y = cmnum("PAD pad flow control","",10,&z,xxstring)) < 0)
4420          return(y);
4421        if (z != 0 && z != 1) {
4422            printf("?The choices are 0 or 1\n");
4423            return(-2);
4424        }
4425        if ((y = cmcfm()) < 0) return(y);
4426        break;
4427      case PAD_SUPPRESSION_OF_SIGNALS:
4428        if ((y = cmnum("PAD service","",10,&z,xxstring)) < 0) return(y);
4429        if (z != 0 && z != 1) {
4430            printf("?The choices are 0 or 1\n");
4431            return(-2);
4432        }
4433        if ((y = cmcfm()) < 0) return(y);
4434        break;
4435
4436      case PAD_BREAK_ACTION:
4437        if ((y = cmnum("PAD break action","",10,&z,xxstring)) < 0) return(y);
4438        if (z != 0 && z != 1 && z != 2 && z != 5 && z != 8 && z != 21) {
4439            printf("?The choices are 0, 1, 2, 5, 8 or 21\n");
4440            return(-2);
4441        }
4442        if ((y = cmcfm()) < 0) return(y);
4443        break;
4444
4445      case PAD_SUPPRESSION_OF_DATA:
4446        if ((y = cmnum("PAD data delivery","",10,&z,xxstring)) < 0) return(y);
4447        if (z != 0 && z != 1) {
4448            printf("?The choices are 0 or 1\n");
4449            return(-2);
4450        }
4451        if ((y = cmcfm()) < 0) return(y);
4452        break;
4453
4454      case PAD_PADDING_AFTER_CR:
4455        if ((y = cmnum("PAD crpad","",10,&z,xxstring)) < 0) return(y);
4456        if (z < 0 || z > 7) {
4457            printf("?The choices are 0 or 1 <= crpad <= 7\n");
4458            return(-2);
4459        }
4460        if ((y = cmcfm()) < 0) return(y);
4461        break;
4462
4463      case PAD_LINE_FOLDING:
4464        if ((y = cmnum("PAD linefold","",10,&z,xxstring)) < 0) return(y);
4465        if (z < 0 || z > 255) {
4466            printf("?The choices are 0 or 1 <= linefold <= 255\n");
4467            return(-2);
4468        }
4469        if ((y = cmcfm()) < 0) return(y);
4470        break;
4471
4472      case PAD_LINE_SPEED:
4473        if ((y = cmnum("PAD baudrate","",10,&z,xxstring)) < 0) return(y);
4474        if (z < 0 || z > 18) {
4475            printf("?The choices are 0 <= baudrate <= 18\n");
4476            return(-2);
4477        }
4478        if ((y = cmcfm()) < 0) return(y);
4479        break;
4480
4481      case PAD_FLOW_CONTROL_BY_USER:
4482        if ((y = cmnum("PAD terminal flow control","",10,&z,xxstring)) < 0)
4483            return(y);
4484        if (z != 0 && z != 1) {
4485            printf("?The choices are 0 or 1\n");
4486            return(-2);
4487        }
4488        if ((y = cmcfm()) < 0) return(y);
4489        break;
4490
4491      case PAD_LF_AFTER_CR:
4492        if ((y = cmnum("PAD crpad","",10,&z,xxstring)) < 0) return(y);
4493        if (z < 0 || z == 3 || z > 7) {
4494            printf("?The choices are 0, 1, 2, 4, 5, 6 or 7\n");
4495            return(-2);
4496        }
4497        if ((y = cmcfm()) < 0) return(y);
4498        break;
4499
4500      case PAD_PADDING_AFTER_LF:
4501        if ((y = cmnum("PAD lfpad","",10,&z,xxstring)) < 0) return(y);
4502        if (z < 0 || z > 7) {
4503            printf("?The choices are 0 or 1 <= lfpad <= 7\n");
4504            return(-2);
4505        }
4506        if ((y = cmcfm()) < 0) return(y);
4507        break;
4508
4509      case PAD_EDITING:
4510        if ((y = cmnum("PAD edit control","",10,&z,xxstring)) < 0) return(y);
4511        if (z != 0 && z != 1) {
4512            printf("?The choices are 0 or 1\n");
4513            return(-2);
4514        }
4515        if ((y = cmcfm()) < 0) return(y);
4516        break;
4517
4518      case PAD_CHAR_DELETE_CHAR:
4519        if ((y = cmnum("PAD char delete char","",10,&z,xxstring)) < 0)
4520            return(y);
4521        if (z < 0 || z > 127) {
4522            printf("?The choices are 0 or 1 <= chardelete <= 127\n");
4523            return(-2);
4524        }
4525        if ((y = cmcfm()) < 0) return(y);
4526        break;
4527
4528      case PAD_BUFFER_DELETE_CHAR:
4529        if ((y = cmnum("PAD buffer delete char","",10,&z,xxstring)) < 0)
4530            return(y);
4531        if (z < 0 || z > 127) {
4532            printf("?The choices are 0 or 1 <= bufferdelte <= 127\n");
4533            return(-2);
4534        }
4535        if ((y = cmcfm()) < 0) return(y);
4536        break;
4537
4538      case PAD_BUFFER_DISPLAY_CHAR:
4539        if ((y = cmnum("PAD display line char","",10,&z,xxstring)) < 0)
4540            return(y);
4541        if (z < 0 || z > 127) {
4542            printf("?The choices are 0 or 1 <= displayline <= 127\n");
4543            return(-2);
4544        }
4545        if ((y = cmcfm()) < 0) return(y);
4546        break;
4547    }
4548    padparms[x] = z;
4549    return(success = 1);
4550}
4551#endif /* ANYX25 */
4552
4553int
4554setat(rmsflg) int rmsflg; {
4555    int xx;
4556    if ((y = cmkey(attrtab,natr,"File Attribute packets","",xxstring)) < 0)
4557      return(y);   
4558    if (y == AT_XALL) {                 /* ATTRIBUTES ALL ON or ALL OFF */
4559        if ((z = seton(&xx)) < 0) return(z);
4560        if (rmsflg) {
4561            printf("Sorry, command not available\n");
4562            return(-9);
4563        } else {
4564            atenci = xx;                /* Encoding in */
4565            atenco = xx;                /* Encoding out */
4566            atdati = xx;                /* Date in */
4567            atdato = xx;                /* Date out */
4568            atdisi = xx;                /* Disposition in/out */
4569            atdiso = xx;
4570            atleni = xx;                /* Length in/out (both kinds) */
4571            atleno = xx;
4572            atblki = xx;                /* Blocksize in/out */
4573            atblko = xx;
4574            attypi = xx;                /* File type in/out */
4575            attypo = xx;
4576            atsidi = xx;                /* System ID in/out */
4577            atsido = xx;
4578            atsysi = xx;                /* System-dependent params in/out */
4579            atsyso = xx;
4580#ifdef STRATUS
4581            atfrmi = xx;                /* Format in/out */
4582            atfrmo = xx;
4583            atcrei = xx;                /* Creator id in/out */
4584            atcreo = xx;
4585            atacti = xx;                /* Account in/out */
4586            atacto = xx;
4587#endif /* STRATUS */
4588        }
4589        return(z);
4590    } else if (y == AT_ALLY || y == AT_ALLN) { /* ATTRIBUTES ON or OFF */
4591        if ((x = cmcfm()) < 0) return(x);
4592        atcapr = (y == AT_ALLY) ? 1 : 0;
4593        if (rmsflg) {
4594            sstate = setgen('S', "132", atcapr ? "1" : "0", "");
4595            return((int) sstate);
4596        } else return(success = 1);
4597    }
4598    /* Otherwise, it's an individual attribute that wants turning off/on */
4599
4600    if ((z = cmkey(onoff,2,"","",xxstring)) < 0) return(z);
4601    if ((x = cmcfm()) < 0) return(x);
4602
4603/* There are better ways to do this... */
4604/* The real problem is that we're not separating the in and out cases */
4605/* and so we have to arbitrarily pick the "in" case, i.e tell the remote */
4606/* server to ignore incoming attributes of the specified type, rather */
4607/* than telling it not to send them.  The protocol does not (yet) define */
4608/* codes for "in-and-out-at-the-same-time". */
4609
4610    switch(y) {
4611      case AT_DISP:
4612        if (rmsflg) {
4613            sstate = setgen('S', "142", z ? "1" : "0", "");
4614            return((int) sstate);
4615        }
4616        atdisi = atdiso = z; break;
4617      case AT_ENCO:
4618        if (rmsflg) {
4619            sstate = setgen('S', "141", z ? "1" : "0", "");
4620            return((int) sstate);
4621        }
4622        atenci = atenco = z; break;
4623      case AT_DATE:
4624        if (rmsflg) {
4625            sstate = setgen('S', "135", z ? "1" : "0", "");
4626            return((int) sstate);
4627        }
4628        atdati = atdato = z; break;
4629      case AT_LENB:
4630      case AT_LENK:
4631        if (rmsflg) {
4632            sstate = setgen('S', "133", z ? "1" : "0", "");
4633            return((int) sstate);
4634        }
4635        atleni = atleno = z; break;
4636      case AT_BLKS:
4637        if (rmsflg) {
4638            sstate = setgen('S', "139", z ? "1" : "0", "");
4639            return((int) sstate);
4640        }
4641        atblki = atblko = z; break;
4642      case AT_FTYP:
4643        if (rmsflg) {
4644            sstate = setgen('S', "134", z ? "1" : "0", "");
4645            return((int) sstate);
4646        }
4647        attypi = attypo = z; break;
4648#ifdef STRATUS
4649      case AT_CREA:
4650        if (rmsflg) {
4651            sstate = setgen('S', "136", z ? "1" : "0", "");
4652            return((int) sstate);
4653        }
4654        atcrei = atcreo = z; break;
4655      case AT_ACCT:
4656        if (rmsflg) {
4657            sstate = setgen('S', "137", z ? "1" : "0", "");
4658            return((int) sstate);
4659        }
4660        atacti = atacto = z; break;
4661#endif /* STRATUS */
4662      case AT_SYSI:
4663        if (rmsflg) {
4664            sstate = setgen('S', "145", z ? "1" : "0", "");
4665            return((int) sstate);
4666        }
4667        atsidi = atsido = z; break;
4668#ifdef STRATUS
4669      case AT_RECF:
4670        if (rmsflg) {
4671            sstate = setgen('S', "146", z ? "1" : "0", "");
4672            return((int) sstate);
4673        }
4674        atfrmi = atfrmo = z; break;
4675#endif /* STRATUS */
4676      case AT_SYSP:
4677        if (rmsflg) {
4678            sstate = setgen('S', "147", z ? "1" : "0", "");
4679            return((int) sstate);
4680        }
4681        atsysi = atsyso = z; break;
4682      default:
4683        printf("?Not available\n");
4684        return(-2);
4685    }
4686    return(1);
4687}
4688
4689#ifndef NOSPL
4690int
4691setinp() {
4692    if ((y = cmkey(inptab,ninp,"","",xxstring)) < 0) return(y);
4693    switch (y) {
4694#ifdef OS2
4695      case IN_PAC:                      /* SET INPUT PACING */
4696        z = cmnum("milliseconds","0",10,&x,xxstring);
4697        return(setnum(&tt_inpacing,x,z,94));
4698#endif /* OS2 */
4699      case IN_DEF:                      /* SET INPUT DEFAULT-TIMEOUT */
4700        z = cmnum("Positive number","",10,&x,xxstring);
4701        return(setnum(&indef,x,z,94));
4702      case IN_TIM:                      /* SET INPUT TIMEOUT-ACTION */
4703        if ((z = cmkey(intimt,2,"","",xxstring)) < 0) return(z);
4704        if ((x = cmcfm()) < 0) return(x);
4705        intime[cmdlvl] = z;
4706        return(success = 1);
4707      case IN_CAS:                      /* SET INPUT CASE */
4708        if ((z = cmkey(incast,2,"","",xxstring)) < 0) return(z);
4709        if ((x = cmcfm()) < 0) return(x);
4710        inpcas[cmdlvl] = z;
4711        return(success = 1);
4712      case IN_ECH:                      /* SET INPUT ECHO */
4713        return(seton(&inecho));
4714      case IN_SIL:                      /* SET INPUT SILENCE */
4715        z = cmnum("Seconds of inactivity before INPUT fails","",10,&x,
4716                  xxstring);
4717        return(setnum(&insilence,x,z,-1));
4718      case IN_BUF:                      /* SET INPUT BUFFER-SIZE */
4719        sprintf(tmpbuf, "%d", INPBUFSIZ);
4720        if ((z = cmnum("Number of bytes in INPUT buffer",
4721                       tmpbuf,10,&x, xxstring)) < 0)
4722          return(z);
4723        if ((y = cmcfm()) < 0) return(y);
4724        inbufsize = 0;
4725        if (inpbuf) {
4726            free(inpbuf);
4727            inpbuf = NULL;
4728            inpbp = NULL;
4729        }
4730        if (!(s = (char *)malloc(x + 1)))
4731          return(0);
4732        inpbuf = s;
4733        inpbp = s;
4734        inbufsize = x;
4735        for (x = 0; x <= inbufsize; x++)
4736          inpbuf[x] = NUL;
4737    }
4738    return(0);
4739}
4740#endif /* NOSPL */
4741
4742#ifdef NETCONN
4743VOID
4744ndreset() {
4745#ifndef NODIAL                          /* This depends on DIAL... */
4746    int i=0, j=0;
4747    if (!ndinited)                      /* Don't free garbage... */
4748      return;
4749    for (i = 0; i < nhcount; i++) {     /* Clean out previous list */
4750        if (nh_p[i])
4751          free(nh_p[i]);
4752        nh_p[i] = NULL;
4753        if (nh_p2[i])
4754          free(nh_p2[i]);
4755        nh_p2[i] = NULL;
4756        for (j = 0; j < 4; j++) {
4757            if (nh_px[j][i])
4758              free(nh_px[j][i]);
4759            nh_px[j][i] = NULL;
4760        }
4761    }
4762#endif /* NODIAL */
4763}
4764
4765VOID
4766ndinit() {                              /* Net directory pointers */
4767#ifndef NODIAL                          /* This depends on DIAL... */
4768    int i, j;
4769    if (ndinited++)                     /* Don't do this more than once. */
4770      return;
4771    for (i = 0; i < MAXDDIR; i++) {     /* Init all pointers to NULL */
4772        netdir[i] = NULL;
4773    }
4774    for (i = 0; i < MAXDNUMS; i++) {
4775        nh_p[i] = NULL;
4776        nh_p2[i] = NULL;
4777        for (j = 0; j < 4; j++)
4778          nh_px[j][i] = NULL;
4779    }
4780#endif /* NODIAL */
4781}
4782
4783#ifndef NODIAL
4784#ifdef NETCONN
4785VOID                                    /* Get net defaults from environment */
4786getnetenv() {
4787    char *p = NULL;
4788
4789    makestr(&p,getenv("K_NET_DIRECTORY")); /* Dialing directories */
4790    if (p) {
4791        int i;
4792        xwords(p,(MAXDDIR - 2),netdir,0);
4793        for (i = 0; i < (MAXDDIR - 1); i++) { /* Fill in any gaps... */
4794            if (!netdir[i+1])
4795              break;
4796            else
4797              netdir[i] = netdir[i+1];
4798        }
4799        nnetdir = i;
4800    }
4801}
4802#endif /* NETCONN */
4803#endif /* NODIAL */
4804
4805int     
4806#ifdef CK_ANSIC
4807lunet(char *s)                          /* s = name to look up   */
4808#else
4809lunet(s) char *s;
4810#endif /* CK_ANSIC */
4811/* lunet */ {
4812#ifndef NODIAL                          /* This depends on DIAL... */
4813    int n, n1, n3, n4, t, i, j, k, dd = 0;
4814    int ambiguous = 0;
4815    FILE * f;
4816    char *line = NULL, *pp, *p2;
4817    extern int dialdpy;
4818    int netdpy = dialdpy;
4819    char *info[8];
4820
4821    nhcount = 0;                        /* Set this before returning */
4822
4823    if (!s || nnetdir < 1)              /* Validate arguments */
4824      return(-1);
4825
4826    if (isdigit(*s) || *s == '*' || *s == '.')
4827      return(0);
4828
4829    if ((n1 = (int) strlen(s)) < 1)     /* Length of string to look up */
4830      return(-1);
4831
4832    if (!(line = malloc(1024)))         /* Allocate input buffer */
4833      return(-1);
4834
4835  lu_again:
4836    f = NULL;                           /* Network directory file descriptor */
4837    t = nhcount = 0;                    /* Match count */
4838    dd = 0;                             /* Directory counter */
4839
4840    dirline = 0;
4841    while (1) {                         /* We make one pass */
4842        if (!f) {                       /* Directory not open */
4843            if (dd >= nnetdir)          /* No directories left? */
4844              break;                    /* Done. */
4845            if ((f = fopen(netdir[dd],"r")) == NULL) { /* Open it */
4846                perror(netdir[dd]);     /* Can't, print message saying why */
4847                dd++;
4848                continue;               /* But go on to next one. */
4849            }
4850            if (netdpy)
4851              printf("Opening %s...\n",netdir[dd]);
4852            dd++;
4853        }
4854        line[0] = NUL;
4855        if (getnct(line,1023,f,1) < 0) { /* Read a line */
4856            if (f) {                    /* f can be clobbered! */
4857                fclose(f);              /* Close the file */
4858                f = NULL;               /* Indicate next one needs opening */
4859            }
4860            continue;
4861        }
4862        if (!line[0])                   /* Empty line */
4863          continue;
4864
4865        xwords(line,7,info,0);          /* Parse it */
4866       
4867        if (!info[1] || !info[2] || !info[3]) /* Required fields */
4868          continue;
4869        if (*info[1] == ';')            /* Full-line comment */
4870          continue;
4871        if ((n = (int) strlen(info[1])) < 1) /* Length of name-tag */
4872          continue;
4873        if (n < n1)                     /* Search name is longer */
4874          continue;                     /* Can't possibly match */
4875        if (ambiguous && n != n1)
4876          continue;
4877        if (xxstrcmp(s,info[1],n1))     /* Compare using length of */
4878          continue;                     /* search string s. */
4879
4880        /* Have a match */
4881
4882        makestr(&(nh_p[nhcount]), info[3]);    /* address */
4883        makestr(&(nh_p2[nhcount]),info[2]);    /* net type */
4884        makestr(&(nh_px[0][nhcount]),info[4]); /* net-specific stuff... */
4885        makestr(&(nh_px[1][nhcount]),info[5]);
4886        makestr(&(nh_px[2][nhcount]),info[6]);
4887        makestr(&(nh_px[3][nhcount]),info[7]);
4888
4889        nhcount++;                      /* Count this match */
4890        if (nhcount > MAXDNUMS) {       /* Watch out for too many */
4891            printf("Warning: %d matches found, %d max\n",
4892                   nhcount,
4893                   MAXDNUMS
4894                   );
4895            nhcount = MAXDNUMS;
4896            break;
4897        }
4898        if (nhcount == 1) {             /* First one - save entry name */
4899            if (n_name) {               /* Free the one from before if any */
4900                free(n_name);
4901                n_name = NULL;
4902            }
4903            if (!(n_name = (char *)malloc(n + 1))) { /* Allocate new storage */
4904                printf("?memory allocation error - lunet:3\n");
4905                if (line) {
4906                    free(line);
4907                    line = NULL;
4908                }
4909                nhcount = 0;
4910                return(-1);
4911            }
4912            t = n;                      /* Remember its length */
4913            strcpy(n_name,info[1]);
4914        } else {                        /* Second or subsequent one */
4915            if ((int) strlen(info[1]) == t) /* Lengths compare */
4916              if (!xxstrcmp(n_name,info[1],t)) /* Caseless compare OK */
4917                continue;
4918
4919            /* Name given by user matches entries with different names */
4920           
4921            if (ambiguous)              /* Been here before */
4922              break;
4923
4924            ambiguous = 1;              /* Now an exact match is required */
4925            ndreset();                  /* Clear out previous list */
4926            goto lu_again;              /* Do it all over again. */
4927        }
4928    }
4929    if (line) {
4930        free(line);
4931        line = NULL;
4932    }
4933    if (nhcount == 0 && ambiguous)
4934      printf("Ambiguous - \"%s\" different names in network directory\n",s);
4935#else
4936    nhcount = 0;
4937#endif /* NODIAL */
4938    return(nhcount);
4939}
4940#endif /* NETCONN */
4941
4942#ifndef NOLOCAL
4943/* S E T L I N -- parse name of and then open communication device. */
4944/*
4945  Call with:
4946    xx == XYLINE for a serial (tty) line, XYHOST for a network host,
4947    zz == 0 means if user doesn't give a device name, continue current
4948            active connection (if any);
4949    zz != 0 means if user doesn't give a device name, then close the
4950            current connection and restore the default communication device.
4951*/
4952int
4953setlin(xx, zz) int xx, zz; {
4954    int i;
4955    char * ss;
4956
4957#ifdef OS2
4958#define SRVBUFSIZ PIPENAML
4959#else
4960#define SRVBUFSIZ 63
4961#endif /* OS2 */
4962
4963    char srvbuf[SRVBUFSIZ+1];
4964    char * service;
4965
4966#ifdef OS2
4967#ifdef NT
4968    int xxtapi = 0;
4969#else
4970    int xxslip = 0, xxppp = 0;
4971#endif /* NT */
4972#endif /* OS2 */
4973
4974    service = srvbuf;
4975    *service = NUL;
4976
4977    if (xx == XYHOST) {                 /* SET HOST <hostname> */
4978#ifndef NETCONN
4979        printf("?Network connections not supported\n");
4980        return(-9);
4981#else
4982        if (
4983#ifdef DECNET
4984            (nettype != NET_DEC) &&
4985#endif /* DECNET */
4986            (nettype != NET_SX25) &&
4987            (nettype != NET_VX25) &&
4988#ifdef NPIPE
4989            (nettype != NET_PIPE) &&
4990#endif /* NPIPE */
4991#ifdef CK_NETBIOS
4992            (nettype != NET_BIOS) &&
4993#endif /* CK_NETBIOS */
4994#ifdef SUPERLAT
4995            (nettype != NET_SLAT) &&
4996#endif /* SUPERLAT */
4997#ifdef NETFILE
4998            (nettype != NET_FILE) &&
4999#endif /* NETFILE */
5000            (nettype != NET_TCPB)) {
5001            printf("?Network type not supported\n");
5002            return(-9);
5003        }
5004#ifdef CK_NETBIOS
5005        if (nettype == NET_BIOS) {
5006            if ((x = cmtxt( zz ?
5007    "server name, *,\n or carriage return to close an open connection" :
5008    "server name, *,\n or carriage return to resume an open connection",
5009                           "",&s,xxstring)) < 0)
5010              return(x);
5011            strcpy(line,s);
5012            s = line;
5013        } else
5014#endif /* CK_NETBIOS */
5015#ifdef NPIPE
5016          if (nettype == NET_PIPE) {
5017              if ((x = cmtxt( zz ?
5018    "server name, *,\n or carriage return to close an open connection" :
5019    "server name, *,\n or carriage return to resume an open connection",
5020                            "",&s,xxstring)) < 0)
5021                return(x);
5022              if (*s != '\0') {
5023                  if (strcmp(s,"*")) {  /* If remote, */
5024                      strcpy(line,"\\\\"); /* begin with server name */
5025                      strcat(line,s);
5026                  } else {
5027                      line[0]='\0';
5028                  }     
5029                  strcat(line,"\\pipe\\"); /* Make this a pipe name */
5030                  strcat(line,pipename);   /* Add the name of the pipe */
5031                  s = line;
5032              }
5033          } else       
5034#endif /* NPIPE */
5035#ifdef NETFILE
5036            if (nettype == NET_FILE) {
5037                if ((x = cmtxt( zz ?
5038    "file name,\n or carriage return to close an open connection" :
5039    "file name,\n or carriage return to resume an open connection",
5040                               "",&s,xxstring)) < 0)
5041                  return(x);
5042                if (*s != '\0')
5043                  strcpy(line,s);
5044                s = line;
5045            } else
5046#endif /* NETFILE */
5047#ifdef SUPERLAT
5048              if (nettype == NET_SLAT) {
5049                  slat_pwd[0] = NUL;    /* Erase any previous one */
5050
5051                  /* Just get a text string */
5052
5053                  if ((x = cmfld( zz ?
5054   "service, node/port,\n or carriage return to close an open connection" :
5055   "service, node/port,\n or carriage return to resume an open connection",
5056                                 "",&s,xxstring)) < 0) {
5057                      if (x != -3)      /* Parse error */
5058                        return(x);      /* return it */
5059                      else if (!network) {
5060                          printf("?Host name or address required\n");
5061                          return(-9);
5062                      } else if (!zz)   /* No hostname given */
5063                        return(1);      /* and none required, */
5064                  } /* continue current connection. */
5065                  if (*s) {             /* If they gave a host name... */
5066                      strcpy(line,s);
5067                      if ((x = cmfld(
5068                  "password,\n or carriage return if no password required",
5069                                     "",
5070                                     &s,
5071                                     xxstring
5072                                     )) < 0 && x != -3)
5073                        return(x);
5074                      strncpy(slat_pwd,s,17); /* Set the password, if any */
5075                  }
5076                  if ((x = cmcfm()) < 0) return(x); /* Confirm the command */
5077                  s = line;
5078              } else
5079#endif /* SUPERLAT */
5080                if (nettype != NET_TCPB) { /* Not a TCP/IP connection */
5081                    /* Just get a text string */
5082                    if ((x = cmtxt(zz ?
5083    "Network host name,\n or carriage return to close an open connection" :
5084    "Network host name,\n or carriage return to resume an open connection",
5085                                   "",&s,xxstring)) < 0)
5086                      return(x);
5087                    strcpy(line,s);
5088                    s = line;
5089                } else {                /* TCP/IP connection... */
5090                    /* Parse for host and service separately. */
5091#ifndef OS2           
5092                    ss =  zz ?
5093 "IP host name or number,\n or carriage return to close an open connection" :
5094 "IP host name or number,\n or carriage return to resume an open connection";
5095#else /* OS2 */
5096                    if (ttnproto != NP_RLOGIN && ttnproto != NP_TELNET) {
5097                        ss = zz ?
5098 "IP host name, number, *,\n or carriage return to close an open connection" :
5099 "IP host name, number, *,\n or carriage return to resume an open connection";
5100                    } else {
5101                        ss = zz ?
5102 "IP host name or number,\n or carriage return to close an open connection" :
5103 "IP host name or number,\n or carriage return to resume an open connection";
5104                    }
5105#endif /* OS2 */
5106                    if ((x = cmfld(ss,"",&s,xxstring)) < 0) {
5107                        if (x != -3)    /* Parse error */
5108                          return(x);    /* return it */
5109                        else if (!network) {
5110                            printf("?Host name or address required\n");
5111                            return(-9);
5112                        } else if (!zz) /* No hostname given */
5113                          return(1);    /* and none required, */
5114                    } /* continue current connection. */
5115                    if (*s) {           /* If they gave a host name... */
5116                        debug(F110,"setlin host s 1",s,0);
5117#ifdef NOLISTEN           
5118                        if (nettype == NET_TCPB && *s == '*') {
5119                            printf(
5120"?Sorry, incoming connections not supported in this version of Kermit.\n"
5121                                   );
5122                            return(-9);
5123                        }
5124#endif /* NOLISTEN */
5125                        strcpy(line,s); /* Make a copy */
5126                        s = line;
5127                        debug(F110,"setlin host line[]",line,0);
5128#ifdef RLOGCODE
5129                        /* Allow a username if rlogin is requested */
5130                        if (ttnproto == NP_RLOGIN) {
5131                            int y;
5132                            uidflag = 0;
5133#ifdef VMS     
5134                            strcpy(service,"513"); /* Set service to login */
5135#else /* VMS */
5136#ifdef OS2_LOGIN_IS_513
5137                            strcpy(service,"513");
5138#else /* OS2 */
5139                            strcpy(service,"login");
5140#endif /* OS2 */
5141#endif /* VMS */
5142                            y = cmfld("Userid on remote system",
5143                                      uidbuf,&s,xxstring);
5144                            if (y < 0 && y != -3)
5145                              return(y);
5146                            if ((int)strlen(s) > 63) {
5147                                printf("Sorry, too long\n");
5148                                return(-9);
5149                            }
5150                            strcpy(uidbuf,s);
5151                            if (uidbuf[0])
5152                              uidflag = 1;
5153                        } else {
5154#endif /* RLOGCODE */
5155                            s = line;   /* TELNET or SET HOST */
5156                            /* Check for "host:service" */
5157                            for ( ; (*s != '\0') && (*s != ':'); s++) ;
5158                            if (*s) {   /* Service, save it */
5159                                *s++ = NUL;
5160                                strncpy(service,s,SRVBUFSIZ);
5161                                service[SRVBUFSIZ] = NUL;
5162                            } else {    /* No :service, let them type one. */
5163                                if (*line != '*') {
5164                                    if (ttnproto == NP_KERMIT) {
5165                                        if ((x = cmfld(
5166                                               "TCP service name or number",
5167                                                       "",&s,xxstring)
5168                                             ) < 0 && x != -3)
5169                                          return(x);
5170                                    } else if (ttnproto == NP_RLOGIN) {
5171                                        if ((x = cmfld(
5172       "TCP service name or number,\n or carriage return for rlogin (513)",
5173       "513",&s,xxstring)
5174                                             ) < 0 && x != -3)
5175                                          return(x);
5176                                    } else {
5177                                        if ((x = cmfld(
5178                                             "TCP service name or number",
5179                                                       "",&s,xxstring)
5180                                             ) < 0 && x != -3)
5181                                          return(x);
5182                                    }
5183                                } else { /* Not incoming */
5184                                    if ((x = cmfld(
5185                                                "TCP service name or number",
5186                                                   "",&s,xxstring)
5187                                         ) < 0 && x != -3)
5188                                      return(x);
5189                                }
5190                                if (*s) { /* If they gave a service, */
5191                                    strncpy(srvbuf,s,SRVBUFSIZ); /* copy it */
5192                                }
5193                            }
5194#ifdef RLOGCODE
5195                        }
5196#endif /* RLOGCODE */
5197                        if ((x = cmcfm()) < 0) /* Confirm the command */
5198                          return(x);
5199                    } else {
5200                        line[0] = NUL;
5201                    }
5202                }
5203
5204        s = line;
5205        debug(F110,"setlin service 0",srvbuf,0);
5206        debug(F110,"setlin host s 2",s,0);
5207
5208#ifndef NODIAL
5209        /* Look up in network directory */
5210        x = 0;
5211        debug(F101,"setlin nettype 1","",nettype);
5212        debug(F111,"setlin nnetdir",s,nnetdir);
5213        if (*s == '=') {                /* If number starts with = sign */
5214            s++;                        /* strip it */
5215            while (*s == SP) s++;       /* and any leading spaces */
5216            strcpy(line,s);             /* Do this again. */
5217            s = line;
5218            debug(F110,"setlin host s 3",s,0);
5219            nhcount = 0;
5220        } else if (*s) {                /* We want to look it up. */
5221            if (nnetdir > 0)            /* If there is a directory... */
5222              x = lunet(line);          /* (sets nhcount) */
5223            else                        /* otherwise */
5224              nhcount = 0;              /* we didn't find any there */
5225            if (x < 0) {                /* Internal error? */
5226                printf("?Fatal network directory lookup error - %s\n",line);
5227                return(-9);
5228            }
5229            debug(F111,"setlin lunet nhcount",line,nhcount);
5230        }
5231#endif /* NODIAL */
5232
5233        /* New connection wanted.  Make a copy of the host name/address... */
5234
5235        strncpy(tmpbuf,s,TMPBUFSIZ);    /* Because we are reusing line[] */
5236        s = tmpbuf;                     /* for net directory entries...  */
5237        debug(F110,"setlin host s 5",s,0);
5238        if (!hupok(1))
5239          return(success = 0);
5240
5241        ttflui();                       /* Clear away buffered up junk */
5242#ifndef NODIAL
5243        mdmhup();
5244#endif /* NODIAL */
5245        ttclos(0);                      /* Close old connection, if any */
5246        if (oldplex > -1)               /* Restore duplex setting. */
5247          duplex = oldplex;
5248        if (*s) {                       /* They gave a hostname */
5249            x = 1;                      /* Network connection always local */
5250            if (mdmsav < 0)
5251              mdmsav = mdmtyp;          /* Remember old modem type */
5252            mdmtyp = -nettype;          /* Special code for network */
5253            if (nettype == NET_TCPB) {  /* For TCP/IP telnet connections */
5254                oldplex = duplex;       /* Remember previous duplex */
5255                duplex = 0;             /* Set full duplex and let */
5256                                        /* negotiations change if necessary. */
5257            }
5258        } else {                        /* They just said "set host" */
5259            if (network && msgflg)
5260              printf(" Closing connection\n");
5261            s = dftty;                  /* So go back to normal */
5262            x = dfloc;                  /* default tty, location, */
5263            network = 0;                /* No more network connection. */
5264            if (oldplex > -1)
5265              duplex = oldplex;         /* Restore old duplex setting. */
5266            if (mdmtyp < 0) {           /* Switching from net to serial? */
5267                if (mdmsav > -1) {      /* Restore modem type from last */
5268                    mdmtyp = mdmsav;    /* SET MODEM command, if any. */
5269                    mdmsav = -1;
5270                } else
5271                  mdmtyp = 0;
5272            }
5273            if (zz) {
5274                if (autoflow)           /* Maybe change flow control */
5275                  setflow();
5276                return(success = 1);
5277            }
5278        }
5279#endif /* NETCONN */
5280    }
5281
5282/* Serial tty device, possibly modem, connection... */
5283
5284    if (xx == XYLINE                    /* SET LINE or SET PORT */
5285#ifdef CK_TAPI
5286        || xx == XYTAPI_LIN             /* SET TAPI LINE */
5287#endif /* CK_TAPI */
5288        ) {
5289#ifdef OS2                     
5290/*
5291  User can type:
5292    COM1..COM8 = Regular COM port
5293    1..8       = Synonym for COM1..COM8, is translated to COM1..COM8
5294    _n         = (n is a number) = open file handle
5295    string     = any text string = name of some other kind of device,
5296                 taken literally, as given.
5297*/
5298        s = "Communication device name";
5299#ifdef CK_TAPI
5300        if (TAPIAvail)
5301          cktapiBuildLineTable(&tapilinetab, &ntapiline);
5302        if (tapilinetab && ntapiline > 0)
5303          s = "Communication device name, or \"TAPI\"";
5304        else if ( xx == XYTAPI_LIN ) {
5305            printf("\nNo TAPI Line Devices are configured for this system\n");
5306            return(-9);
5307        }
5308        if (xx == XYTAPI_LIN)
5309          s = "tapi";
5310        else  /* Query the user */
5311#endif /* CK_TAPI */
5312          if ((x = cmfld(s,dftty,&s,xxstring)) < 0)
5313            return(x);
5314        debug(F110,"OS2 SET PORT s",s,0);
5315        y = lookup(os2devtab,s,nos2dev,&x); /* Look up in keyword table */
5316        debug(F101,"OS2 SET PORT x","",x);
5317        debug(F101,"OS2 SET PORT y","",y);
5318        if ((y > -1) && (x >= 0 && x < 8)) { /* User typed a digit 1..8 */
5319            s = os2devtab[x+8].kwd;     /* Substitite its real name */
5320#ifdef NT
5321            xxtapi = 0;
5322#else /* NT */
5323            xxslip = xxppp = 0;
5324#endif /* NT */
5325            debug(F110,"OS2 SET PORT subst s",s,"");
5326#ifndef NT
5327        } else if ((y >-1) && (x >= 16 && x < 24)) { /* SLIP access */
5328            s = os2devtab[x-8].kwd;     /* Substitite its real name */
5329            debug(F110,"OS2 SET PORT SLIP subst s",s,"");
5330            xxslip = 1;
5331            xxppp  = 0;
5332        } else if ((y >-1) && (x >= 24 && x < 32)) { /* PPP access */
5333            s = os2devtab[x-16].kwd;    /* Substitite its real name */
5334            debug(F110,"OS2 SET PORT PPP subst s",s,"");
5335            xxppp = 1;
5336            xxslip = 0;
5337            if ((y = cmkey(os2ppptab,
5338                           nos2ppp,
5339                           "PPP driver interface",
5340                           "ppp0",
5341                           xxstring)
5342                 ) < 0)
5343                return(y);
5344            debug(F101,"OS2 SET PORT PPP INTERFACE y","",y);
5345            xxppp = (y % 10) + 1;
5346#endif /* NT */
5347        } else if (*s == '_') {         /* User used "_" prefix */
5348            s++;                        /* Remove it */
5349            /* Rest must be numeric */
5350            debug(F110,"OS2 SET PORT HANDLE _subst s",s,0);
5351            if (!rdigits(s)) {
5352                printf("?Invalid format for file handle\n");
5353                return(-9);
5354            }
5355#ifdef NT
5356            xxtapi = 0;
5357#else /* NT */
5358            xxslip = xxppp = 0;
5359#endif /* NT */
5360        } else {                        /* A normal COMx port or a string */
5361            s = brstrip(s);             /* Strip braces if any */
5362#ifdef NT
5363            /* Windows TAPI support - Look up in keyword table */
5364            if (tapilinetab && ntapiline > 0) {
5365                if (!xxstrcmp(s,"tapi",4)) {
5366
5367                    /* Find out what the lowest numbered TAPI device is */
5368                    /* and use it as the default.                       */
5369                    int j = 9999, k = -1;
5370                    for (i = 0; i < ntapiline; i++ ) {
5371                        if (tapilinetab[i].kwval < j) {
5372                            j = tapilinetab[i].kwval;
5373                            k = i;
5374                        }
5375                    }           
5376                    if (k >= 0)
5377                      s = tapilinetab[k].kwd;
5378                    else s = "";
5379
5380                    if ((y = cmkey(tapilinetab,ntapiline,
5381                                   "TAPI device name",s,xxstring)) < 0)
5382                      return(y);
5383
5384                    xxtapi = 1;
5385#ifdef COMMENT
5386                    y = lookup(tapilinetab,s,ntapiline,&x);
5387#endif /* COMMENT */
5388                    if (y > -1)
5389                      s = tapilinetab[y].kwd;
5390                } else
5391                  xxtapi = 0;
5392            }
5393#else /* NT */
5394            /* not OS/2 SLIP or PPP */
5395            xxslip = xxppp = 0;
5396#endif /* NT */
5397        }
5398        if ((x = cmcfm()) < 0)
5399          return(x);
5400
5401#else /* !OS2 */
5402
5403        if ((x = cmtxt("Communication device name",dftty,&s,xxstring)) < 0)
5404          return(x);
5405#endif /* OS2 */
5406
5407        strcpy(tmpbuf,s);
5408        s = tmpbuf;
5409        if (!hupok(1))
5410          return(success = 0);
5411
5412        if (local) ttflui();            /* Clear away buffered up junk */
5413#ifndef NODIAL
5414#ifdef OS2ONLY
5415/* Don't hangup a line that is shared with the SLIP or PPP driver */
5416        if (!ttslip && !ttppp)
5417#endif /* OS2ONLY */
5418        mdmhup();
5419#endif /* NODIAL */
5420        ttclos(0);                      /* Close old line, if any was open */
5421        if (*s) {                       /* They gave a device name */
5422            x = -1;                     /* Let ttopen decide about it */
5423        } else {                        /* They just said "set line" */
5424            s = dftty;                  /* so go back to normal tty */
5425            x = dfloc;                  /* and mode. */
5426        }
5427
5428#ifdef OS2                              /* Must wait until after ttclos() */
5429#ifdef NT                               /* to change these settings       */
5430        tttapi = xxtapi;
5431#else
5432        ttslip = xxslip;
5433        ttppp  = xxppp;
5434#endif /* NT */
5435        debug(F110,"OS2 SET PORT final s",s,"");
5436#endif /* OS2 */
5437
5438#ifdef NETCONN
5439        if (mdmtyp < 0) {               /* Switching from net to async? */
5440            if (mdmsav > -1)            /* Restore modem type from last */
5441              mdmtyp = mdmsav;          /* SET MODEM command, if any. */
5442            else
5443              mdmtyp = 0;
5444            mdmsav = -1;
5445        }
5446        if (oldplex > -1) {             /* Restore previous duplex setting. */
5447            duplex = oldplex;
5448            oldplex = -1;
5449        }
5450        if (network) {
5451#ifdef TNCODE
5452/* This should be unnecessary, since ttclos() did it already? */
5453/* But it can't hurt ... */
5454            tn_init = 0;                /* TELNET not init'd any more. */
5455#endif /* TNCODE */
5456            network = 0;                /* No more network. */
5457        }
5458#endif /* NETCONN */
5459    }
5460#ifdef COMMENT
5461/*
5462  The following is removed, not so much because it's a horrible hack, but
5463  because it only works if the SET FLOW command was given *before* the SET
5464  LINE command, whereas normally these commands can be given in any order.
5465*/
5466#ifdef NEXT
5467/*
5468  This is a horrible hack, but it's nice for users.  On the NeXT, you select
5469  RTS/CTS hardware flow control not by system calls, but by referring to the
5470  device with a different name.  If the user has asked for RTS/CTS flow
5471  control on a NeXT, but used the non-RTS/CTS device name in the SET LINE
5472  command, we make the appropriate substitute here.  I wonder how much bigger
5473  this section of code will grow as the years go by...
5474*/
5475    if ((flow == FLO_RTSC) &&           /* RTS/CTS flow control selected */
5476        strcmp(s,dftty)) {              /*  ...on external port? */
5477        y = strlen(s);                  /* Yes, insert "f" as next-to-last */
5478        if (s[y-2] != 'f') {            /* character in device name if not */
5479            strcpy(line,s);             /* already there... */
5480            line[y] = line[y-1];        /* So /dev/cua => /dev/cufa, etc. */
5481            line[y-1] = 'f';
5482            line[y+1] = '\0';
5483            s = line;
5484        }
5485    }
5486#endif /* NEXT */
5487#endif /* COMMENT */
5488
5489    success = 0;
5490    if (mdmtyp > -1) {                  /* Serial connections... */
5491        if ((y = ttopen(s,&x,mdmtyp,cdtimo)) > -1 ) { /* Open the new line */
5492            success = 1;
5493        } else {
5494#ifdef OS2ONLY
5495            if (!strcmp(s,dftty))   /* Do not generate an error with dftty */
5496              ;
5497            else if (y == -6 && ttslip) {
5498                printf("Unable to access SLIP driver.\n");
5499            } else if (y == -6 && ttppp) {
5500                printf("Unable to access PPP driver (wrong interface?)\n");
5501            } else
5502#endif /* OS2ONLY */
5503              if (y == -2) {
5504                  printf("?Timed out, no carrier.\n");
5505                  printf("Try SET CARRIER OFF and SET LINE again, or else\n");
5506                  printf("SET MODEM, SET LINE, and then DIAL.\n");
5507              } else if (y == -3) {
5508                  printf("Sorry, access to lock denied: %s\n",s);
5509              } else if (y == -4) {
5510                  printf("Sorry, access to device denied: %s\n",s);
5511              } else if (y == -5) {
5512#ifdef VMS
5513                  printf(
5514                   "Sorry, device is in use or otherwise unavailable: %s\n",s);
5515#else
5516                  printf("Sorry, device is in use: %s\n",s);
5517#endif /* VMS */
5518              } else {                  /* Other error. */
5519#ifdef COMMENT
5520#ifndef VMS
5521#endif /* COMMENT */
5522                  if (errno) {
5523                      int x;            /* Find a safe, long buffer */
5524                      x = strlen(line) + 2; /* for the error message. */
5525                      if (LINBUFSIZ - x > 100) { /* Allow room for 100 chars */
5526                          tp = line + x;
5527                          sprintf(tp,"Sorry, can't open connection: %s",s);
5528                          perror(tp);
5529                      } else printf("Sorry, can't open connection: %s\n",s);
5530                  } else
5531#ifdef COMMENT
5532#endif /* VMS */
5533#endif /* COMMENT */
5534                    printf("Sorry, can't open connection: %s\n",s);
5535              }
5536        }
5537    }
5538#ifdef NETCONN
5539    else {                              /* Network connection */
5540        char *p;
5541        int i, n;
5542#ifndef NODIAL
5543        debug(F101,"setlin nettype 3","",nettype);
5544        debug(F101,"setlin nhcount","",nhcount);
5545        if ((nhcount > 1) && !quiet && !backgrd) {
5546            int k;
5547            printf("%d entr%s found for \"%s\"%s\n",
5548                   nhcount,
5549                   (nhcount == 1) ? "y" : "ies",
5550                   s,
5551                   (nhcount > 0) ? ":" : "."
5552                   );
5553            for (i = 0; i < nhcount; i++) {
5554                    printf("%3d. %-12s => %-9s %s",
5555                           i+1,n_name,nh_p2[i],nh_p[i]);
5556                for (k = 0; k < 4; k++) { /* Also list net-specific items */
5557                    if (nh_px[k][i])      /* free format... */
5558                      printf(" %s",nh_px[k][i]);
5559                    else
5560                      break;
5561                }
5562                printf("\n");
5563            }
5564        }
5565        if (nhcount == 0)
5566          n = 1;
5567        else
5568          n = nhcount;
5569#else
5570        n = 1;
5571        nhcount = 0;
5572#endif /* NODIAL */
5573        for (i = 0; i < n; i++) {       /* Loop for each entry found */
5574#ifndef NODIAL
5575            debug(F101,"setlin loop i","",i);
5576            if (nhcount > 0) {          /* If we found at least one entry... */
5577                strcpy(line,nh_p[i]);   /* Copy the current entry to line[] */
5578                if (lookup(netcmd,nh_p2[i],nnets,&x) > -1) { /* Net type */
5579                    nettype = netcmd[x].kwval;
5580                    mdmtyp  = 0 - nettype;
5581                    debug(F101,"setlin nettype 4","",nettype);
5582                } else {
5583                    printf("Error - network type \"%s\" not supported\n",
5584                           nh_p2[i]
5585                           );
5586                    continue;
5587                }                   
5588
5589                switch (nettype) {      /* Net-specific things */
5590
5591                  case NET_TCPB: {      /* TCP/IP */
5592#ifdef TCPSOCKET
5593                      char *q;
5594                      int flag = 0;
5595
5596                      /* Extract ":service", if any, from host string */
5597                      debug(F110,"setlin service 1",line,0);
5598                      for (q = line; (*q != '\0') && (*q != ':'); q++)
5599                        ;
5600                      if (*q == ':') { *q++ == NUL; flag = 1; }
5601                      debug(F111,"setlin service 2",line,flag);
5602
5603                      /* Get service, if any, from directory entry */
5604
5605                      if (!*service) {
5606                          if (nh_px[0][i]) {
5607                              strncpy(srvbuf,nh_px[0][i],SRVBUFSIZ);
5608                              debug(F110,"setlin service 3",service,0);
5609                          }                       
5610                          if (flag) {
5611                              strncpy(srvbuf,q,SRVBUFSIZ);
5612                              debug(F110,"setlin service 4",service,0);
5613                          }                       
5614                      }
5615
5616                      /* If we have a service, append to host name/address */
5617
5618                      if (*service) {
5619                          strcat(line, ":"); /* separated by a colon. */
5620                          strncat(line, service, LINBUFSIZ);
5621                          debug(F110,"setlin service 5",line,0);
5622                      }
5623#ifdef RLOGCODE
5624                      /* If no service given but command was RLOGIN */
5625
5626                      else if (ttnproto == NP_RLOGIN) { /* add this... */
5627                          strcat(line, ":login");
5628                          debug(F110,"setlin service 6",line,0);
5629                      }
5630#endif /* RLOGCODE */
5631                      else {            /* Otherwise, add ":telnet". */
5632                          strcat(line, ":telnet");
5633                          debug(F110,"setlin service 7",line,0);
5634                      }       
5635
5636                      /* Fifth field, if any, is user ID (for rlogin) */
5637
5638                      if (nh_px[1][i] && !uidflag)
5639                        strncpy(uidbuf,nh_px[1][i],63);
5640#ifdef RLOGCODE
5641                      if (ttnproto == NP_RLOGIN && !uidbuf[0]) {
5642                          printf("Username required for rlogin\n");
5643                          return(-9);
5644                      }
5645#endif /* RLOGCODE */
5646#endif /* TCPSOCKET */
5647                      break;
5648                  }
5649
5650
5651                  case NET_PIPE:
5652#ifdef NPIPE
5653                    if (!pipename[0]) { /* User didn't give a pipename */
5654                        if (nh_px[0][i]) { /* But directory entry has one */
5655                            if (strcmp(pipename,"\\pipe\\")) {
5656                                strcpy(pipename,"\\pipe\\");
5657                                strncat(srvbuf,nh_px[0][i],PIPENAML-6);
5658                            } else {
5659                                strncpy(pipename,nh_px[0][i],PIPENAML);
5660                            }
5661                            debug(F110,"setlin pipeneme",pipename,0);
5662                        }
5663                    }
5664#endif /* NPIPE */
5665                    break;
5666
5667                  case NET_SLAT:
5668#ifdef SUPERLAT
5669                    if (!slat_pwd[0]) { /* User didn't give a password */
5670                        if (nh_px[0][i]) { /* But directory entry has one */
5671                            strncpy(slat_pwd,nh_px[0][i],17);
5672                            debug(F110,"setlin SuperLAT password",slat_pwd,0);
5673                        }
5674                    }
5675#endif /* SUPERLAT */
5676                    break;
5677
5678                  case NET_SX25:        /* X.25 keyword parameters */
5679                  case NET_VX25: {
5680#ifdef ANYX25               
5681                      int k;            /* Cycle through the four fields */
5682                      for (k = 0; k < 4; k++) {
5683                          if (!nh_px[k][i]) /* Bail out if none left */
5684                            break;
5685                          if (!xxstrcmp(nh_px[k][i],"cug=",4)) {
5686                              closgr = atoi(nh_px[k][i]+4);
5687                              debug(F101,"X25 CUG","",closgr);
5688                          } else if (!xxstrcmp(nh_px[k][i],"cud=",4)) {
5689                              cudata = 1;
5690                              strncpy(udata,nh_px[k][i]+4,MAXCUDATA);
5691                              debug(F110,"X25 CUD",cudata,0);
5692                          } else if (!xxstrcmp(nh_px[k][i],"rev=",4)) {
5693                              revcall = !xxstrcmp(nh_px[k][i]+4,"=on",3);
5694                              debug(F101,"X25 REV","",revcall);
5695                          } else if (!xxstrcmp(nh_px[k][i],"pad=",4)) {
5696                              int x3par, x3val;
5697                              char *s1, *s2;
5698                              s1 = s2 = nh_px[k][i]+4; /* PAD parameters */
5699                              while (*s2) {            /* Pick them apart */
5700                                  if (*s2 == ':') {
5701                                      *s2 = NUL;
5702                                      x3par = atoi(s1);
5703                                      s1 = ++s2;
5704                                      continue;
5705                                  } else if (*s2 == ',') {
5706                                      *s2 = NUL;
5707                                      x3val = atoi(s1);
5708                                      s1 = ++s2;
5709                                      debug(F111,"X25 PAD",x3par,x3val);
5710                                      if (x3par > -1 &&
5711                                          x3par <= MAXPADPARMS)
5712                                        padparms[x3par] = x3val;
5713                                      continue;
5714                                  } else
5715                                    s2++;
5716                              }
5717                          }
5718                      }
5719#endif /* ANYX25 */
5720                      break;
5721                  }
5722
5723                  default:              /* Nothing special for other nets */
5724                    break;
5725                }
5726            } else {                    /* No directory entries found. */
5727                strcpy(line,tmpbuf);    /* Put this back... */
5728                if (nettype == NET_TCPB)
5729                  if (service)          /* If user gave a service */
5730                    if (*service) {     /* append it to host name/address */
5731                        strcat(line, ":");
5732                        strcat(line, service);
5733                    }
5734            }
5735#endif /* NODIAL */
5736            /*
5737               Get here with host name/address and all net-specific
5738               parameters set, ready to open the connection.
5739            */
5740            mdmtyp = -nettype;          /* This should have been done */
5741                                        /* already but just in case ... */
5742
5743            debug(F110,"setlin net line[] before ttopen",line,0);
5744            debug(F101,"setlin net mdmtyp before ttopen",line,mdmtyp);
5745
5746            if ((y = ttopen(line, &x, mdmtyp, 0 )) < 0) { /* Try to open */
5747#ifndef VMS
5748                if (errno) {
5749                    int x;
5750                    debug(F111,"set host line, errno","",errno);
5751                    x = strlen(line) + 2;
5752                    if (LINBUFSIZ - x > 100) {
5753                        tp = line + x;
5754                        sprintf(tp,"Can't connect to %s",line);
5755                        perror(tp);
5756                    } else printf("Can't connect to %s\n",line);
5757                } else
5758#endif /* VMS */
5759                  printf("Can't open connection to %s\n",line);
5760                continue;
5761            } else {
5762                success = 1;
5763                break;
5764            }
5765        } /* for-loop */
5766        s = line;
5767    } /* network connection */
5768#endif /* NETCONN */
5769/*
5770  NOTE:
5771  The following will fail if Kermit is running as a daemon with no
5772  controlling tty.  Needs research.
5773*/
5774    if (!success) {
5775        local = dfloc;                  /* Go back to normal */
5776#ifndef MAC
5777        strcpy(ttname,dftty);           /* Restore default tty name */
5778#endif /* MAC */
5779        speed = ttgspd();
5780        network = 0;                    /* No network connection active */
5781        return(0);                      /* Return failure */
5782    }
5783    if (x > -1) local = x;              /* Opened ok, set local/remote. */
5784    network = (mdmtyp < 0);             /* Remember connection type. */
5785    strcpy(ttname,s);                   /* Copy name into real place. */
5786    speed = ttgspd();                   /* Get the current speed. */
5787    debug(F111,"set line ",ttname,local);
5788#ifdef NETCONN
5789    if (network)
5790#ifdef CK_SPEED
5791      /* Force prefixing of 255 on TCP/IP connections... */
5792      if (nettype == NET_TCPB) {
5793          ctlp[255] = 1;
5794      } else
5795#endif /* CK_SPEED */
5796        if (nettype == NET_SX25 || nettype == NET_VX25)
5797          duplex = 1;                   /* Local echo for X.25 */
5798#endif /* NETCONN */
5799#ifdef OS2
5800    if (mdmtyp <= 0)                    /* Network or Direct Connection */
5801      DialerSend(OPT_KERMIT_CONNECT, 0);
5802#endif /* OS2 */
5803    if (autoflow)                       /* Maybe change flow control */
5804      setflow();
5805    return(success = 1);
5806}
5807#endif /* NOLOCAL */
5808
5809#ifndef NOSETKEY
5810/* Save Key maps and in OS/2 Mouse maps */
5811int
5812savkeys(name,disp) char * name; int disp; {
5813    char *tp;
5814    static struct filinfo xx;
5815    int savfil, i, j, k;
5816    char buf[1024];
5817
5818    zclose(ZMFILE);
5819
5820    if (disp) {
5821        xx.bs = 0; xx.cs = 0; xx.rl = 0; xx.org = 0; xx.cc = 0;
5822        xx.typ = 0; xx.dsp = XYFZ_A; xx.os_specific = '\0';
5823        xx.lblopts = 0;
5824        savfil = zopeno(ZMFILE,name,NULL,&xx);
5825    } else savfil = zopeno(ZMFILE,name,NULL,NULL);
5826
5827    if (savfil) {
5828        ztime(&tp);
5829        zsout(ZMFILE, "; C-Kermit SAVE KEYMAP file: ");
5830        zsoutl(ZMFILE,tp);
5831#ifdef OS2
5832        if (mskkeys) {
5833            zsoutl(ZMFILE,
5834         "if eq \"\\v(program)\" \"C-Kermit\" set mskermit keycodes on");
5835        } else {
5836            zsoutl(ZMFILE,
5837         "if NOT eq \"\\v(program)\" \"C-Kermit\" stop 1 C-Kermit required.");
5838            zsoutl(ZMFILE,"set mskermit keycodes off");
5839        }
5840        zsoutl(ZMFILE,"");
5841#endif /* OS2 */
5842
5843        zsoutl(ZMFILE,"; Clear previous keyboard mappings ");
5844        zsoutl(ZMFILE,"set key clear");
5845#ifdef OS2
5846        for (k = 0; k < nttkey; k++) {
5847            if (!ttkeytab[k].flgs) {
5848                sprintf(buf, "set terminal key %s clear", ttkeytab[k].kwd);
5849                zsoutl(ZMFILE,buf);
5850            }
5851        }
5852#endif /* OS2 */
5853        zsoutl(ZMFILE,"");
5854
5855        for (i = 0; i < KMSIZE; i++) {
5856            if (macrotab[i]) {
5857                int len = strlen((char *)macrotab[i]);
5858#ifdef OS2
5859                sprintf(buf,"set key \\%d ",mskkeys ? cktomsk(i) : i);
5860#else /* OS2 */
5861                sprintf(buf,"set key \\%d ",i);
5862#endif /* OS2 */
5863                zsout(ZMFILE,buf);
5864
5865                for (j = 0; j < len; j++) {
5866                    char ch = macrotab[i][j];
5867                    if (ch <= SP || ch >= DEL ||
5868                         ch == '-' || ch == ',') {
5869                        sprintf(buf, "\\{%d}", ch);
5870                        zsout(ZMFILE,buf);
5871                    } else {
5872                        sprintf(buf, "%c", ch);
5873                        zsout(ZMFILE,buf);
5874                    }
5875                }
5876#ifdef OS2
5877                sprintf(buf, "\t; %s", keyname(i));
5878                zsoutl(ZMFILE,buf);
5879#else
5880                zsoutl(ZMFILE,"");
5881#endif /* OS2 */
5882            } else if ( keymap[i] != i ) {
5883#ifndef NOKVERBS
5884                if (IS_KVERB(keymap[i])) {
5885                    for (j = 0; j < nkverbs; j++)
5886                      if (kverbs[j].kwval == (keymap[i] & ~F_KVERB))
5887                        break;
5888                    if (j != nkverbs) {
5889#ifdef OS2
5890                        sprintf(buf, "set key \\%d \\K%s\t; %s",
5891                                mskkeys ? cktomsk(i) : i,
5892                                kverbs[j].kwd, keyname(i)
5893                                );
5894                        zsoutl(ZMFILE,buf);
5895#else
5896                        sprintf(buf, "set key \\%d \\K%s", i, kverbs[j].kwd);
5897                        zsoutl(ZMFILE,buf);
5898#endif
5899                    }
5900                } else
5901#endif /* NOKVERBS */
5902                  {
5903#ifdef OS2
5904                      sprintf(buf, "set key \\%d \\{%d}\t; %s",
5905                              mskkeys ? cktomsk(i) : i,
5906                              keymap[i],
5907                              keyname(i)
5908                              );
5909                      zsoutl(ZMFILE,buf);
5910#else
5911                      sprintf(buf, "set key \\%d \\{%d}", i, keymap[i]);
5912                      zsoutl(ZMFILE,buf);
5913#endif /* OS2 */
5914                  }
5915            }
5916        }
5917#ifdef OS2
5918        /* OS/2 also has the SET TERMINAL KEY <termtype> defines */
5919        for (k = 0; k < nttkey; k++) {
5920            extern struct keynode * ttkeymap[];
5921            struct keynode * pnode = NULL;
5922
5923            if (ttkeytab[k].flgs)       /* Don't process CM_INV or CM_ABR */
5924              continue;
5925
5926            zsoutl(ZMFILE,"");
5927            sprintf(buf, "; SET TERMINAL KEY %s", ttkeytab[k].kwd );
5928            zsoutl(ZMFILE,buf);
5929
5930            for (pnode = ttkeymap[ttkeytab[k].kwval];
5931                 pnode;
5932                 pnode = pnode->next
5933                 ) {
5934                switch (pnode->def.type) {
5935                  case key:
5936                    sprintf(buf, "set terminal key %s \\%d \\{%d}\t; %s",
5937                            ttkeytab[k].kwd,
5938                            mskkeys ? cktomsk(pnode->key) : pnode->key,
5939                            pnode->def.key.scancode,
5940                            keyname(pnode->key)
5941                            );
5942                    zsoutl(ZMFILE,buf);
5943                    break;
5944                  case kverb:
5945                    for (j = 0; j < nkverbs; j++)
5946                      if (kverbs[j].kwval == (pnode->def.kverb.id & ~F_KVERB))
5947                        break;
5948                    if (j != nkverbs) {
5949                        sprintf(buf, "set terminal key %s \\%d \\K%s\t; %s",
5950                                ttkeytab[k].kwd,
5951                                mskkeys ? cktomsk(pnode->key) : pnode->key,
5952                                kverbs[j].kwd, keyname(pnode->key)
5953                                );
5954                        zsoutl(ZMFILE,buf);
5955                    }
5956                    break;
5957                  case macro: {
5958                      int len = strlen((char *)pnode->def.macro.string);
5959                      sprintf(buf,"set terminal key %s \\%d ",
5960                              ttkeytab[k].kwd,
5961                              mskkeys ? cktomsk(pnode->key) : pnode->key);
5962                      zsout(ZMFILE,buf);
5963
5964                      for (j = 0; j < len; j++) {
5965                          char ch = pnode->def.macro.string[j];
5966                          if (ch <= SP || ch >= DEL ||
5967                              ch == '-' || ch == ',') {
5968                              sprintf(buf, "\\{%d}", ch);
5969                              zsout(ZMFILE,buf);
5970                          } else {
5971                              sprintf(buf, "%c", ch);
5972                              zsout(ZMFILE,buf);
5973                          }
5974                      }
5975                      sprintf(buf, "\t; %s", keyname(pnode->key));
5976                      zsoutl(ZMFILE,buf);
5977                      break;
5978                  }
5979                  case esc:
5980                    sprintf(buf,"set terminal key %s \\%d \\{27}\\{%d}\t; %s",
5981                            ttkeytab[k].kwd,
5982                            mskkeys ? cktomsk(pnode->key) : pnode->key,
5983                            pnode->def.esc.key & ~F_ESC,
5984                            keyname(pnode->key)
5985                            );
5986                    zsoutl(ZMFILE,buf);
5987                    break;
5988                  case csi:
5989                    sprintf(buf,"set terminal key %s \\%d \\{27}[\\{%d}\t; %s",
5990                            ttkeytab[k].kwd,
5991                            mskkeys ? cktomsk(pnode->key) : pnode->key,
5992                            pnode->def.csi.key & ~F_CSI,
5993                            keyname(pnode->key)
5994                            );
5995                    zsoutl(ZMFILE,buf);
5996                    break;
5997                  default:
5998                    continue;
5999                }
6000            }
6001        }
6002#endif /* OS2 */
6003
6004        zsoutl(ZMFILE,"");
6005        zsoutl(ZMFILE,"; End");
6006        zclose(ZMFILE);
6007        return(success = 1);
6008    } else {
6009        return(success = 0);
6010    }
6011}
6012#endif /* NOSETKEY */
6013
6014int
6015dosave(xx) int xx; {
6016    int x, y, disp;
6017    char * s = NULL;
6018    extern struct keytab disptb[];
6019#ifdef ZFNQFP
6020    struct zfnfp * fnp;
6021#endif /* ZFNQFP */
6022
6023    switch (xx) {
6024#ifndef NOSETKEY
6025      case XSKEY:
6026        y = cmofi("Name of INI file","keymap.ini",&s,xxstring);
6027        if (y < 0) return(y);
6028        if (y == 2) {
6029            printf("?Sorry, %s is a directory name\n",s);
6030            return(-9);
6031        }
6032#ifdef ZFNQFP
6033        if (fnp = zfnqfp(s,TMPBUFSIZ - 1,tmpbuf)) {
6034            if (fnp->fpath)
6035                if ((int) strlen(fnp->fpath) > 0)
6036                  s = fnp->fpath;
6037        }
6038#endif /* ZFNQFP */
6039
6040        strcpy(line,s);
6041        s = line;
6042#ifdef MAC
6043        y = 0;
6044#else
6045        if ((y = cmkey(disptb,2,"Disposition","new",xxstring)) < 0)
6046          return(y);
6047#endif /* MAC */
6048        disp = y;   
6049        if ((x = cmcfm()) < 0) return(x);
6050        return (savkeys(s,disp));
6051#endif /* NOSETKEY */
6052
6053      default:
6054        if ((x = cmcfm()) < 0) return(x);
6055        printf("Not implemented - %s\n",cmdbuf);
6056        return(success = 0);
6057    }
6058}
6059#endif /* NOICP */
Note: See TracBrowser for help on using the repository browser.