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

Revision 10780, 118.6 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"                     /* Symbol definitions */
2#ifndef NOICP
3
4/*  C K U U S 3 --  "User Interface" for Unix Kermit, part 3  */
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/*  SET command (but much material has been split off into ckuus7.c). */
20 
21/*
22  Kermit-specific includes.
23  Definitions here supersede those from system include files.
24*/
25#include "ckcdeb.h"                     /* Debugging & compiler things */
26#include "ckcasc.h"                     /* ASCII character symbols */
27#include "ckcker.h"                     /* Kermit application definitions */
28#include "ckcxla.h"                     /* Character set translation */
29#include "ckcnet.h"                     /* Network symbols */
30#include "ckuusr.h"                     /* User interface symbols */
31#ifdef OS2
32#ifdef NT
33#include "ckntap.h"                     /* Microsoft TAPI */
34#endif /* NT */
35#ifdef CK_NETBIOS
36#include <os2.h>
37#ifdef COMMENT                          /* Would you believe */
38#undef COMMENT                          /* <os2.h> defines this ? */
39#endif /* COMMENT */
40#include "ckonbi.h"
41extern UCHAR NetBiosAdapter;
42#endif /* CK_NETBIOS */
43#include "ckocon.h"
44#include "ckokey.h"
45extern unsigned char colorcmd;  /* Command-screen colors */
46extern struct keytab ttyclrtab[];
47extern int nclrs;
48extern int tt_cols[], tt_rows[], tt_szchng[];
49_PROTOTYP(int setprty, (void));
50extern char startupdir[], exedir[];
51extern int srvidl;
52#endif /* OS2 */
53
54#ifdef CK_RECALL
55extern int cm_retry;
56#endif /* CK_RECALL */
57
58/* Variables */
59
60int cmd_quoting = 1;
61
62extern char * ckprompt;                 /* Default prompt */
63
64extern xx_strp xxstring;
65
66extern struct ck_p ptab[];
67extern int protocol;
68
69#ifndef NOSERVER
70extern int ngetpath;
71extern char * getpath[];
72#endif /* NOSERVER */
73
74extern int size, spsiz, spmax, urpsiz, srvtim, slostart,
75  local, server, success, dest,
76  flow, autoflow, binary, xfermode, delay, parity, escape, what, srvdis,
77  turn, duplex, backgrd,
78  turnch, bctr, mdmtyp, keep, maxtry, unkcs, network,
79  ebqflg, quiet, swcapr, nettype,
80  wslotr, lscapr, lscapu,
81  carrier, debses,
82  cdtimo, nlangs, bgset, pflag, msgflg, dblchar,
83  cmdmsk, spsizr, wildxpand, suspend,
84  techo, rptena, rptmin, docrc,
85  xfrcan, xfrchr, xfrnum, pacing, xitwarn, xitsta,
86  cmd_cols, cmd_rows, ckxech, xaskmore, xfrbel;
87
88#ifdef TCPSOCKET
89  extern int tn_exit;
90#endif /* TCPSOCKET */
91  extern int exitonclose;
92
93#ifndef NOKVERBS
94extern int nkverbs;
95extern struct keytab kverbs[];
96#endif /* NOKVERBS */
97
98#ifdef TNCODE
99extern int ttnproto;
100#endif /* TNCODE */
101
102extern char *ccntab[];                  /* Names of control chars */
103
104#ifdef CK_SPEED
105extern short ctlp[];                    /* Control-prefix table */
106extern int prefixing;
107static struct keytab pfxtab[] = {
108    "all",         PX_ALL, 0,
109    "cautious",    PX_CAU, 0,
110    "minimal",     PX_WIL, 0,
111    "none",        PX_NON, 0
112};
113#endif /* CK_SPEED */
114
115#ifndef NOSCRIPT
116extern int secho;                       /* Whether SCRIPT cmd should echo */
117#endif /* NOSCRIPT */
118
119#ifdef DCMDBUF
120extern char *atmbuf, *atxbuf;
121#else
122extern char atmbuf[], atxbuf[];
123#endif /* DCMDBUF */
124
125extern char psave[];
126extern char uidbuf[];
127
128#ifndef NOSPL
129int DeleteStartupFile =
130#ifdef NT
131                        1
132#else
133                        0
134#endif /* NT */
135;
136char pwbuf[64]  = { NUL, NUL };
137char prmbuf[64] = { NUL, NUL };
138#ifdef DCMDBUF
139extern int *count, *takerr, *merror, *inpcas;
140#else
141extern int count[], takerr[], merror[], inpcas[];
142#endif /* DCMDBUF */
143extern int mecho;                       /* Macro echo */
144extern long ck_alarm;
145extern char alrm_date[], alrm_time[];
146#else
147extern int takerr[];
148#endif /* NOSPL */
149
150extern int x_ifnum;
151extern int bigsbsiz, bigrbsiz;          /* Packet buffers */
152
153extern long speed;                      /* Terminal speed */
154
155extern CHAR sstate;                     /* Protocol start state */
156extern CHAR myctlq;                     /* Control-character prefix */
157extern CHAR myrptq;                     /* Repeat-count prefix */
158extern CHAR mystch, seol;               /* Packet start and end chars */
159extern char ttname[];                   /* Communication device name */
160extern char myhost[] ;
161extern char inidir[];                   /* Ini File directory */
162
163#ifndef NOSETKEY
164extern KEY *keymap;                     /* Character map for SET KEY (1:1)  */
165extern MACRO *macrotab;                 /* Macro map for SET KEY (1:string) */
166#ifdef OS2
167int wideresult;                         /* For SET KEY, wide OS/2 scan codes */
168extern int tt_scrsize[];                /* Scrollback buffer Sizes */
169#endif /* OS2 */
170#endif /* NOSETKEY */
171
172extern char * printfile;                /* NULL if printer not redirected */
173extern int printpipe;                   /* For SET PRINTER */
174
175#ifdef OS2
176extern int tcp_avail;                   /* Nonzero if TCP/IP is available */
177#ifdef DECNET
178extern int dnet_avail;                  /* Ditto for DECnet */
179#endif /* DECNET */
180#ifdef SUPERLAT
181extern int slat_avail;
182#endif /* SUPERLAT */
183#endif /* OS2 */
184
185static struct keytab logintab[] = {
186    "password", LOGI_PSW, CM_INV,
187    "prompt",   LOGI_PRM, CM_INV,
188    "userid",   LOGI_UID, 0
189};
190
191#ifndef NOCSETS
192/* system-independent character sets, defined in ckcxla.[ch] */
193extern struct csinfo tcsinfo[];
194extern struct langinfo langs[];
195
196/* Other character-set related variables */
197extern int tcharset, tslevel, language;
198#endif /* NOCSETS */
199
200/* Declarations from cmd package */
201 
202#ifdef DCMDBUF
203extern char *cmdbuf;                    /* Command buffer */
204extern char *line;
205extern char *tmpbuf;
206#else
207extern char cmdbuf[];                   /* Command buffer */
208extern char line[];                     /* Character buffer for anything */
209extern char tmpbuf[];
210#endif /* DCMDBUF */
211
212/* From main ckuser module... */
213 
214extern char *tp, *lp;                   /* Temporary buffer */
215
216extern int tlevel;                      /* Take Command file level */
217
218#ifndef NOSPL
219extern int cmdlvl;                      /* Overall command level */
220#endif /* NOSPL */
221
222#ifndef NOLOCAL
223#ifdef UNIX
224extern int sessft;                      /* Session-log file type */
225#else
226#ifdef OSK
227extern int sessft;
228#endif /* OSK */
229#endif /* UNIX */
230#endif /* NOLOCAL */
231
232char * tempdir = NULL;
233
234#ifdef VMS
235int vms_msgs = 1;                       /* SET MESSAGES */
236#endif /* VMS */
237
238/* Keyword tables for SET commands */
239 
240#ifdef CK_SPEED
241struct keytab ctltab[] = {
242    "prefixed",   1, 0,                 /* Note, the values are important. */
243    "unprefixed", 0, 0
244};
245#endif /* CK_SPEED */
246
247#ifndef NOSPL
248struct keytab outptab[] = {             /* SET OUTPUT parameters */
249    "pacing", 0, 0                      /* only one so far... */
250};
251#endif /* NOSPL */
252
253struct keytab chktab[] = {              /* Block check types */
254    "1", 1, 0,                          /* 1 =  6-bit checksum */
255    "2", 2, 0,                          /* 2 = 12-bit checksum */
256    "3", 3, 0,                          /* 3 = 16-bit CRC */
257    "blank-free-2", 4, 0                /* B = 12-bit checksum, no blanks */
258};
259
260struct keytab rpttab[] = {              /* SET REPEAT */
261    "counts",    0, 0,                  /* On or Off */
262#ifdef COMMENT
263    "minimum",   1, 0,                  /* Threshhold */
264#endif /* COMMENT */
265    "prefix",    2, 0                   /* Repeat-prefix character value */
266};
267
268#ifndef NOLOCAL
269/* For SET [ MODEM ] CARRIER, and also for SET DIAL CONNECT */
270
271struct keytab crrtab[] = {
272    "auto", CAR_AUT, 0,                 /* 2 */
273    "off",  CAR_OFF, 0,                 /* 0 */
274    "on",   CAR_ON, 0                   /* 1 */
275};
276int ncrr = 3;
277
278#endif /* NOLOCAL */
279
280struct keytab qvtab[] = {               /* Quiet/Verbose table */
281    "quiet", 1, 0,
282    "verbose", 0, 0
283};
284int nqvt = 2;
285
286/* For SET DEBUG */
287
288struct keytab dbgtab[] = {
289    "off",     0,  0,
290    "on",      1,  0,
291    "session", 2,  0
292};
293int ndbg = 3;
294
295#ifndef NOLOCAL
296/* Transmission speeds */
297
298/*
299  Note, the values are encoded in cps rather than bps because 19200 and higher
300  are too big for some ints.  All but 75bps are multiples of ten.  Result of
301  lookup in this table must be multiplied by 10 to get actual speed in bps.
302  If this number is 70, it must be changed to 75.  If it is 888, this means
303  75/1200 split speed.
304
305  The values are generic, rather than specific to UNIX.  We can't use B75,
306  B1200, B9600, etc, because non-UNIX versions of C-Kermit will not
307  necessarily have these symbols defined.  The BPS_xxx symbols are
308  Kermit-specific, and are defined in ckcdeb.h or on the CC command line.
309
310  Like all other keytabs, this one must be in "alphabetical" order,
311  rather than numeric order.
312*/
313struct keytab spdtab[] = {
314    "0",      0,  CM_INV,
315    "110",   11,  0,
316#ifdef BPS_115K
317 "115200",11520,  0,
318#endif /* BPS_115K */
319  "1200",   120,  0,
320#ifdef BPS_134
321  "134.5",  134,  0,
322#endif /* BPS_134 */
323#ifdef BPS_14K
324  "14400", 1440,  0,
325#endif /* BPS_14K */
326#ifdef BPS_150
327  "150",     15,  0,
328#endif /* BPS_150 */
329#ifdef BPS_19K
330  "19200", 1920,  0,
331#endif /* BPS_19K */
332#ifdef BPS_200
333  "200",     20,  0,
334#endif /* BPS_200 */
335#ifdef BPS_230K
336  "230400", 23040, 0,
337#endif /* BPS_230K */
338  "2400",   240,  0,
339#ifdef BPS_28K
340  "28800", 2880,  0,
341#endif /* BPS_28K */
342  "300",     30,  0,
343#ifdef BPS_3600
344  "3600",   360,  0,
345#endif /* BPS_3600 */
346#ifdef BPS_38K
347  "38400", 3840,  0,
348#endif /* BPS_38K */
349  "4800",   480,  0,
350#ifdef BPS_50
351  "50",       5,  0,
352#endif /* BPS_50 */
353#ifdef BPS_57K
354  "57600", 5760,  0,
355#endif /* BPS_57K */
356  "600",     60,  0,
357#ifdef BPS_7200
358  "7200",   720,  0,
359#endif /* BPS_7200 */
360#ifdef BPS_75
361  "75",       7,  0,
362#endif /* BPS_75 */
363#ifdef BPS_7512
364  "75/1200",888,  0,            /* Special code "888" for split speed */
365#endif /* BPS_7512 */
366#ifdef BPS_76K
367  "76800", 7680,  0,
368#endif /* BPS_76K */
369  "9600",   960,  0
370};
371int nspd = (sizeof(spdtab) / sizeof(struct keytab)); /* How many speeds */
372#endif /* NOLOCAL */
373
374#ifndef NOCSETS
375extern struct keytab lngtab[];          /* Languages for SET LANGUAGE */
376extern int nlng;
377#endif /* NOCSETS */
378
379#ifndef NOLOCAL
380/* Duplex keyword table */
381 
382struct keytab dpxtab[] = {
383    "full",      0, 0,
384    "half",      1, 0
385};
386#endif /* NOLOCAL */
387 
388/* SET FILE parameters */
389
390struct keytab filtab[] = {
391    "bytesize",         XYFILS, 0,
392#ifndef NOCSETS
393    "character-set",    XYFILC, 0,
394#endif /* NOCSETS */
395    "collision",        XYFILX, 0,
396    "destination",      XYFILY, 0,
397    "display",          XYFILD, CM_INV,
398#ifdef CK_TMPDIR
399    "download-directory", XYFILG, 0,
400#endif /* CK_TMPDIR */
401    "end-of-line",      XYFILA, 0,
402    "eol",              XYFILA, CM_INV,
403    "incomplete",       XYFILI, 0,
404#ifdef CK_LABELED
405    "label",            XYFILL, 0,
406#endif /* CK_LABELED */
407    "names",            XYFILN, 0,
408#ifdef VMS
409    "record-length",    XYFILR, 0,
410#endif /* VMS */
411    "type",             XYFILT, 0,
412    "warning",          XYFILW, CM_INV
413};
414int nfilp = (sizeof(filtab) / sizeof(struct keytab));
415
416/* Flow Control */
417
418struct keytab flotab[] = {              /* SET FLOW-CONTROL keyword table */
419    "automatic", FLO_AUTO, 0,
420#ifdef CK_DTRCD
421    "dtr/cd",    FLO_DTRC, 0,
422#endif /* CK_DTRCD */
423#ifdef CK_DTRCTS
424    "dtr/cts",   FLO_DTRT, 0,
425#endif /* CK_DTRCTS */
426    "keep",      FLO_KEEP, 0,
427    "none",      FLO_NONE, 0,
428#ifdef CK_RTSCTS
429    "rts/cts",   FLO_RTSC, 0,
430#endif /* CK_RTSCTS */
431#ifndef Plan9
432    "xon/xoff",  FLO_XONX, 0
433#endif /* Plan9 */
434};
435int nflo = (sizeof(flotab) / sizeof(struct keytab));
436
437/*  Handshake characters  */
438 
439struct keytab hshtab[] = {
440    "bell", 007, 0,
441    "code", 998, 0,
442    "cr",   015, 0,
443    "esc",  033, 0,
444    "lf",   012, 0,
445    "none", 999, 0,                     /* (can't use negative numbers) */
446    "xoff", 023, 0,
447    "xon",  021, 0
448};
449int nhsh = (sizeof(hshtab) / sizeof(struct keytab));
450 
451#ifndef NOLOCAL
452static struct keytab sfttab[] = {       /* File types for SET SESSION-LOG */
453    "ascii",     XYFT_B, CM_INV,
454    "binary",    XYFT_B, 0,
455    "text",      XYFT_T, 0
456};
457static int nsfttab = (sizeof(sfttab) / sizeof(struct keytab));
458#endif /* NOLOCAL */
459
460#ifndef NODIAL
461
462#ifdef NETCONN                          /* Networks directory depends */
463int nnetdir = 0;                        /* on DIAL code -- fix later... */
464char *netdir[MAXDDIR];
465#endif /* NETCONN */
466
467_PROTOTYP( static int setdial, (int) );
468_PROTOTYP( static int setdcd, (void) );
469_PROTOTYP( static int parsdir, (int) );
470_PROTOTYP( static int cklogin, (void) );
471
472#ifndef MINIDIAL
473#ifdef OLDTBCODE
474extern int tbmodel;                     /* Telebit model ID */
475#endif /* OLDTBCODE */
476#endif /* MINIDIAL */
477
478extern MDMINF *modemp[];                /* Pointers to modem info structs */
479extern struct keytab mdmtab[] ;         /* Modem types (in module ckudia.c) */
480extern int nmdm;                        /* Number of them */
481
482_PROTOTYP(static int dialstr,(char **, char *));
483
484extern int dialhng, dialtmo, dialksp, dialdpy, dialmhu, dialec, dialdc;
485extern int dialrtr, dialint, dialudt, dialsrt, dialrstr, mdmwaitd;
486extern int mdmspd, dialfc, dialmth, dialesc;
487
488int dialcvt = 2;                        /* DIAL CONVERT-DIRECTORY */
489int dialcnf = 0;                        /* DIAL CONFIRMATION */
490int dialcon = 2;                        /* DIAL CONNECT */
491int dialcq  = 0;                        /* DIAL CONNECT AUTO quiet/verbose */
492extern long dialmax, dialcapas;
493int usermdm = 0;
494extern int ndialdir;
495extern char *dialini,   *dialmstr, *dialmprmt, *dialdir[], *dialcmd,  *dialnpr,
496 *dialdcon, *dialdcoff, *dialecon, *dialecoff, *dialhcmd,
497 *dialhwfc, *dialswfc,  *dialnofc, *dialtone,  *dialpulse, *dialname, *diallac;
498extern char *diallcc,   *dialixp,  *dialixs,   *dialldp,   *diallds,  *dialtfp,
499 *dialpxx,  *dialpxi,   *dialpxo,  *dialsfx,   *dialaaon,  *dialaaoff;
500
501#define MAXTOLLFREE 8
502int ntollfree = 0;
503char *dialtfc[MAXTOLLFREE] = {
504    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
505};
506
507static struct keytab drstrtab[] = {
508    "international", 5, 0,
509    "local",         2, 0,
510    "long-distance", 4, 0,
511    "none",          6, 0
512};
513
514static struct keytab dcnvtab[] = {
515    "ask",  2, 0,
516    "off",  0, 0,
517    "on",   1, 0
518};
519
520struct keytab setmdm[] = {
521    "capabilities",     XYDCAP,  0,
522    "carrier-watch",    XYDMCD,  0,
523    "command",          XYDSTR,  0,
524    "compression",      XYDDC,   0,
525    "dial-command",     XYDDIA,  0,
526    "error-correction", XYDEC,   0,
527    "escape-character", XYDESC,  0,
528    "flow-control",     XYDFC,   0,
529    "hangup-method",    XYDMHU,  0,
530    "kermit-spoof",     XYDKSP,  0,
531    "maximum-speed",    XYDMAX,  0,
532    "name",             XYDNAM,  0,
533    "speed-matching",   XYDSPD,  0,
534    "type",             XYDTYP,  0
535};
536int nsetmdm = (sizeof(setmdm) / sizeof(struct keytab));
537
538struct keytab mdmcap[] = {
539    "at-commands",      CKD_AT,  0,
540    "compression",      CKD_DC,  0,
541    "dc",               CKD_DC,  CM_INV,
542    "ec",               CKD_EC,  CM_INV,
543    "error-correction", CKD_EC,  0,
544    "hardware-flow",    CKD_HW,  0,
545    "hwfc",             CKD_HW,  CM_INV,
546    "itu",              CKD_V25, CM_INV,
547    "kermit-spoof",     CKD_KS,  0,
548    "ks",               CKD_KS,  CM_INV,
549    "sb",               CKD_SB,  CM_INV,
550    "software-flow",    CKD_SW,  0,
551    "speed-buffering",  CKD_SB,  0,
552    "swfc",             CKD_SW,  CM_INV,
553    "tb",               CKD_TB,  CM_INV,
554    "telebit",          CKD_TB,  0,
555    "v25bis-commands",  CKD_V25, 0
556};
557int nmdmcap = (sizeof(mdmcap) / sizeof(struct keytab));
558
559struct keytab dialtab[] = {             /* SET DIAL table */
560    "area-code",        XYDLAC, 0,      /* Also still includes items     */
561    "compression",      XYDDC,  CM_INV, /* that were moved to SET MODEM, */
562    "confirmation",     XYDCNF, 0,      /* but they are CM_INVisible...  */
563    "connect",          XYDCON, 0,
564    "convert-directory",XYDCVT, 0,
565    "country-code",     XYDLCC, 0,
566    "dial-command",     XYDDIA, CM_INV,
567    "directory",        XYDDIR, 0,
568    "display",          XYDDPY, 0,
569    "escape-character", XYDESC, CM_INV,
570    "error-correction", XYDEC,  CM_INV,
571    "flow-control",     XYDFC,  CM_INV,
572    "hangup",           XYDHUP, 0,
573    "interval",         XYDINT, 0,
574    "in",               XYDINI, CM_INV|CM_ABR,
575    "init-string",      XYDINI, CM_INV,
576    "intl-prefix",      XYDIXP, 0,
577    "intl-suffix",      XYDIXS, 0,
578    "kermit-spoof",     XYDKSP, CM_INV,
579    "local-area-code",  XYDLAC, CM_INV,
580    "ld-prefix",        XYDLDP, 0,
581    "ld-suffix",        XYDLDS, 0,
582    "m",                XYDMTH, CM_INV|CM_ABR,
583#ifdef MDMHUP
584    "me",               XYDMTH, CM_INV|CM_ABR,
585#endif /* MDMHUP */
586    "method",           XYDMTH, 0,
587    "mnp-enable",       XYDMNP, CM_INV, /* obsolete but still accepted */
588#ifdef MDMHUP
589    "modem-hangup",     XYDMHU, CM_INV,
590#endif /* MDMHUP */
591    "pbx-exchange",     XYDPXX, 0,
592    "pbx-inside-prefix",XYDPXI, 0,
593    "pbx-outside-prefix",XYDPXO, 0,
594    "prefix",           XYDNPR,  0,
595    "restrict",         XYDRSTR, 0,
596    "retries",          XYDRTM,  0,
597    "sort",             XYDSRT,  0,
598    "speed-matching",   XYDSPD, CM_INV,
599    "string",           XYDSTR, CM_INV,
600    "suffix",           XYDSFX, 0,
601    "timeout",          XYDTMO, 0,
602    "tf-area-code",     XYDTFC, CM_INV,
603    "tf-prefix",        XYDTFP, CM_INV,
604    "toll-free-area-code",XYDTFC, 0,
605    "toll-free-prefix", XYDTFP, 0
606};
607int ndial = (sizeof(dialtab) / sizeof(struct keytab));
608
609#ifdef MDMHUP
610struct keytab mdmhang[] = {
611    "modem-command", 1, 0,
612    "rs232-signal",  0, 0,
613    "v24-signal",    0, CM_INV
614};
615#endif /* MDMHUP */
616
617struct keytab dial_str[] = {
618    "autoanswer",       XYDS_AN, 0,     /* autoanswer */
619    "compression",      XYDS_DC, 0,     /* data compression */
620    "dial-mode-prompt", XYDS_MP, 0, /* dial mode prompt */
621    "dial-mode-string", XYDS_MS, 0, /* dial mode string */
622    "error-correction", XYDS_EC, 0,     /* error correction */
623    "hangup-command",   XYDS_HU, 0,     /* hangup command */
624    "hardware-flow",    XYDS_HW, 0,     /* hwfc */
625    "init-string",      XYDS_IN, 0,     /* init string */
626    "no-flow-control",  XYDS_NF, 0,     /* no flow control */
627    "pulse",            XYDS_DP, 0,     /* pulse */
628    "software-flow",    XYDS_SW, 0,     /* swfc */
629    "tone",             XYDS_DT, 0      /* tone */
630};
631int ndstr = (sizeof(dial_str) / sizeof(struct keytab));
632
633struct keytab dial_fc[] = {
634    "auto",     FLO_AUTO, 0,
635    "none",     FLO_NONE, 0,
636    "rts/cts",  FLO_RTSC, 0,
637    "xon/xoff", FLO_XONX, 0
638};
639
640struct keytab dial_m[] = {              /* DIAL METHOD */
641    "default", XYDM_D, 0,
642    "pulse",   XYDM_P, 0,
643    "tone",    XYDM_T, 0
644};
645                           
646#ifdef CK_TAPI
647struct keytab tapitab[] = {             /* SET Microsoft TAPI */
648   "configure-line",     XYTAPI_CFG,  CM_INV,
649   "dialing-properties", XYTAPI_DIAL, CM_INV,
650   "line",               XYTAPI_LIN, 0,
651   "location",           XYTAPI_LOC, 0
652};
653int ntapitab = (sizeof(tapitab)/sizeof(struct keytab)) ;
654
655struct keytab * tapiloctab = NULL;      /* Microsoft TAPI Locations */
656int ntapiloc = 0;
657extern struct keytab * tapilinetab;     /* Microsoft TAPI Line Devices */
658extern int ntapiline;
659#endif /* CK_TAPI */
660#endif /* NODIAL */
661 
662#ifndef NOPUSH
663extern int nopush;
664#ifdef UNIX
665struct keytab wildtab[] = {             /* SET WILDCARD-EXPANSION */
666    "kermit",  0, 0,
667    "shell",   1, 0
668};
669#endif /* UNIX */
670#endif /* NOPUSH */
671
672#ifdef NETCONN
673extern struct keytab netcmd[], netkey[];
674extern int nnets, nnetkey;
675#ifdef TCPSOCKET
676#ifdef SOL_SOCKET
677extern struct keytab tcpopt[];
678extern int ntcpopt;
679#ifdef SO_LINGER
680_PROTOTYP( int linger, (int,int) );
681#endif /* SO_LINGER */
682#ifdef TCP_NODELAY
683_PROTOTYP( int no_delay, (int) );
684#endif /* TCP_NODELAY */
685#ifdef SO_SNDBUF
686_PROTOTYP( int sendbuf, (int) );
687#endif /* SO_SNDBUF */
688#ifdef SO_RCVBUF
689_PROTOTYP( int recvbuf, (int) );
690#endif /* SO_RCVBUF */
691#ifdef SO_KEEPALIVE
692_PROTOTYP( int keepalive, (int) );
693#endif /* SO_KEEPALIVE */
694#endif /* SOL_SOCKET */
695#endif /* TCPSOCKET */
696#ifdef NPIPE
697char pipename[PIPENAML+1] = { NUL, NUL };
698#endif /* NPIPE */
699#ifdef CK_NETBIOS
700extern unsigned char NetBiosName[];
701#endif /* CK_NETBIOS */
702#endif /* NETCONN */
703
704#ifdef ANYX25
705struct keytab x25tab[] = {
706    "call-user-data",    XYUDAT, 0,
707    "closed-user-group", XYCLOS, 0,
708    "reverse-charge",    XYREVC, 0 
709};
710int nx25 = (sizeof(x25tab) / sizeof(struct keytab));
711
712struct keytab padx3tab[] = {
713    "break-action",         PAD_BREAK_ACTION,           0,
714    "break-character",      PAD_BREAK_CHARACTER,        0,
715    "character-delete",     PAD_CHAR_DELETE_CHAR,       0,
716    "cr-padding",           PAD_PADDING_AFTER_CR,       0,
717    "discard-output",       PAD_SUPPRESSION_OF_DATA,    0,
718    "echo",                 PAD_ECHO,                   0,
719    "editing",              PAD_EDITING,                0,
720    "escape",               PAD_ESCAPE,                 0,
721    "forward",              PAD_DATA_FORWARD_CHAR,      0,
722    "lf-padding",           PAD_PADDING_AFTER_LF,       0,
723    "lf-insert",            PAD_LF_AFTER_CR,            0,
724    "line-delete",          PAD_BUFFER_DELETE_CHAR,     0,
725    "line-display",         PAD_BUFFER_DISPLAY_CHAR,    0,
726    "line-fold",            PAD_LINE_FOLDING,           0,
727    "pad-flow-control",     PAD_FLOW_CONTROL_BY_PAD,    0,
728    "service-signals",      PAD_SUPPRESSION_OF_SIGNALS, 0,
729    "timeout",              PAD_DATA_FORWARD_TIMEOUT,   0,
730/* Speed is read-only */
731    "transmission-rate",    PAD_LINE_SPEED,             0,
732    "user-flow-control",    PAD_FLOW_CONTROL_BY_USER,   0
733};
734int npadx3 = (sizeof(padx3tab) / sizeof(struct keytab));
735#endif /* ANYX25 */
736
737/* Parity keyword table */
738 
739struct keytab partbl[] = {
740    "even",    'e', 0,
741    "mark",    'm', 0,
742    "none",     0 , 0,
743    "odd",     'o', 0,
744    "space",   's', 0
745};
746int npar = (sizeof(partbl) / sizeof(struct keytab));
747 
748/* On/Off table */
749 
750struct keytab onoff[] = {
751    "off",       0, 0,
752    "on",        1, 0
753};
754 
755static
756struct keytab xittab[] = {              /* SET EXIT */
757    "on-disconnect", 2, 0,              /* ...ON-DISCONNECT */
758    "status",        0, 0,              /* ...STATUS */
759    "warning",       1, 0               /* ...WARNING */
760};
761int nexit = (sizeof(xittab) / sizeof(struct keytab));
762
763struct keytab xitwtab[] = {             /* SET EXIT WARNING */
764    "always", 2, 0,                     /* even when not connected */
765    "off",    0, 0,                     /* no warning     */
766    "on",     1, 0                      /* when connected */
767};
768int nexitw = (sizeof(xitwtab) / sizeof(struct keytab));
769
770struct keytab rltab[] = {
771    "local",     1, 0,
772    "off",       0, CM_INV,
773    "on",        1, CM_INV,
774    "remote",    0, 0
775};
776int nrlt = (sizeof(rltab) / sizeof(struct keytab));
777
778/* Incomplete File Disposition table */
779static
780struct keytab ifdtab[] = {
781    "discard",   0, 0,
782    "keep",      1, 0
783};
784
785/* SET TAKE parameters table */
786static
787struct keytab taktab[] = {
788    "echo",  0, 0,
789    "error", 1, 0,
790    "off",   2, CM_INV,                 /* For compatibility */
791    "on",    3, CM_INV                  /* with MS-DOS Kermit... */
792};
793
794#ifndef NOSPL
795static
796struct keytab suftab[] = {              /* (what to do with) STARTUP-FILE */
797    "delete", 1, 0,
798    "keep",   0, 0
799};
800
801/* SET MACRO parameters table */
802static
803struct keytab smactab[] = {
804    "echo",  0, 0,
805    "error", 1, 0
806};
807#endif /* NOSPL */
808
809#ifndef NOSCRIPT
810static
811struct keytab scrtab[] = {
812    "echo",  0, 0
813};
814#endif /* NOSCRIPT */
815
816/* SET COMMAND table */
817struct keytab scmdtab[] = {
818    "bytesize",  SCMD_BSZ, 0,
819#ifdef OS2
820    "color",     SCMD_COL, 0,
821    "cursor-position", SCMD_CUR, 0,
822#endif /* OS2 */
823    "height",    SCMD_HIG, 0,
824    "more-prompting",  SCMD_MOR, 0,
825    "quoting",   SCMD_QUO, 0
826#ifdef CK_RECALL
827,   "recall-buffer-size", SCMD_RCL, 0
828#endif /* CK_RECALL */
829#ifdef CK_RECALL
830,   "retry", SCMD_RTR, 0
831#endif /* CK_RECALL */
832#ifdef OS2
833#ifdef ONETERMUPD
834,  "scrollback",  SCMD_SCR, 0
835#endif /* ONETERMUPD */
836#endif /* OS2 */
837,   "width",     SCMD_WID, 0
838};
839int nbytt = (sizeof(scmdtab) / sizeof(struct keytab));
840
841#ifndef NOSERVER
842/* Server parameters table */
843struct keytab srvtab[] = {
844    "display",  XYSERD, 0,
845    "get-path", XYSERP, 0,
846#ifdef OS2
847    "idle-timeout", XYSERI, 0,
848#endif /* OS2 */
849    "login",    XYSERL, 0,
850    "timeout",  XYSERT, 0
851};
852int nsrvt = (sizeof(srvtab) / sizeof(struct keytab));
853#endif /* NOSERVER */
854
855/* SET TRANSFER/XFER table */
856
857struct keytab tstab[] = {
858    "bell",          XYX_BEL,   0,
859#ifdef XFRCAN
860    "cancellation",  XYX_CAN,   0,
861#endif /* XFRCAN */
862#ifndef NOCSETS
863    "character-set", XYX_CSE,   0,
864#endif /* NOCSETS */
865#ifndef NOSPL
866    "crc-calculation", XYX_CRC, 0,
867#endif /* NOSPL */
868    "display",       XYX_DIS,   0,
869    "locking-shift", XYX_LSH,   0,
870    "mode",          XYX_MOD,   0,
871#ifdef CK_XYZ
872    "protocol",      XYX_PRO,   0,
873#endif /* CK_XYZ */
874    "slow-start",    XYX_SLO,   0,
875    "", 0, 0
876};
877int nts = (sizeof(tstab) / sizeof(struct keytab)) - 1;
878
879static struct keytab xfrmtab[] = {
880    "automatic", XMODE_A, 0,
881    "manual",    XMODE_M, 0
882};
883
884#ifndef NOCSETS
885/* SET TRANSFER CHARACTER-SET table */
886
887extern struct keytab tcstab[];
888extern int ntcs;
889#endif /* NOCSETS */
890
891/* SET TRANSFER LOCKING-SHIFT table */
892struct keytab lstab[] = {
893    "forced", 2,   0,
894    "off",    0,   0,
895    "on",     1,   0
896};
897int nls = (sizeof(lstab) / sizeof(struct keytab));
898
899/* SET TELNET tables */
900#ifdef TNCODE
901extern int tn_duplex, tn_nlm, tn_binary, tn_b_nlm, tn_b_meu, tn_b_ume;
902extern char *tn_term;
903
904static struct keytab tnbmtab[] = {      /* TELNET BINARY-MODE table */
905    "accepted", TN_BM_AC, 0,
906    "refused",  TN_BM_RF, 0,
907    "requested", TN_BM_RQ, 0
908};
909
910static struct keytab tnbugtab[] = {     /* TELNET BUG table */
911    "binary-me-means-u-too", 0, 0,
912    "binary-u-means-me-too", 1, 0
913};
914
915#ifdef CK_ENVIRONMENT
916static struct keytab tnenvtab[] = {     /* TELNET ENVIRONMENT table */
917    "acct",     TN_ENV_ACCT,    0,
918    "disp",     TN_ENV_DISP,    0,
919    "job",      TN_ENV_JOB,     0,
920    "printer",  TN_ENV_PRNT,    0,
921    "systemtype",TN_ENV_SYS,    0,
922    "user",     TN_ENV_USR,     0,
923    "uservar",  TN_ENV_UVAR,    CM_INV
924};
925static int ntnenv = sizeof(tnenvtab)/sizeof(struct keytab) ;
926#endif /* CK_ENVIRONMENT */
927
928#define TN_NL_BIN 3
929#define TN_NL_NVT 4
930static struct keytab tn_nlmtab[] = {    /* TELNET NEWLINE-MODE table */
931    "binary-mode", TN_NL_BIN, 0,              /* Binary mode */
932    "nvt",    TN_NL_NVT, 0,                 /* NVT mode */
933    "off",    TNL_CRNUL, CM_INV,                /* CR-NUL (TELNET spec) */
934    "on",     TNL_CRLF,  CM_INV,                /* CR-LF (TELNET spec) */
935    "raw",    TNL_CR,    CM_INV                 /* CR only (out of spec) */
936};
937static int ntn_nlm = (sizeof(tn_nlmtab) / sizeof(struct keytab));
938
939static struct keytab tnlmtab[] = {      /* TELNET NEWLINE-MODE table */
940    "cr",     TNL_CR,    CM_INV,    /* CR only (out of spec) */
941    "cr-lf",  TNL_CRLF,  CM_INV,    /* CR-LF (TELNET spec) */
942    "cr-nul", TNL_CRNUL, CM_INV,    /* CR-NUL (TELNET spec) */
943    "lf",     TNL_LF,    CM_INV,    /* LF instead of CR-LF */
944    "off",    TNL_CRNUL, 0,                 /* CR-NUL (TELNET spec) */
945    "on",     TNL_CRLF,  0,                 /* CR-LF (TELNET spec) */
946    "raw",    TNL_CR,    0                      /* CR only (out of spec) */
947};
948static int ntnlm = (sizeof(tnlmtab) / sizeof(struct keytab));
949
950struct keytab tntab[] = {
951    "binary-mode",     CK_TN_BM,   0,
952    "bug",             CK_TN_BUG,  0,
953    "echo",            CK_TN_EC,   0,
954#ifdef CK_ENVIRONMENT
955    "environment",     CK_TN_ENV,  0,
956#endif /* CK_ENVIRONMENT */
957    "newline-mode",    CK_TN_NL,   0,
958    "terminal-type",   CK_TN_TT,   0
959};
960int ntn = (sizeof(tntab) / sizeof(struct keytab));
961#endif /* TNCODE */
962
963struct keytab ftrtab[] = {              /* Feature table */
964#ifndef NOCSETS                         /* 0 = we have it, 1 = we don't */
965"character-sets",       0, 0,
966#else
967"character-sets",       1, 0,
968#endif /* NOCSETS */
969#ifndef NOCYRIL
970"cyrillic",             0, 0,
971#else
972"cyrillic",             1, 0,
973#endif /* NOCYRIL */
974
975#ifndef NODEBUG
976"debug",                0, 0,
977#else
978"debug",                1, 0,
979#endif /* NODEBUG */
980
981#ifndef NODIAL
982"dial",                 0, 0,
983#else
984"dial",                 1, 0,
985#endif /* NODIAL */
986
987#ifdef DYNAMIC
988"dynamic-memory",       0, 0,
989#else
990"dynamic-memory",       1, 0,
991#endif /* DYNAMIC */
992
993#ifdef XXFWD
994"forward",              0, 0,
995#else
996"forward",              1, 0,
997#endif /* XXFWD */
998
999#ifdef CK_CURSES
1000"fullscreen-display",   0, 0,
1001#else
1002"fullscreen-display",   1, 0,
1003#endif /* CK_CURSES */
1004#ifdef HEBREW
1005"hebrew",               0, 0,
1006#else
1007"hebrew",               1, 0,
1008#endif /* HEBREW */
1009#ifndef NOHELP
1010"help",                 0, 0,
1011#else
1012"help",                 1, 0,
1013#endif /* NOHELP */
1014#ifndef NOSPL
1015"if-command",           0, 0,
1016#else
1017"if-command",           1, 0,
1018#endif /* NOSPL */
1019#ifndef NOJC
1020#ifdef UNIX
1021"job-control",          0, 0,
1022#else
1023"job-control",          1, 0,
1024#endif /* UNIX */
1025#else
1026"job-control",          1, 0,
1027#endif /* NOJC */
1028#ifdef KANJI
1029"kanji",                0, 0,
1030#else
1031"kanji",                1, 0,
1032#endif /* KANJI */
1033#ifndef NOCSETS
1034"latin1",               0, 0,
1035#else
1036"latin1",               1, 0,
1037#endif /* NOCSETS */
1038#ifdef LATIN2
1039"latin2",               0, 0,
1040#else
1041"latin2",               1, 0,
1042#endif /* LATIN2 */
1043#ifdef NETCONN
1044"network",              0, 0,
1045#else
1046"network",              1, 0,
1047#endif /* NETCONN */
1048#ifndef NOPUSH
1049"push",                 0, 0,
1050#else
1051"push",                 1, 0,
1052#endif /* PUSH */
1053#ifdef CK_RTSCTS
1054"rts/cts",              0, 0,
1055#else
1056"rts/cts",              1, 0,
1057#endif /* RTS/CTS */
1058
1059#ifdef CK_REDIR
1060"redirect",             0, 0,
1061#else
1062"redirect",             1, 0,
1063#endif /* CK_REDIR */
1064
1065#ifndef NOSCRIPT
1066"script-command",       0, 0,
1067#else
1068"script-command",       1, 0,
1069#endif /* NOSCRIPT */
1070#ifndef NOSERVER
1071"server-mode",          0, 0,
1072#else
1073"server-mode",          1, 0,
1074#endif /* NOSERVER */
1075#ifndef NOSHOW
1076"show-command",         0, 0,
1077#else
1078"show-command",         1, 0,
1079#endif /* NOSHOW */
1080
1081#ifndef NOXMIT
1082"transmit",             0, 0,
1083#else
1084"transmit",             1, 0,
1085#endif /* NOXMIT */
1086
1087#ifdef CK_XYZ
1088"xyzmodem",             0, 0,
1089#else
1090"xyzmodem",             1, 0,
1091#endif /* NOXMIT */
1092
1093"", 0, 0
1094};
1095int nftr = (sizeof(ftrtab) / sizeof(struct keytab)) - 1;
1096
1097struct keytab desttab[] = {             /* SET DESTINATION */
1098    "disk",    DEST_D, 0,
1099    "printer", DEST_P, 0,
1100    "screen",  DEST_S, 0
1101};
1102int ndests =  (sizeof(desttab) / sizeof(struct keytab));
1103
1104
1105#ifndef NOICP /* Used only with script programming items... */
1106
1107#ifndef NOSERVER                        /* This is just to avoid some */
1108#define CK_PARSDIR                      /* "statement not reached" */
1109#else                                   /* complaints... */
1110#ifndef NODIAL
1111#define CK_PARSDIR
1112#endif /* NODIAL */
1113#endif /* NOSERVER */
1114
1115/*
1116  cx == 0 means dial directory
1117  cx == 1 means network directory
1118  cx == 2 means a directory path list
1119*/
1120static int
1121parsdir(cx) int cx; {
1122    int i, x, y, z, dd;                 /* Workers */
1123    int nxdir;
1124    char *s;
1125    char ** xdir;
1126    char *pp[MAXGETPATH];               /* Temporary name pointers */
1127#ifdef ZFNQFP
1128    char dirpath[1024];                 /* For fully qualified filenames */
1129    struct zfnfp * fnp;
1130#ifdef OS2
1131    char * env;
1132#endif /* OS2 */
1133#endif /* ZFNQFP */
1134
1135    int max = 0;                        /* Maximum number of things to parse */
1136    char c;
1137
1138#ifndef NODIAL
1139    if (cx == 0) {                      /* Dialing */
1140        nxdir = ndialdir;
1141        xdir = dialdir;
1142        max = MAXDDIR;
1143    } else
1144#ifdef NETCONN
1145    if (cx == 1) {                      /* Network */
1146        nxdir = nnetdir;
1147        xdir = netdir;
1148        max = MAXDDIR;
1149    } else
1150#endif /* NETCONN */
1151#endif /* NODIAL */
1152#ifndef NOSERVER
1153    if (cx == 2) {                      /* GET path */
1154        nxdir = ngetpath;
1155        xdir = getpath;
1156        max = MAXGETPATH;
1157    } else                              /* Called with invalid function code */
1158#endif /* NOSERVER */
1159      return(-2);
1160
1161#ifdef CK_PARSDIR
1162    dd = 0;                             /* Temporary name counter */
1163    while (1) {
1164        if (cx != 2) {                  /* Dialing or Network Directory */
1165#ifdef OS2   
1166#ifdef NT
1167            env = getenv("K95PHONES");
1168#else /* NT */
1169            env = getenv("K2PHONES");
1170#endif /* NT */
1171            if (!env)
1172              env = getenv("K95PHONES");
1173            sprintf(dirpath,"%s%s%s;%s%s;%s;%s%s;%s;%s%s",
1174                    /* semicolon-separated path list */
1175                    env?env:"",
1176                    (env && env[strlen(env)-1]==';')?"":";",
1177                    startupdir,
1178                    startupdir, "PHONES/",
1179                    inidir,
1180                    inidir, "PHONES/",
1181                    exedir,
1182                    exedir, "PHONES/"
1183                    );
1184#else
1185#ifdef UNIX
1186            y = 1024;
1187            s = dirpath;
1188            zzstring("\\v(home)",&s,&y);
1189#endif /* UNIX */
1190#endif /* OS2 */
1191            y = cmifip(
1192                  "Names of one or more directory files, separated by spaces",
1193                       "",&s,&x,0,
1194#ifdef OS2ORUNIX
1195                       dirpath,
1196#else
1197                       NULL,
1198#endif /* OS2ORUNIX */
1199                       xxstring
1200                       );
1201        } else {
1202            x = 0;
1203            y = cmdir("Directory name","",&s,xxstring);
1204        }
1205        if (y < 0) {
1206            if (y == -3) {              /* EOL or user typed <CR> */
1207                for (i = 0; i < max; i++) { /* Clear these */
1208                    if (i < nxdir && xdir[i]) {
1209                        free(xdir[i]);
1210                    }
1211                    xdir[i] = (i < dd) ? pp[i] : NULL;
1212                }
1213#ifndef NODIAL
1214                if (cx == 0)
1215                  ndialdir = dd;
1216#ifdef NETCONN
1217                if (cx == 1)
1218                  nnetdir = dd;
1219#endif /* NETCONN */
1220#endif /* NODIAL */
1221#ifndef NOSERVER
1222                if (cx == 2)
1223                  ngetpath = dd;
1224#endif /* NOSERVER */
1225                return(success = 1);
1226
1227            } else {                    /* Parse error */
1228                for (i = 0; i < dd; i++) {  /* Free temp storage */
1229                    if (pp[i]) free(pp[i]); /* but don't change */
1230                    pp[i] = NULL;           /* anything else */
1231                }
1232                return(y);
1233            }
1234        }
1235        if (x) {
1236            printf("?Wildcards not allowed\n");
1237            return(-9);
1238        }
1239#ifdef CK_TMPDIR
1240        if (cx == 2 && !isdir(s)) {
1241            printf("?Not a directory - %s\n", s);
1242            return(-9);
1243        }
1244#endif /* CK_TMPDIR */
1245
1246#ifdef ZFNQFP
1247        /* Get fully qualified pathname */
1248        if (fnp = zfnqfp(s,TMPBUFSIZ - 1,tmpbuf)) {
1249            if (fnp->fpath)
1250              if ((int) strlen(fnp->fpath) > 0)
1251                s = fnp->fpath;
1252        }
1253#endif /* ZFNQFP */
1254        c = NUL;
1255        x = strlen(s);
1256        if (x > 0)                      /* Get last char */
1257          c = s[x-1];
1258        debug(F000,"parsdir s",s,c);
1259        if ((pp[dd] = malloc(strlen(s)+2)) == NULL) {
1260            printf("?Internal error - malloc\n");
1261            for (i = 0; i < dd; i++) {  /* Free temp storage */
1262                if (pp[i]) free(pp[i]);
1263                pp[i] = NULL;
1264            }
1265            return(-9);
1266        } else {                        /* Have storage for name */
1267            strcpy(pp[dd],s);           /* Copy string into new storage */
1268            debug(F111,"parsdir pp[dd] 1",pp[dd],dd);
1269            if (cx == 2) {              /* If we are parsing directories */
1270                char dirsep[2];
1271                extern int myindex;     /* Append directory separator if */
1272                extern struct sysdata sysidlist[]; /* it is missing...   */
1273                debug(F101,"parsdir myindex","",myindex);
1274                if (myindex > -1)
1275                  if (sysidlist[myindex].sid_unixlike)
1276                    if (c != sysidlist[myindex].sid_dirsep) {
1277                        dirsep[0] = sysidlist[myindex].sid_dirsep;
1278                        dirsep[1] = NUL;
1279                        strcat(pp[dd], (char *) dirsep);
1280                    }
1281            }
1282            debug(F111,"parsdir pp[dd] 2",pp[dd],dd);
1283            if (++dd > max) {
1284                printf("?Too many directories - %d max\n", max);
1285                for (i = 0; i < dd; i++) {  /* Free temp storage */
1286                    if (pp[i]) free(pp[i]);
1287                    pp[i] = NULL;
1288                }
1289            }
1290        }
1291    }
1292#endif /* CK_PARSDIR */
1293}
1294#endif /* NOICP */
1295
1296#ifndef NOSERVER
1297static int
1298cklogin() {
1299    int x;
1300    char * s;
1301    char username[LOGINLEN+1];
1302    char password[LOGINLEN+1];
1303    char account[LOGINLEN+1];
1304    extern char * x_user, * x_passwd, * x_acct;
1305    extern int x_login, x_logged;
1306
1307    username[0] = NUL;
1308    password[0] = NUL;
1309    account[0]  = NUL;
1310
1311    x = cmfld("username", "", &s, xxstring);
1312    if (x != -3) {
1313        if (x < 0)
1314          return(x);
1315        if ((int)strlen(s) > LOGINLEN) {
1316            printf("\"%s\" - too long, %d max\n", s, LOGINLEN);
1317            return(-9);
1318        }
1319        strcpy(username,s);
1320        x = cmfld("password", "", &s, xxstring);
1321        if (x != -3) {
1322            if (x < 0)
1323              return(x);
1324            if ((int)strlen(s) > LOGINLEN) {
1325                printf("\"%s\" - too long, %d max\n", s, LOGINLEN);
1326                return(-9);
1327            }
1328            strcpy(password,s);
1329            x = cmfld("account", "", &s, xxstring);
1330            if (x != -3) {
1331                if (x < 0)
1332                  return(x);
1333                if ((int)strlen(s) > LOGINLEN) {
1334                    printf("\"%s\" - too long, %d max\n", s, LOGINLEN);
1335                    return(-9);
1336                }
1337                strcpy(account,s);
1338                if ((x = cmcfm()) < 0)
1339                  return(x);
1340            }
1341        }
1342    }
1343    makestr(&x_user,username);
1344    makestr(&x_passwd,password);
1345    makestr(&x_acct,account);
1346    x_login = (x_user) ? 1 : 0;
1347    x_logged = 0;
1348    return(1);
1349}
1350#endif /* NOSERVER */
1351
1352#ifndef NOLOCAL
1353VOID
1354setflow() {
1355#ifndef NODIAL
1356    MDMINF * p = NULL;
1357    long bits = 0;
1358#endif /* NODIAL */
1359
1360    if (!autoflow)                      /* Only if FLOW is AUTO */
1361      return;
1362#ifdef VMS
1363    flow = FLO_XONX;                    /* Special for VMS */
1364    return;
1365#endif /* VMS */
1366
1367    if (network)                        /* Network connection */
1368      flow = FLO_NONE;                  /* None for all non-VMS */
1369
1370    if (mdmtyp < 1) {                   /* Direct connection */
1371#ifdef CK_RTSCTS                        /* If we can do RTS/CTS flow control */
1372        flow = FLO_RTSC;                /* then do it */
1373#else                                   /* Otherwise */
1374        flow = FLO_XONX;                /* Use Xon/Xoff. */
1375#endif /* CK_RTSCTS */
1376        return;
1377    }
1378#ifndef NODIAL
1379    bits = dialcapas;                   /* Capability bits */
1380    if (!bits) {                        /* No bits? */
1381        p = modemp[mdmtyp - 1];         /* Look in modem info structure */
1382        if (p)
1383          bits = p->capas;
1384    }
1385    if (dialfc == FLO_AUTO) {           /* If DIAL flow is AUTO */
1386#ifdef CK_RTSCTS                        /* If we can do RTS/CTS flow control */
1387        if (bits & CKD_HW)              /* and modem can do it too */
1388          flow = FLO_RTSC;              /* then switch to RTS/CTS */
1389        else                            /* otherwise */
1390          flow = FLO_XONX;              /* use Xon/Xoff. */
1391#else
1392        flow = FLO_XONX;                /* No RTS/CTS so use Xon/Xoff. */
1393#endif /* CK_RTSCTS */
1394    }
1395#endif /* NODIAL */
1396    return;
1397}
1398
1399static int
1400setdcd() {
1401    int x, y, z;
1402    if ((y = cmkey(crrtab,ncrr,"","auto",xxstring)) < 0) return(y);
1403    if (y == CAR_ON) {
1404        x = cmnum("Carrier wait timeout, seconds","0",10,&z,xxstring);
1405        if (x < 0) return(x);
1406    }
1407    if ((x = cmcfm()) < 0) return(x);
1408    carrier = ttscarr(y);
1409    cdtimo = z;
1410    return(1);
1411}
1412#endif /* NOLOCAL */
1413
1414extern struct keytab yesno[];
1415extern int nyesno;
1416
1417int
1418getyesno(msg) char * msg; {             /* Ask question, get yes/no answer */
1419
1420    int x, y, z;
1421
1422#ifdef VMS
1423/*
1424  In VMS, whenever a TAKE file or macro is active, we restore the
1425  original console modes so Ctrl-C/Ctrl-Y can work.  But here we
1426  go interactive again, so we have to temporarily put them back.
1427*/
1428    if (cmdlvl > 0)
1429      concb((char)escape);
1430#endif /* VMS */
1431     
1432    cmsavp(psave,PROMPTL);              /* Save old prompt */
1433    cmsetp(msg);                        /* Make new prompt */
1434    z = 0;                              /* Initialize answer to No. */
1435    cmini(ckxech);                      /* Initialize parser. */
1436    do {
1437        prompt(NULL);                   /* Issue prompt. */
1438        y = cmkey(yesno,nyesno,"","",NULL); /* Get Yes or No */
1439        if (y < 0) {
1440            if (y == -4) {              /* EOF */
1441                z = y;
1442                break;
1443            } else if (y == -3)         /* No answer? */
1444              printf(" Please respond Yes or No\n");
1445            cmini(ckxech);
1446        } else {
1447            z = y;                      /* Save answer */
1448            y = cmcfm();                /* Get confirmation */
1449        }
1450    } while (y < 0);                    /* Continue till done */
1451    cmsetp(psave);                      /* Restore real prompt */
1452#ifdef VMS
1453    if (cmdlvl > 0)                     /* In VMS and not at top level, */
1454      conres();                         /*  restore console again. */
1455#endif /* VMS */
1456    return(z);
1457}
1458
1459int                                     /* CHECK command */
1460dochk() {
1461    int x, y;
1462    if ((y = cmkey(ftrtab,nftr,"","",xxstring)) < 0)
1463      return(y);
1464    strcpy(line,atmbuf);
1465    if ((y = cmcfm()) < 0)
1466      return(y);
1467#ifndef NOPUSH
1468    if (!xxstrcmp(atmbuf,"push",(int)strlen(atmbuf))) {
1469        if (msgflg)                     /* If at top level... */
1470          printf(" push%s available\n", nopush ? " not" : "");
1471        else if (nopush && !backgrd)
1472          printf(" CHECK: push not available\n");
1473        return(success = 1 - nopush);
1474    }
1475#endif /* NOPUSH */
1476    y = lookup(ftrtab,line,nftr,&x);    /* Look it up */
1477    if (msgflg)                         /* If at top level... */
1478      printf(" %s%s available\n", ftrtab[x].kwd, y ? " not" : "");
1479    else if (y && !backgrd)
1480      printf(" CHECK: %s not available\n", ftrtab[x].kwd);
1481    return(success = 1 - y);
1482}
1483
1484#ifndef NODIAL
1485/*
1486  Parse a DIAL-related string, stripping enclosing braces, if any.
1487*/
1488static int
1489dialstr(p,msg) char **p; char *msg; {
1490    int x;
1491    char *s;
1492
1493    if ((x = cmtxt(msg, "", &s, xxstring)) < 0)
1494      return(x);
1495    s = brstrip(s);                     /* Strip braces around. */
1496    makestr(p,s);
1497    return(success = 1);
1498}
1499
1500VOID
1501initmdm(x) int x; {
1502    MDMINF * p, * u;
1503    int m;
1504
1505    mdmtyp = x;                         /* Set global modem type */
1506    debug(F101,"initmdm mdmtyp","",mdmtyp);
1507    debug(F101,"initmdm usermdm","",usermdm);
1508    if (x < 1) return;
1509
1510    m = usermdm ? usermdm : mdmtyp;
1511
1512    p = modemp[m - 1];                  /* Point to modem info struct, and */
1513    debug(F101,"initmdm p","",p);
1514    if (p) {
1515        dialec = p->capas & CKD_EC;     /* set DIAL ERROR-CORRECTION, */
1516        dialdc = p->capas & CKD_DC;     /* DIAL DATA-COMPRESSION, and */
1517        mdmspd = p->capas & CKD_SB ? 0 : 1; /* DIAL SPEED-MATCHING from it. */
1518        dialfc = FLO_AUTO;                  /* Modem's local flow control.. */
1519    } else if (mdmtyp > 0) {
1520        printf("WARNING: modem info for \"%s\" not filled in yet\n",
1521               gmdmtyp()
1522               );
1523    }
1524
1525/* Reset or set the SET DIAL STRING items ... */
1526
1527    if (usermdm && p) { /* USER-DEFINED: copy info from specified template */
1528
1529        makestr(&dialini,p->wake_str);
1530        makestr(&dialmstr,p->dmode_str);
1531        makestr(&dialmprmt,p->dmode_prompt);
1532        makestr(&dialcmd,p->dial_str);
1533        makestr(&dialdcon,p->dc_on_str);
1534        makestr(&dialdcoff,p->dc_off_str);
1535        makestr(&dialecon,p->ec_on_str);
1536        makestr(&dialecoff,p->ec_off_str);
1537        makestr(&dialhcmd,p->hup_str);
1538        makestr(&dialhwfc,p->hwfc_str);
1539        makestr(&dialswfc,p->swfc_str);
1540        makestr(&dialnofc,p->nofc_str);
1541        makestr(&dialtone,p->tone);
1542        makestr(&dialpulse,p->pulse);
1543        makestr(&dialname,"This space available (use SET MODEM NAME)");
1544        dialmax   = p->max_speed;
1545        dialcapas = p->capas;
1546        dialesc   = p->esc_char;
1547
1548    } else {                    /* Not user-defined, so wipe out overrides */
1549       
1550        if (dialini)   free(dialini);   dialini =   NULL; /* Init-string */
1551        if (dialmstr)  free(dialmstr);  dialmstr =  NULL; /* Dial-mode-str */
1552        if (dialmprmt) free(dialmprmt); dialmprmt = NULL; /* Dial-mode-pro */
1553        if (dialcmd)   free(dialcmd);   dialcmd =   NULL; /* Dial-command  */
1554        if (dialdcon)  free(dialdcon);  dialdcon =  NULL; /* DC ON command */
1555        if (dialdcoff) free(dialdcoff); dialdcoff = NULL; /* DC OFF command */
1556        if (dialecon)  free(dialecon);  dialecon =  NULL; /* EC ON command */
1557        if (dialecoff) free(dialecoff); dialecoff = NULL; /* EC OFF command */
1558        if (dialhcmd)  free(dialhcmd);  dialhcmd =  NULL; /* Hangup command */
1559        if (dialhwfc)  free(dialhwfc);  dialhwfc =  NULL; /* Flow control... */
1560        if (dialswfc)  free(dialswfc);  dialswfc =  NULL;
1561        if (dialnofc)  free(dialnofc);  dialnofc =  NULL;
1562        if (dialtone)  free(dialtone);  dialtone =  NULL; /* Dialing method */
1563        if (dialpulse) free(dialpulse); dialpulse = NULL;
1564        if (dialname)  free(dialname);  dialname =  NULL; /* Modem name */
1565    }
1566    if (autoflow)                       /* Maybe change flow control */
1567      setflow();
1568
1569#ifndef MINIDIAL
1570#ifdef OLDTBCODE
1571    tbmodel = 0;           /* If it's a Telebit, we don't know the model yet */
1572#endif /* OLDTBCODE */
1573#endif /* MINIDIAL */
1574}
1575
1576int
1577setmodem() {                            /* SET MODEM */
1578
1579    int x, y, z;
1580    long zz;
1581    char *s;
1582
1583    if ((x = cmkeyx(setmdm,nsetmdm,"modem parameter","", xxstring)) < 0) {
1584        debug(F111,"setmodem cmkeyx","atmbuf",x);
1585        if (x == -9) {
1586            extern int cmflgs;
1587            debug(F101,"setmodem cmflgs","",cmflgs);
1588            if (!atmbuf[0])
1589              return(-3);
1590            y = lookup(mdmtab,atmbuf,nmdm,&x); /* Maybe old SET MODEM <type> */
1591            if (y == -2) {                     /* Look up in modem table.... */
1592                printf("?Ambiguous modem type - %s\n",atmbuf);
1593                return(-9);
1594            } else if (y < 0) {
1595                printf("?\"%s\" does not match a keyword or modem type\n",
1596                       atmbuf);
1597                return(-9);
1598            }
1599            if (!cmflgs)
1600              if ((x = cmcfm()) < 0)    /* Confirm */
1601                return(x);
1602            usermdm = 0;
1603            initmdm(y);                 /* Set it. */
1604            return(success = 1);        /* Done */
1605        } else return(x);
1606    }
1607    switch (x) {
1608#ifdef MDMHUP
1609      case XYDMHU:                      /* DIAL MODEM-HANGUP */
1610        if ((y = cmkey(mdmhang,3,"how to hang up modem",
1611                       "modem-command", xxstring)) < 0)
1612          return(y);
1613        if ((x = cmcfm()) < 0)
1614          return(x);
1615        dialmhu = y;
1616        return(success = 1);
1617#endif /* MDMHUP */
1618
1619      case XYDCAP:
1620        zz = 0L;
1621        y = 0;
1622        while (y != -3) {
1623            if ((y = cmkey(mdmcap,nmdmcap,
1624                           "capability of modem", "", xxstring)) < 0) {
1625                if (y == -3)
1626                  break;
1627                else
1628                  return(y);
1629            }
1630            zz |= y;
1631        }
1632        dialcapas = zz;
1633        if (autoflow)                   /* Maybe change flow control */
1634          setflow();
1635        return(success = 1);
1636
1637      case XYDMAX:
1638        if ((x = cmkey(spdtab,nspd,line,"",xxstring)) < 0) {
1639            if (x == -3) printf("?value required\n");
1640            return(x);
1641        }
1642        if ((y = cmcfm()) < 0) return(y);
1643        dialmax = (long) x * 10L;
1644        if (dialmax == 70) dialmax = 75;
1645        return(success = 1);
1646
1647      case XYDSTR:                      /* These moved from SET DIAL */
1648      case XYDDC:
1649      case XYDEC:
1650      case XYDESC:
1651      case XYDFC:
1652      case XYDKSP:
1653      case XYDSPD:
1654      case XYDDIA:
1655        return(setdial(x));
1656
1657      case XYDTYP:
1658        if ((y = cmkey(mdmtab,nmdm,"modem type","none", xxstring)) < 0)
1659          return(y);
1660        if (y == dialudt) {             /* User-defined modem type */
1661            if ((x = cmkey(mdmtab,nmdm,"based on existing modem type",
1662                           "unknown", xxstring)) < 0)
1663              return(x);
1664        }
1665        if ((z = cmcfm()) < 0)
1666          return(z);
1667        usermdm = 0;
1668        usermdm = (y == dialudt) ? x : 0;
1669        initmdm(y);
1670        return(success = 1);
1671
1672      case XYDNAM:
1673        return(dialstr(&dialname,"Descriptive name for modem"));
1674
1675      case XYDMCD:                      /* SET MODEM CARRIER */
1676        return(success = setdcd());
1677
1678      default:
1679        printf("Unexpected SET MODEM parameter\n");
1680        return(-9);
1681    }
1682}
1683
1684static int                              /* Set DIAL command options */
1685setdial(y) int y; {
1686    int x, z;
1687    char *s;
1688
1689    if (y < 0)
1690      if ((y = cmkey(dialtab,ndial,"","",xxstring)) < 0)
1691        return(y);
1692    switch (y) {
1693      case XYDHUP:                      /* DIAL HANGUP */
1694        return(seton(&dialhng));
1695      case XYDINI:                      /* DIAL INIT-STRING */
1696        return(dialstr(&dialini,"Modem initialization string"));
1697      case XYDNPR:                      /* DIAL PREFIX */
1698        return(dialstr(&dialnpr,"Telephone number prefix"));
1699      case XYDDIA:                      /* DIAL DIAL-COMMAND */
1700        x = cmtxt("Dialing command for modem,\n\
1701 include \"%s\" to stand for phone number,\n\
1702 for example, \"set dial dial-command ATDT%s\\13\"",
1703                  "",
1704                  &s,
1705                  xxstring);
1706        if (x < 0 && x != -3)           /* Handle parse errors */
1707          return(x);
1708        y = x = strlen(s);              /* Get length of text */
1709        if (x > 0 && *s == '{') {       /* Strip enclosing braces, */
1710            if (s[x-1] == '}') {        /* if any. */
1711                s[x-1] = NUL;
1712                s++;
1713                y -= 2;
1714            }
1715        }
1716        if (y > 0) {                    /* If there is any text (left), */
1717            for (x = 0; x < y; x++) {   /* make sure they included "%s" */
1718                if (s[x] != '%') continue;
1719                if (s[x+1] == 's') break;
1720            }
1721            if (x == y) {
1722                printf(
1723"?Dial-command must contain \"%cs\" for phone number.\n",'%');
1724                return(-9);
1725            }
1726        }
1727        if (dialcmd) {                  /* Free any previous string. */
1728            free(dialcmd);
1729            dialcmd = (char *) 0;
1730        }       
1731        if (y > 0) {
1732            dialcmd = malloc(y + 1);    /* Allocate space for it */
1733            strcpy(dialcmd,s);          /* and make a safe copy. */
1734        }
1735        return(success = 1);
1736      case XYDKSP:                      /* DIAL KERMIT-SPOOF */
1737        return(seton(&dialksp));
1738      case XYDTMO:                      /* DIAL TIMEOUT */
1739        y = cmnum("Seconds to wait for call completion","0",10,&x,xxstring);
1740        if (y < 0) return(y);
1741        y = cmnum("Kermit/modem timeout differential","10",10,&z,xxstring);
1742        if (y < 0) return(y);   
1743        if ((y = cmcfm()) < 0)
1744          return(y);
1745        dialtmo = x;
1746        mdmwaitd = z;
1747      case XYDESC:                      /* DIAL ESCAPE-CHARACTER */
1748        y = cmnum("ASCII value of character to escape back to modem",
1749                  "43",10,&x,xxstring);
1750        return(setnum(&dialesc,x,y,128));
1751      case XYDDPY:                      /* DIAL DISPLAY */
1752        return(seton(&dialdpy));
1753      case XYDSPD:                      /* DIAL SPEED-MATCHING */
1754                                        /* used to be speed-changing */
1755        if ((y = seton(&mdmspd)) < 0) return(y);
1756#ifdef COMMENT
1757        mdmspd = 1 - mdmspd;            /* so here we reverse the meaning */
1758#endif /* COMMENT */
1759        return(success = 1);
1760      case XYDMNP:                      /* DIAL MNP-ENABLE */
1761      case XYDEC:                       /* DIAL ERROR-CORRECTION */
1762        x = seton(&dialec);
1763        if (x > 0)
1764          if (!dialec) dialdc = 0;      /* OFF also turns off compression */
1765        return(x);
1766
1767      case XYDDC:                       /* DIAL COMPRESSION */
1768        x = seton(&dialdc);
1769        if (x > 0)
1770          if (dialdc) dialec = 1;       /* ON also turns on error correction */
1771        return(x);
1772
1773#ifdef MDMHUP
1774      case XYDMHU:                      /* DIAL MODEM-HANGUP */
1775        return(seton(&dialmhu));
1776#endif /* MDMHUP */
1777
1778      case XYDDIR:                      /* DIAL DIRECTORY (zero or more) */
1779        return(parsdir(0));             /* 0 means DIAL */
1780
1781      case XYDSTR:                      /* DIAL STRING */
1782        if ((y = cmkey(dial_str,ndstr,"","",xxstring)) < 0) return(y);
1783        switch (y) {
1784          case XYDS_AN:                 /* Autoanswer ON/OFF */
1785          case XYDS_DC:                 /* Data compression ON/OFF */
1786          case XYDS_EC:                 /* Error correction ON/OFF */
1787            if ((x = cmkey(onoff,2,"","on",xxstring)) < 0) return(x);
1788            sprintf(tmpbuf,"Modem's command to %sable %s",
1789                    x ? "en" : "dis",
1790                    (y == XYDS_DC) ? "compression" :
1791                    ((y == XYDS_EC) ? "error-correction" :
1792                    "autoanswer")
1793                    );
1794            if (x) {
1795                if (y == XYDS_DC)
1796                  return(dialstr(&dialdcon,tmpbuf));
1797                else if (y == XYDS_EC)
1798                  return(dialstr(&dialecon,tmpbuf));
1799                else
1800                  return(dialstr(&dialaaon,tmpbuf));
1801            } else {
1802                if (y == XYDS_DC)
1803                  return(dialstr(&dialdcoff,tmpbuf));
1804                else if (y == XYDS_EC)
1805                  return(dialstr(&dialecoff,tmpbuf));
1806                else
1807                  return(dialstr(&dialaaoff,tmpbuf));
1808            }
1809          case XYDS_HU:                 /*    hangup command */
1810            return(dialstr(&dialhcmd,"Modem's hangup command"));
1811          case XYDS_HW:                 /*    hwfc */
1812            return(dialstr(&dialhwfc,
1813                           "Modem's command to enable hardware flow control"));
1814          case XYDS_IN:                 /*    init */
1815            return(dialstr(&dialini,"Modem's initialization string"));
1816          case XYDS_NF:                 /*    no flow control */
1817            return(dialstr(&dialnofc,
1818                           "Modem's command to disable local flow control"));
1819          case XYDS_PX:                 /*    prefix */
1820            return(dialstr(&dialnpr,"Telephone number prefix for dialing"));
1821          case XYDS_SW:                 /*    swfc */
1822            return(dialstr(&dialswfc,
1823                   "Modem's command to enable local software flow control"));
1824          case XYDS_DT:                 /*    tone dialing */
1825            return(dialstr(&dialtone,
1826                   "Command to configure modem for tone dialing"));
1827          case XYDS_DP:                 /*    pulse dialing */
1828            return(dialstr(&dialpulse,
1829                   "Command to configure modem for pulse dialing"));
1830    case XYDS_MS:           /*    dial mode string */
1831         return(dialstr(&dialmstr,
1832                         "Command to enter dial mode"));
1833    case XYDS_MP:           /*    dial mode prompt */
1834         return(dialstr(&dialmprmt,
1835                         "Modem response upon entering dial mode"));
1836          default:
1837            printf("?Unexpected SET DIAL STRING parameter\n");
1838        }
1839
1840      case XYDFC:                       /* DIAL FLOW-CONTROL */
1841        if ((y = cmkey(dial_fc,4,"","auto",xxstring)) < 0) return(y);
1842        if ((x = cmcfm()) < 0) return(x);
1843        dialfc = y;
1844        return(success = 1);
1845
1846      case XYDMTH:                      /* DIAL METHOD */
1847        if ((y = cmkey(dial_m,3,"","default",xxstring)) < 0)
1848          return(y);
1849        if ((x = cmcfm()) < 0)          /* DEFAULT means don't force */
1850          return(x);                    /* any particular method, use */
1851        dialmth = y;                    /* modem's default method. */
1852        return(success = 1);
1853
1854      case XYDRTM:
1855        y = cmnum("Number of times to try dialing a number",
1856                  "1",10,&x,xxstring);
1857        return(setnum(&dialrtr,x,y,16383));
1858       
1859      case XYDINT:
1860        y = cmnum("Seconds to wait between redial attempts",
1861                  "30",10,&x,xxstring);
1862        return(setnum(&dialint,x,y,128));
1863
1864      case XYDLAC:                      /* DIAL AREA-CODE */
1865        if ((x = dialstr(&diallac,"Area code you are calling from")) < 0)
1866          return(x);
1867        if (diallac) {
1868            if (!rdigits(diallac)) {
1869                printf("?Sorry, area code must be numeric\n");
1870                if (*diallac == '(')
1871                  printf("(please omit the parentheses)\n");
1872                if (*diallac == '/')
1873                  printf("(no slashes, please)\n");
1874                if (diallac) free(diallac);
1875                diallac = NULL;
1876                return(-9);
1877            }
1878        }
1879        return(x);
1880
1881      case XYDCNF:                      /* CONFIRMATION */
1882        return(success = seton(&dialcnf));
1883
1884      case XYDCVT:                      /* CONVERT-DIRECTORY */
1885        if ((y = cmkey(dcnvtab,3,"","ask",xxstring)) < 0)
1886          return(y);
1887        if ((x = cmcfm()) < 0)
1888          return(x);
1889        dialcvt = y;
1890        return(success = 1);
1891
1892      case XYDLCC:                      /* DIAL COUNTRY-CODE */
1893        x = dialstr(&diallcc,"Country code you are calling from");
1894        if (x < 1) return(x);
1895        if (diallcc) {
1896            if (!rdigits(diallcc)) {
1897                printf("?Sorry, country code must be numeric\n");
1898                if (*diallcc == '+')
1899                  printf("(please omit the plus sign)\n");
1900                if (diallcc) free(diallcc);
1901                diallcc = NULL;
1902                return(-9);
1903            }
1904            if (!strcmp(diallcc,"1")) { /* Set defaults for USA and Canada */
1905                if (!dialldp)           /* Long-distance prefix */
1906                  makestr(&dialldp,"1");
1907                if (!dialixp)           /* International dialing prefix */
1908                  makestr(&dialixp,"011");
1909                if (ntollfree == 0) {   /* Toll-free area codes */
1910                    if (dialtfc[0] = malloc(4)) {
1911                        strcpy(dialtfc[0],"800");
1912                        ntollfree++;
1913                    }
1914                    if (dialtfc[1] = malloc(4)) {
1915                        strcpy(dialtfc[1],"888");
1916                        ntollfree++;
1917                    }
1918                }
1919                if (!dialtfp)           /* Toll-free dialing prefix */
1920                  makestr(&dialtfp,"1");
1921            } else if (!strcmp(diallcc,"358") &&
1922                       ((int) strcmp(zzndate(),"19961011") > 0)
1923                       ) {              /* Finland */
1924                if (!dialldp)           /* Long-distance prefix */
1925                  makestr(&dialldp,"9");
1926                if (!dialixp)           /* International dialing prefix */
1927                  makestr(&dialixp,"990");
1928            } else {                    /* Everywhere else ... */
1929                if (!dialldp) {
1930                    if (dialldp = malloc(4))
1931                      strcpy(dialldp,"0");
1932                }
1933                if (!dialixp) {
1934                    if (dialixp = malloc(4))
1935                      strcpy(dialixp,"00");
1936                }
1937            }
1938        }
1939        return(success = 1);
1940
1941      case XYDIXP:                      /* DIAL INTL-PREFIX */
1942        return(dialstr(&dialixp,"International dialing prefix"));
1943
1944      case XYDIXS:                      /* DIAL INTL-SUFFIX */
1945        return(dialstr(&dialixs,"International dialing suffix"));
1946
1947      case XYDLDP:                      /* DIAL INTL-PREFIX */
1948        return(dialstr(&dialldp,"Long-distance dialing prefix"));
1949
1950      case XYDLDS:                      /* DIAL INTL-SUFFIX */
1951        return(dialstr(&diallds,"Long-distance dialing suffix"));
1952
1953      case XYDPXX:                      /* DIAL PBX-EXCHANGE */
1954        return(dialstr(&dialpxx,"Exchange of PBX you are calling from"));
1955
1956      case XYDPXI:                      /* DIAL PBX-INTERNAL-PREFIX */
1957        return(dialstr(&dialpxi,
1958                       "Internal-call prefix of PBX you are calling from"));
1959
1960      case XYDPXO:                      /* DIAL PBX-OUTSIDE-PREFIX */
1961        return(dialstr(&dialpxo,
1962                       "Outside-line prefix of PBX you are calling from"));
1963
1964      case XYDSFX:                      /* DIAL INTL-SUFFIX */
1965        return(dialstr(&dialsfx," Telephone number suffix for dialing"));
1966
1967      case XYDSRT:                      /* DIAL SORT */
1968        return(success = seton(&dialsrt));
1969
1970      case XYDTFC: {                    /* DIAL TOLL-FREE-AREA-CODE  */
1971          int n, i;                     /* (zero or more of them...) */
1972          char * p[MAXTOLLFREE];        /* Temporary pointers */
1973          for (n = 0; n < MAXTOLLFREE; n++) {
1974              if ((x = cmfld(
1975                    "Toll-free area code in the country you are calling from",
1976                       "",&s,xxstring)) < 0)
1977                break;
1978              if (s) {
1979                  int k;
1980                  k = (int) strlen(s);
1981                  if (k > 0) {
1982                      if (p[n] = malloc(k + 1))
1983                        strcpy(p[n], s);
1984                  } else break;
1985              } else break;
1986          }
1987          if (x == -3) {                /* Command was successful */
1988              for (i = 0; i < ntollfree; i++) /* Remove old list, if any */
1989                if (dialtfc[i]) {
1990                    free(dialtfc[i]);
1991                    dialtfc[i] = NULL;
1992                }
1993              ntollfree = n;            /* New count */
1994              for (i = 0; i < ntollfree; i++) /* New list */
1995                dialtfc[i] = p[i];
1996              return(success = 1);
1997          } else {                      /* Parse error, undo everything */
1998              for (i = 0; i < n; i++)
1999                if (p[i]) free(p[i]);
2000              return(x);
2001          }
2002      }
2003
2004      case XYDTFP:                      /* TOLL-FREE-PREFIX */
2005        return(dialstr(&dialtfp,
2006                       " Long-distance prefix for toll-free dialing"));
2007
2008      case XYDCON:                      /* CONNECT */
2009        z = -1;
2010        if ((y = cmkey(crrtab,ncrr,"","auto",xxstring)) < 0) return(y);
2011        if (y != CAR_OFF)               /* AUTO or ON? */
2012          if ((z = cmkey(qvtab,nqvt,"","verbose",xxstring)) < 0) return(z);
2013        if ((x = cmcfm()) < 0) return(x);
2014        if (z > -1)
2015          dialcq = z;
2016        dialcon = y;
2017        return(success = 1);
2018
2019      case XYDRSTR:                     /* RESTRICT */
2020        if ((y = cmkey(drstrtab,4,"","none",xxstring)) < 0) return(y);
2021        if ((x = cmcfm()) < 0) return(x);
2022        dialrstr = y;
2023        return(success = 1);
2024
2025      default:
2026        printf("?Unexpected SET DIAL parameter\n");
2027        return(-9);
2028    }
2029}
2030
2031#ifdef CK_TAPI
2032static int                              /* Set DIAL command options */
2033settapi() {
2034    int x,y;
2035    char *s;
2036
2037    if (!TAPIAvail) {
2038        printf("\nTAPI is unavailable on this system.\n");
2039        return(-9);
2040    }
2041    if ((y = cmkey(tapitab,ntapitab,"MS TAPI option","line",xxstring)) < 0)
2042      return(y);
2043    switch (y) {
2044      case XYTAPI_LIN:                  /* TAPI LINE */
2045        return setlin(XYTAPI_LIN,1);
2046        break;
2047      case XYTAPI_LOC: {                /* TAPI LOCATION */
2048          extern char tapiloc[] ;
2049          extern int tapilocid ;
2050          int i=0, j = 9999, k = -1 ;
2051
2052          cktapiBuildLocationTable(&tapiloctab, &ntapiloc);
2053          if (!tapiloctab || !ntapiloc) {
2054              printf("\nNo TAPI Locations are configured for this system\n");
2055              return(-9) ;
2056          }
2057          /* Find out what the lowest numbered TAPI location is */
2058          /* and use it as the default. */
2059          for (i = 0; i < ntapiloc; i++) {
2060              if (tapiloctab[i].kwval < j) {
2061                  j = tapiloctab[i].kwval;
2062                  k = i;
2063              }
2064          }             
2065          if (k >= 0)
2066            s = tapiloctab[k].kwd;
2067          else
2068            s = "";
2069
2070          if ((y = cmkey(tapiloctab,ntapiloc,
2071                         "TAPI location",s,xxstring)) < 0)
2072            return(y);
2073          y = lookup(tapiloctab,s,ntapiloc,&x);
2074          if (y > -1) {
2075              strcpy(tapiloc,tapilinetab[x].kwd);
2076              tapilocid = y;
2077          }
2078          if ((x = cmcfm()) < 0)
2079            return(x);
2080        }
2081        break;
2082      case XYTAPI_CFG:                  /* TAPI CONFIGURE-LINE */
2083        if ((x = cmcfm()) < 0) return(x);
2084        break;
2085      case XYTAPI_DIAL:                 /* TAPI DIALING-PROPERTIES */
2086        if ((x = cmcfm()) < 0) return(x);
2087        break;
2088    }
2089    return(1);
2090}
2091#endif /* CK_TAPI */
2092
2093#ifndef NOSHOW
2094int                                     /* SHOW MODEM */
2095shomodem() {
2096    extern MDMINF * modemp[];
2097    MDMINF * p;
2098    int x, n;
2099    char c;
2100    long zz;
2101
2102    shmdmlin();
2103    printf("\n");
2104
2105    p = (mdmtyp > 0) ? modemp[mdmtyp - 1] : NULL;
2106    if (p) {
2107        printf(" %s\n\n", dialname ? dialname : p->name);
2108        printf(" Modem carrier-watch:    ");
2109        if (carrier == CAR_OFF) printf("off\n");
2110        else if (carrier == CAR_ON) printf("on\n");
2111        else if (carrier == CAR_AUT) printf("auto\n");
2112        else printf("unknown\n");
2113
2114        printf(" Modem capabilities:    ");
2115        zz = dialcapas ? dialcapas : p->capas;
2116        if (!zz) {
2117            printf(" (none)");
2118        } else {
2119            if (zz & CKD_AT) printf(" AT");
2120            if (zz & CKD_V25) printf(" ITU");
2121            if (zz & CKD_SB) printf(" SB");
2122            if (zz & CKD_EC) printf(" EC");
2123            if (zz & CKD_DC) printf(" DC");
2124            if (zz & CKD_HW) printf(" HWFC");
2125            if (zz & CKD_SW) printf(" SWFC");
2126            if (zz & CKD_KS) printf(" KS");
2127            if (zz & CKD_TB) printf(" TB");
2128        }
2129        printf("\n Modem maximum-speed:    ");
2130        zz = (dialmax > 0L) ? dialmax : p->max_speed;
2131        if (zz > 0)
2132          printf("%ld bps\n", zz);
2133        else
2134          printf("(unknown)\n");
2135        printf(" Modem error-correction: %s\n", dialec ? "on" : "off");
2136        printf(" Modem compression:      %s\n", dialdc ? "on" : "off");
2137        printf(" Modem speed-matching:   %s",   mdmspd ? "on" : "off");
2138        printf(" (interface speed %s)\n", mdmspd ? "changes" : "is locked");
2139        printf(" Modem flow-control:     ");
2140        if (dialfc == FLO_NONE) printf("none\n");
2141        else if (dialfc == FLO_XONX) printf("xon/xoff\n");
2142        else if (dialfc == FLO_RTSC) printf("rts/cts\n");
2143        else if (dialfc == FLO_AUTO) printf("auto\n");
2144        printf(" Modem kermit-spoof:     %s\n", dialksp ? "on" : "off");
2145        c = (char) (x = (dialesc ? dialesc : p->esc_char));
2146        printf(" Modem escape-character: %d", x);
2147        if (isprint(c))
2148          printf(" (= \"%c\")",c);
2149        printf(
2150"\n\nMODEM COMMANDs (* = set automatically by SET MODEM TYPE):\n\n");
2151        printf(" %c Init-string:          ", dialini ? ' ' : '*' );
2152        shods(dialini ? dialini : p->wake_str);
2153    printf(" %c Dial-mode-string:     ", dialmstr ? ' ' : '*' );
2154    shods(dialmstr ? dialmstr : p->dmode_str);
2155    printf(" %c Dial-mode-prompt:     ", dialmprmt ? ' ' : '*' );
2156    shods(dialmprmt ? dialmprmt : p->dmode_prompt);
2157    printf(" %c Dial-command:         ", dialcmd ? ' ' : '*' );
2158        shods(dialcmd ? dialcmd : p->dial_str);
2159        printf(" %c Compression on:       ", dialdcon ? ' ' : '*' );
2160        shods(dialdcon ? dialdcon : p->dc_on_str);
2161        printf(" %c Compression off:      ", dialdcoff ? ' ' : '*' );
2162        shods(dialdcoff ? dialdcoff : p->dc_off_str);
2163        printf(" %c Error-correction on:  ", dialecon ? ' ' : '*' );
2164        shods(dialecon ? dialecon : p->ec_on_str);
2165        n = local ? 19 : 20;
2166        if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
2167        printf(" %c Error-correction off: ", dialecoff ? ' ' : '*' );
2168        shods(dialecoff ? dialecoff : p->ec_off_str);
2169        if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
2170        printf(" %c Autoanswer on:        ", dialaaoff ? ' ' : '*' );
2171        shods(dialaaon ? dialaaon : p->aa_on_str);
2172        if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
2173        printf(" %c Autoanswer off:       ", dialaaoff ? ' ' : '*' );
2174        shods(dialaaoff ? dialaaoff : p->aa_off_str);
2175        if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
2176        printf(" %c Hangup-command:       ", dialhcmd ? ' ' : '*' );
2177        shods(dialhcmd ? dialhcmd : p->hup_str);
2178        if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
2179        printf(" %c Hardware-flow:        ", dialhwfc ? ' ' : '*' );
2180        shods(dialhwfc ? dialhwfc : p->hwfc_str);
2181        if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
2182        printf(" %c Software-flow:        ", dialswfc ? ' ' : '*' );
2183        shods(dialswfc ? dialswfc : p->swfc_str);
2184        if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
2185        printf(" %c No-flow-control:      ", dialnofc ? ' ' : '*' );
2186        shods(dialnofc ? dialnofc : p->nofc_str);
2187        if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
2188        printf(" %c Pulse:                ", dialpulse ? ' ' : '*');
2189        shods(dialpulse ? dialpulse : p->pulse);
2190        if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
2191        printf(" %c Tone:                 ", dialtone ? ' ' : '*');
2192        shods(dialtone ? dialtone : p->tone);
2193        if (++n > cmd_rows - 4) if (!askmore()) return(0); else n = 0;
2194        printf("\n For more info: SHOW DIAL and SHOW COMMUNICATIONS\n");
2195
2196    } else if (mdmtyp > 0) {
2197        printf("Modem info for \"%s\" not filled in yet\n", gmdmtyp());
2198    } else printf(
2199" No modem selected, so DIAL and most SET MODEM commands have no effect.\n\
2200 Use SET MODEM TYPE to select a modem.\n");
2201    return(1);
2202}
2203#endif /* NOSHOW */
2204#endif /* NODIAL */
2205
2206#ifndef NOSPL
2207
2208static int mdays[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
2209
2210_PROTOTYP(static int setalarm,(long));
2211
2212#ifdef CK_ANSIC                         /* SET ALARM */
2213static int
2214setalarm(long xx)
2215#else
2216static int
2217setalarm(xx) long xx;
2218#endif /* CK_ANSIC */
2219/* setalarm */ {
2220    int yyyy, mm, dd, x;
2221    char *s;
2222    long zz;
2223
2224    debug(F101,"setalarm xx","",xx);
2225    ck_alarm = 0L;                      /* 0 = no alarm (in case of error) */
2226    if (xx < 0L) {
2227        printf("%ld - illegal value, must be 0 or positive\n", xx);
2228        return(-9);
2229    }
2230    x = 8;                              /* Get current date */
2231    s = alrm_date;
2232    if (zzstring("\\v(ndate)",&s,&x) < 0) {
2233        printf("Internal date error, sorry.\n");
2234        alrm_date[0] = SP;
2235        return(-9);
2236    }
2237    x = 5;                              /* Get current time */
2238    s = alrm_time;
2239    if (zzstring("\\v(ntime)",&s,&x) < 0) {
2240        printf("Internal time error, sorry.\n");
2241        alrm_time[0] = SP;
2242        return(-9);
2243    }
2244    debug(F110,"SET ALARM date (1)",alrm_date,0);
2245    debug(F110,"SET ALARM time (1)",alrm_time,0);
2246
2247    if ((zz = atol(alrm_time) + xx) < 0L) {
2248        printf("Internal time conversion error, sorry.\n");
2249        return(-9);
2250    }
2251    if (zz > 86400L) {                  /* Alarm crosses midnight */
2252        char d[10];                     /* Local date buffer */
2253        int lastday;                    /* Last day of this month */
2254
2255        strncpy(d,alrm_date,8);         /* We'll have to change the date */
2256
2257        x = (zz / 86400L);              /* How many days after today */
2258
2259        dd = atoi((char *)(d+6));       /* Parse yyyymmdd */
2260        d[6] = NUL;                     /* into yyyy, mm, dd ... */
2261        mm = atoi((char *)(d+4));
2262        d[4] = NUL;
2263        yyyy = atoi((char *)d);
2264
2265        /* How many days in this month */
2266
2267        lastday = mdays[mm];
2268        if (mm == 2 && yyyy % 4 == 0)   /* Works thru 2099 AD... */
2269          lastday++;
2270
2271        if (dd + x > lastday) {         /* Dumb loop */
2272            int y;
2273           
2274            x -= (mdays[mm] - dd);      /* Deduct rest of this month's days */
2275
2276            /* There's a more elegant way to do this... */
2277
2278            while (1) {
2279                mm++;                   /* Next month */
2280                if (mm > 12) {          /* Wrap around */
2281                    mm = 1;             /* Jan, next year */
2282                    yyyy++;
2283                }
2284                y = mdays[mm];          /* Days in new month */
2285                if (mm == 2 && yyyy % 4 == 0) /* Feb in leap year */
2286                  y++;                  /* Works until 2100 AD */
2287                if (x - y < 1)
2288                  break;
2289                x -= y;
2290            }
2291            dd = x;                     /* Day of alarm month */
2292        } else dd += x;
2293
2294        sprintf(alrm_date,"%04d%02d%02d",yyyy,mm,dd);
2295        zz = zz % 86400L;
2296    }
2297    sprintf(alrm_time,"%ld",zz);
2298    debug(F110,"SET ALARM date (2)",alrm_date,0);
2299    debug(F110,"SET ALARM time (2)",alrm_time,0);
2300    ck_alarm = xx;
2301    return(1);
2302}
2303#endif /* NOSPL */
2304
2305#ifndef NOSETKEY
2306int
2307set_key() {                             /* SET KEY */
2308    int x, y;
2309    int flag = 0;
2310    int kc;                             /* Key code */
2311    char *s;                            /* Key binding */
2312#ifndef NOKVERBS
2313    char *p;                            /* Worker */
2314#endif /* NOKVERBS */
2315#ifdef OS2
2316    extern int os2gks;
2317    extern int mskkeys;
2318    extern int initvik;
2319#endif /* OS2 */
2320
2321    x_ifnum = 1;
2322    y = cmnum("numeric key code, or the word CLEAR,","",10,&kc,xxstring);
2323    x_ifnum = 0;
2324    if (y < 0) {
2325        debug(F111,"SET KEY",atmbuf,y);
2326        if (y == -2) {                  /* Not a valid number */
2327            if ((y = strlen(atmbuf)) < 0) /* Check for SET KEY CLEAR */
2328              return(-2);
2329            if (xxstrcmp(atmbuf,"clear",y))
2330              return(-2);
2331            if ((x = cmcfm()) < 0)
2332              return(x);
2333            for (y = 0; y < KMSIZE; y++) {
2334                keymap[y] = (KEY) y;
2335                macrotab[y] = NULL;
2336            }
2337#ifdef OS2
2338            keymapinit();               /* Special OS/2 initializations */
2339            initvik = 1;                /* Update the VIK table */
2340#endif /* OS2 */
2341            return(1);
2342        } else if (y == -3) {           /* SET KEY <Return> */
2343            printf(" Press key to be defined: "); /* Prompt for a keystroke */
2344#ifdef UNIX
2345#ifdef NOSETBUF
2346            fflush(stdout);
2347#endif /* NOSETBUF */
2348#endif /* UNIX */
2349            conbin((char)escape);       /* Put terminal in binary mode */
2350#ifdef OS2
2351            os2gks = 0;                 /* Turn off Kverb preprocessing */
2352#endif /* OS2 */
2353            kc = congks(0);             /* Get character or scan code */
2354#ifdef OS2
2355            os2gks = 1;                 /* Turn on Kverb preprocessing */
2356#endif /* OS2 */
2357            concb((char)escape);        /* Restore terminal to cbreak mode */
2358            if (kc < 0) {               /* Check for error */
2359                printf("?Error reading key\n");
2360                return(0);
2361            }
2362            shokeycode(kc);             /* Show current definition */
2363            flag = 1;                   /* Remember it's a multiline command */
2364        } else                          /* Error */
2365          return(y);
2366    }
2367
2368    /* Normal SET KEY <scancode> <value> command... */
2369
2370#ifdef OS2
2371    if ( mskkeys )
2372      kc = msktock(kc);
2373#endif /* OS2 */
2374
2375    if (kc < 0 || kc >= KMSIZE) {
2376        printf("?key code must be between 0 and %d\n", KMSIZE - 1);
2377        return(-9);
2378    }
2379    if (kc == escape) {
2380        printf("Sorry, %d is the CONNECT-mode escape character\n",kc);
2381        return(-9);
2382    }
2383#ifdef OS2
2384    wideresult = -1;
2385#endif /* OS2 */
2386    if (flag) {
2387        cmsavp(psave,PROMPTL);
2388        cmsetp(" Enter new definition: ");
2389        cmini(ckxech);
2390    }
2391  def_again:
2392    if (flag) prompt(NULL);
2393    if ((y = cmtxt("key definition,\n\
2394or Ctrl-C to cancel this command,\n\
2395or Enter to restore default definition",
2396                   "",&s,NULL)) < 0) {
2397        if (flag)                       /* Handle parse errors */
2398          goto def_again;
2399        else
2400          return(y);
2401    }
2402    s = brstrip(s);
2403#ifndef NOKVERBS
2404    p = s;                              /* Save this place */
2405#endif /* NOKVERBS */
2406/*
2407  If the definition included any \Kverbs, quote the backslash so the \Kverb
2408  will still be in the definition when the key is pressed.  We don't do this
2409  in zzstring(), because \Kverbs are valid only in this context and nowhere
2410  else.
2411
2412  We use this code active for all versions that support SET KEY, even if they
2413  don't support \Kverbs, because otherwise \K would behave differently for
2414  different versions.
2415*/
2416    for (x = 0, y = 0; s[x]; x++, y++) { /* Convert \K to \\K */
2417        if ((x > 0) &&
2418            (s[x] == 'K' || s[x] == 'k')
2419            ) {                         /* Have K */
2420 
2421            if ((x == 1 && s[x-1] == CMDQ) ||
2422                (x > 1 && s[x-1] == CMDQ && s[x-2] != CMDQ)) {
2423                line[y++] = CMDQ;       /* Make it \\K */
2424            }
2425            if (x > 1 && s[x-1] == '{' && s[x-2] == CMDQ) {
2426                line[y-1] = CMDQ;       /* Have \{K */
2427                line[y++] = '{';        /* Make it \\{K */
2428            }
2429        }
2430        line[y] = s[x];
2431    }
2432    line[y++] = NUL;                    /* Terminate */
2433    s = line + y + 1;                   /* Point to after it */
2434    x = LINBUFSIZ - (int) strlen(line) - 1; /* Calculate remaining space */
2435    if ((x < (LINBUFSIZ / 2)) ||
2436        (zzstring(line, &s, &x) < 0)) { /* Expand variables, etc. */
2437        printf("?Key definition too long\n");
2438        if (flag) cmsetp(psave);
2439        return(-9);
2440    }
2441    s = line + y + 1;                   /* Point to result. */
2442
2443#ifndef NOKVERBS
2444/*
2445  Special case: see if the definition starts with a \Kverb.
2446  If it does, point to it with p, otherwise set p to NULL.
2447*/
2448    p = s;
2449    if (*p++ == CMDQ) {
2450        if (*p == '{') p++;
2451        p = (*p == 'k' || *p == 'K') ? p + 1 : NULL;
2452    }
2453#endif /* NOKVERBS */
2454
2455    if (macrotab[kc]) {                 /* Possibly free old macro from key. */
2456        free(macrotab[kc]);
2457        macrotab[kc] = NULL;
2458    }
2459    switch (strlen(s)) {                /* Action depends on length */
2460      case 0:                           /* Reset to default binding */
2461        keymap[kc] = (KEY) kc;
2462        break;
2463      case 1:                           /* Single character */
2464        keymap[kc] = (CHAR) *s;
2465        break;
2466      default:                          /* Character string */
2467#ifndef NOKVERBS
2468        if (p) {
2469            y = xlookup(kverbs,p,nkverbs,&x); /* Look it up */
2470            debug(F101,"set key kverb lookup",0,y); /* exact match required */
2471            if (y > -1) {
2472                keymap[kc] = F_KVERB | y;
2473                break;
2474            }
2475        }
2476#endif /* NOKVERBS */
2477        keymap[kc] = (KEY) kc;
2478        macrotab[kc] = (MACRO) malloc(strlen(s)+1);
2479        if (macrotab[kc])
2480          strcpy((char *) macrotab[kc], s);
2481        break;
2482    }
2483    if (flag) cmsetp(psave);
2484#ifdef OS2
2485    initvik = 1;                        /* Update VIK table */
2486#endif /* OS2 */
2487    return(1);
2488}
2489#endif /* NOSETKEY */
2490
2491/*
2492  PROTOCOL SELECTION.  Kermit is always available.  If CK_XYZ is defined at
2493  compile time, then the others become selections also.  In OS/2 and
2494  Windows, they are integrated and the various SET commands (e.g. "set file
2495  type") affect them as they would Kermit.  In other OS's (UNIX, VMS, etc),
2496  they are external protocols which are run via Kermit's REDIRECT mechanism.
2497  All we do is collect and verify the filenames and pass them along to the
2498  external protocol.
2499*/
2500extern int protocol;
2501struct keytab protos[] = {
2502#ifdef CK_XYZ
2503    "g",        PROTO_G,  CM_INV,
2504#endif /* CK_XYZ */
2505    "kermit",   PROTO_K,  0,
2506#ifdef CK_XYZ
2507    "other",    PROTO_O,  0,
2508    "xmodem",   PROTO_X,  0,
2509    "y",        PROTO_Y,  CM_INV|CM_ABR,
2510    "ymodem",   PROTO_Y,  0,
2511    "ymodem-g", PROTO_G,  0,
2512    "zmodem",   PROTO_Z,  0
2513#endif /* CK_XYZ */
2514};
2515int nprotos =  (sizeof(protos) / sizeof(struct keytab));
2516
2517#define XPCMDLEN 71
2518
2519_PROTOTYP(static int protofield, (char *, char *, char *));
2520_PROTOTYP(static int setproto, (void));
2521
2522static int
2523protofield(current, help, px) char * current, * help, *px; {
2524
2525    char *s, tmpbuf[XPCMDLEN+1];
2526    int x;
2527
2528    if (current)                        /* Put braces around default */
2529      sprintf(tmpbuf,"{%s}",current);
2530    else
2531      tmpbuf[0] = NUL;
2532
2533    if ((x = cmfld(help, (char *)tmpbuf, &s, xxstring)) < 0)
2534      return(x);
2535    if ((int)strlen(s) > XPCMDLEN) {
2536        printf("?Sorry - maximum length is %d\n", XPCMDLEN);
2537        return(-9);
2538    } else if (*s) {
2539        strcpy(px,s);
2540    } else {
2541        px = NULL;
2542    }
2543    return(x);
2544}
2545
2546static int
2547setproto() {                            /* Select a file transfer protocol */
2548    char * s = NULL;
2549    int x = 0, y;
2550    char s1[XPCMDLEN+1], s2[XPCMDLEN+1], s3[XPCMDLEN+1];
2551    char s4[XPCMDLEN+1], s5[XPCMDLEN+1], s6[XPCMDLEN+1];
2552    char * p1 = s1, * p2 = s2, *p3 = s3;
2553    char * p4 = s4, * p5 = s5, *p6 = s6;
2554
2555#ifdef XYZ_INTERNAL
2556    extern int p_avail;
2557#else
2558#ifndef CK_REDIR
2559    x = 1;
2560#endif /* CK_REDIR */
2561#endif /* XYZ_INTERNAL */
2562    s1[0] = NUL;
2563    s2[0] = NUL;
2564    s3[0] = NUL;
2565    s4[0] = NUL;
2566    s5[0] = NUL;
2567    s6[0] = NUL;
2568
2569    if ((y = cmkey(protos,nprotos,"","kermit",xxstring)) < 0)
2570      return(y);
2571
2572    if (x && y != PROTO_K) {
2573        printf(
2574           "?Sorry, REDIRECT capability required for external protocols.\n");
2575        return(-9);
2576    }
2577    if ((x = protofield(ptab[y].h_b_init,
2578     "Optional command to send to host prior to uploading in binary mode",
2579               p1)) < 0) {
2580        if (x == -3) {
2581            protocol = y;               /* Set protocol but don't change */
2582            return(1);                  /* anything else */
2583        } else
2584          return(x);
2585    }
2586    if ((x = protofield(ptab[y].h_t_init,
2587     "Optional command to send to host prior to uploading in text mode",
2588               p2)) < 0) {
2589        if (x == -3)
2590          goto protoexit;
2591        else
2592          return(x);
2593    }
2594
2595#ifndef XYZ_INTERNAL                    /* If XYZMODEM are external... */
2596
2597    if ((x = protofield(ptab[y].p_b_scmd,
2598     "External command to SEND in BINARY mode with this protocol",
2599               p3)) < 0) {
2600        if (x == -3)
2601          goto protoexit;
2602        else
2603          return(x);
2604    }
2605    if ((x = protofield(ptab[y].p_t_scmd,
2606     "External command to SEND in TEXT mode with this protocol",
2607               p4)) < 0) {
2608        if (x == -3)
2609          goto protoexit;
2610        else
2611          return(x);
2612    }
2613    if ((x = protofield(ptab[y].p_b_rcmd,
2614     "External command to RECEIVE in BINARY mode with this protocol",
2615               p5)) < 0) {
2616        if (x == -3)
2617          goto protoexit;
2618        else
2619          return(x);
2620    }
2621    if ((x = protofield(ptab[y].p_t_rcmd,
2622     "External command to RECEIVE in TEXT mode with this protocol",
2623               p6)) < 0) {
2624        if (x == -3)
2625          goto protoexit;
2626        else
2627          return(x);
2628    }
2629#endif /* XYZ_INTERNAL */
2630
2631    if ((x = cmcfm()) < 0)              /* Confirm the command */
2632      return(x);
2633
2634protoexit:                              /* Common exit from this routine */
2635
2636#ifdef XYZ_INTERNAL
2637    if (!p_avail) {
2638        bleep(BP_WARN);
2639        printf("\n?X,Y, and Zmodem are unavailable\n");
2640        return(success = 0);
2641    }
2642#endif /* XYZ_INTERNAL */
2643
2644    if (p1) p1 = brstrip(p1);
2645    if (p2) p2 = brstrip(p2);
2646    if (p3) p3 = brstrip(p3);
2647    if (p4) p4 = brstrip(p4);
2648    if (p5) p5 = brstrip(p5);
2649    if (p6) p6 = brstrip(p6);
2650
2651    initproto(y,p1,p2,p3,p4,p5,p6);
2652    return(success = 1);
2653}
2654
2655int
2656setdest() {
2657    int x, y;
2658    if ((y = cmkey(desttab,ndests,"","disk",xxstring)) < 0) return(y);
2659    if ((x = cmcfm()) < 0) return(x);
2660    dest = y;
2661    return(1);
2662}
2663
2664/*  D O P R M  --  Set a parameter.  */
2665/*
2666 Returns:
2667  -2: illegal input
2668  -1: reparse needed
2669   0: success
2670*/
2671int
2672doprm(xx,rmsflg) int xx, rmsflg; {
2673    int i, x, y = 0, z;
2674    long zz;
2675    char *s=NULL, *p=NULL;
2676 
2677#ifdef OS2
2678    if (xx == XYMSK)
2679      return(setmsk());
2680#endif /* OS2 */
2681
2682    if (xx == XYPRTR) {                 /* SET PRINTER */
2683        if ((x = cmofi("printer file",
2684#ifdef OS2
2685                       "PRN"
2686#else
2687#ifdef VMS
2688                       "LPT:"
2689#else
2690#ifdef UNIX
2691                       "|lpr"
2692
2693#else
2694                       ""
2695#endif /* UNIX */
2696#endif /* VMS */
2697#endif /* OS2 */
2698                       ,&s,xxstring)) < 0)
2699          return(x);
2700        if (x > 1) {
2701            printf("?Directory names not allowed\n");
2702            return(-9);
2703        }
2704        while (*s == SP || *s == HT) s++; /* Trim leading whitespace */
2705        strcpy(line,s);                 /* Make a temporary safe copy */
2706        if ((x = cmcfm()) < 0)          /* Confirm the command */
2707          return(x);
2708        s = line;
2709#ifdef OS2ORUNIX
2710        if (printpipe = (*s == '|')) {  /* Have pipe? */
2711            s++;                        /* Point past pipe sign */
2712            while (*s == SP | *s == HT) s++; /* Gobble whitespace */
2713        }           
2714#ifdef UNIX
2715        if (!printpipe) {
2716            if (zchko(s) < 0) {
2717                printf("?Access denied - %s\n",s);
2718                return(-9);
2719            }
2720        }
2721#endif /* UNIX */
2722#endif /* OS2ORUNIX */
2723
2724        if (printfile) {                /* Had a print file before? */
2725            free(printfile);            /* Remove its name */
2726            printfile = NULL;
2727        }
2728        x = strlen(s);                  /* Length of name of new print file */
2729        if (x > 0) {
2730#ifdef OS2
2731            if ((x != 3) || (xxstrcmp(s,"PRN",3) != 0)) {
2732#endif /* OS2 */
2733                printfile = (char *) malloc(x + 1); /* Allocate space for it */
2734                if (!printfile) {
2735                    printf("?Memory allocation failure\n");
2736                    return(-9);
2737                }
2738                strcpy(printfile,s);    /* Copy new name to new space */
2739                debug(F110,"printfile name",printfile,0);
2740#ifdef OS2
2741            } else
2742#endif /* OS2 */
2743              debug(F101,"printfile is NULL","",printfile);
2744        }
2745        /* Return with printfile pointing to a file or device name */
2746        /* or NULL to indicate the default printer. */
2747        return(success = 1);
2748    }
2749
2750switch (xx) {
2751 
2752#ifdef ANYX25                           /* SET X25 ... */
2753case XYX25:
2754    return(setx25());
2755
2756case XYPAD:                             /* SET PAD ... */
2757    return(setpadp());
2758#endif /* ANYX25 */
2759
2760case XYEOL:     /* These have all been moved to set send/receive... */
2761case XYLEN:     /* Let the user know what to do. */
2762case XYMARK:
2763case XYNPAD:
2764case XYPADC:
2765case XYTIMO:
2766    printf("...Use SET SEND or SET RECEIVE instead.\n");
2767    printf("Type HELP SET SEND or HELP SET RECEIVE for more info.\n");
2768    return(success = 0);
2769
2770case XYATTR:                            /* File Attribute packets */
2771    return(setat(rmsflg));
2772
2773case XYIFD:                             /* Incomplete file disposition */
2774    if ((y = cmkey(ifdtab,2,"","discard",xxstring)) < 0) return(y);
2775    if ((x = cmcfm()) < 0) return(x);
2776    if (rmsflg) {
2777        sstate = setgen('S', "310", y ? "1" : "0", "");
2778        return((int) sstate);
2779    } else {
2780        keep = y;
2781        return(success = 1);
2782    }
2783 
2784#ifndef NOSPL
2785case XYINPU:                            /* SET INPUT */
2786    return(setinp());
2787#endif /* NOSPL */
2788
2789#ifdef NETCONN
2790case XYNET:                             /* SET NETWORK */
2791
2792#ifdef OS2     /* Hide network-type keywords for networks not installed */
2793    for (z = 0; z < nnets; z++) {
2794        if (netcmd[z].kwval == NET_TCPB && tcp_avail == 0)
2795          netcmd[z].flgs =  CM_INV;
2796#ifdef DECNET
2797        else if (netcmd[z].kwval == NET_DEC  && dnet_avail == 0)
2798          netcmd[z].flgs =  CM_INV;
2799#endif /* DECNET */
2800#ifdef CK_NETBIOS
2801        else if (netcmd[z].kwval == NET_BIOS && netbiosAvail == 0)
2802          netcmd[z].flgs =  CM_INV;
2803#endif /* CK_NETBIOS */
2804#ifdef SUPERLAT
2805        else if (netcmd[z].kwval == NET_SLAT  && slat_avail == 0)
2806          netcmd[z].flgs =  CM_INV;
2807#endif /* SUPERLAT */
2808    }
2809    if (tcp_avail)                      /* Default network type */
2810      strcpy(tmpbuf,"tcp/ip");
2811#ifdef DECNET
2812    else if (dnet_avail)
2813      strcpy(tmpbuf,"decnet");
2814#endif /* DECNET */
2815#ifdef SUPERLAT
2816    else if (slat_avail)
2817      strcpy(tmpbuf,"superlat");
2818#endif /* SUPERLAT */
2819#ifdef CK_NETBIOS
2820    else if (netbiosAvail)
2821      strcpy(tmpbuf,"netbios");
2822#endif /* CK_NETBIOS */
2823    else strcpy(tmpbuf,"named-pipe");
2824#else
2825#ifdef TCPSOCKET
2826    strcpy(tmpbuf,"tcp/ip");
2827#else
2828#ifdef ANYX25
2829    strcpy(tmpbuf,"x.25");
2830#else
2831    strcpy(tmpbuf,"");   
2832#endif /* ANYX25 */
2833#endif /* TCPSOCKET */
2834#endif /* OS2 */
2835
2836    if ((z = cmkey(netcmd,nnets,"",tmpbuf,xxstring)) < 0)
2837      return(z);
2838
2839#ifndef NODIAL
2840    if (z == XYNET_D)                   /* DIRECTORY */
2841      return(parsdir(1));
2842#endif /* NODIAL */
2843
2844    if (z == XYNET_T) {                 /* TYPE */
2845        if ((z = cmkey(netkey,nnetkey,"",tmpbuf,xxstring)) < 0)
2846          return(z);
2847    }
2848
2849#ifdef OS2
2850    if (z == NET_TCPB && tcp_avail == 0) {
2851        printf("\n?Sorry, either TCP/IP is not available on this system or\n\
2852necessary DLLs did not load.  Use SHOW NETWORK to check network status.\n");
2853        return(-9);
2854#ifdef CK_NETBIOS
2855    } else if (z == NET_BIOS && netbiosAvail == 0) {
2856        printf("\n?Sorry, NETBIOS is not available on this system.\n") ;
2857        return(-9);
2858#endif /* CK_NETBIOS */
2859#ifdef DECNET
2860    } else if (z == NET_DEC && dnet_avail == 0) {
2861        printf("\n?Sorry, DECnet is not available on this system.\n") ;
2862        return(-9);
2863#endif /* DECNET */
2864#ifdef SUPERLAT
2865    } else if (z == NET_SLAT && slat_avail == 0) {
2866        printf("\n?Sorry, SuperLAT is not available on this system.\n") ;
2867        return(-9);
2868#endif /* SUPERLAT */
2869    }
2870#endif /* OS2 */
2871
2872#ifdef NPIPEORBIOS
2873    if (z == NET_PIPE ||                /* Named pipe -- also get pipename */
2874        z == NET_BIOS) {                /* NETBIOS -- also get local name */
2875        char *defnam;
2876#ifdef CK_NETBIOS
2877        char tmpnbnam[NETBIOS_NAME_LEN+1];
2878#endif /* CK_NETBIOS */
2879        /* Construct default name  */
2880        if (z == NET_PIPE) {            /* Named pipe */
2881            defnam = "kermit";          /* Default name is always "kermit" */
2882        } else {                        /* NetBIOS */
2883            if (NetBiosName[0] != SP) { /* If there is already a name, */
2884                char *p = NULL;
2885                int n;          /* use it as the default. */
2886                strcpy(tmpnbnam,NetBiosName);
2887                p = tmpnbnam + NETBIOS_NAME_LEN - 1;
2888                while (*p == SP) {
2889                    *p = NUL;
2890                    p--;
2891                }
2892                defnam = tmpnbnam;
2893            } else if (*myhost)         /* Otherwise use this PC's host name */
2894              defnam = (char *) myhost;
2895            else                        /* Otherwise use "kermit" */
2896              defnam = "kermit";
2897        }
2898        if ((y = cmtxt((z == NET_PIPE) ? "pipe name" : "local NETBIOS name",
2899                       defnam, &s, xxstring)) < 0)
2900          return(y);
2901#ifdef NPIPE
2902        pipename[0] = NUL;
2903#endif /* NPIPE */
2904        if ((y = (int) strlen(s)) < 1) {
2905            printf("?You must also specify a %s name\n",
2906                   (z == NET_PIPE) ? "pipe" : "local NETBIOS" );
2907            return(-9);
2908        }
2909#ifdef CK_NETBIOS
2910        if (z == NET_BIOS) {
2911            if ( !netbiosAvail ) {
2912                printf("?NETBIOS support is not available on this system.\n") ;
2913                return(-9) ;
2914            }
2915            if ( y - NETBIOS_NAME_LEN > 0) {
2916                printf("?NETBIOS name too long, %ld maximum\n",
2917                       NETBIOS_NAME_LEN);
2918                return(-9);
2919            } else if ( !strcmp(s,tmpnbnam) ) {
2920                nettype = z;            /* Returning to old connection... */
2921                return(success = 1);    /* Done */
2922            } else if (strcmp("                ",NetBiosName)) {
2923                   printf("?Local NETBIOS name already assigned to \"%s\"\n",
2924                       NetBiosName);
2925                   return(-9) ;
2926           } else {
2927                NCB ncb ;
2928                APIRET rc ;
2929                strcpy(NetBiosName,s);
2930                for (x = y; x < NETBIOS_NAME_LEN; x++)
2931                  NetBiosName[x] = SP;
2932                NetBiosName[NETBIOS_NAME_LEN] = NUL;
2933                printf("Verifying \"%s\" is a unique NetBIOS node name ...\n",
2934                       NetBiosName) ;
2935                rc = NCBAddName( NetbeuiAPI,
2936                                &ncb, NetBiosAdapter, NetBiosName ) ;
2937                if ( rc ) {
2938                    printf(
2939                "?Sorry, \"%s\" is already in use by another NetBIOS node.\n",
2940                           NetBiosName);
2941                    for ( x=0; x < NETBIOS_NAME_LEN; x++)
2942                      NetBiosName[x] = SP ;
2943                    return(-9) ;
2944                }
2945            }
2946        }
2947#endif /* CK_NETBIOS */
2948#ifdef NET_PIPE
2949        if (z == NET_PIPE)
2950          strncpy(pipename,s,PIPENAML);
2951#endif /* NET_PIPE */
2952    } else
2953#endif /* NPIPEORBIOS */
2954      if ((x = cmcfm()) < 0) return(x);
2955    nettype = z;
2956    if (
2957#ifdef DECNET
2958        (nettype != NET_DEC)  &&
2959#endif /* DECNET */
2960#ifdef NPIPE
2961        (nettype != NET_PIPE) &&
2962#endif /* NPIPE */
2963#ifdef CK_NETBIOS
2964        (nettype != NET_BIOS) &&
2965#endif /* CK_NETBIOS */
2966#ifdef NETFILE
2967        (nettype != NET_FILE) &&
2968#endif /* NETFILE */
2969#ifdef SUPERLAT
2970        (nettype != NET_SLAT) &&
2971#endif /* SUPERLAT */
2972        (nettype != NET_SX25) &&
2973        (nettype != NET_VX25) &&
2974        (nettype != NET_TCPB)) {
2975        printf("?Network type not supported\n");
2976        return(success = 0);
2977    } else {
2978        return(success = 1);
2979    }
2980
2981#ifndef NOTCPOPTS
2982#ifdef TCPSOCKET
2983#ifdef SOL_SOCKET
2984case XYTCP:
2985if ((z = cmkey(tcpopt,ntcpopt,"TCP option","nodelay",xxstring)) < 0)
2986   return(z);
2987   
2988   switch (z) {
2989#ifdef SO_KEEPALIVE
2990   case XYTCP_KEEPALIVE:
2991      if ((z = cmkey(onoff,2,"","on",xxstring)) < 0) return(z);
2992      if ((y = cmcfm()) < 0) return(y);
2993      success = keepalive(z) ;
2994      return(success);
2995#endif /* SO_KEEPALIVE */
2996#ifdef TCP_NODELAY
2997   case XYTCP_NODELAY:
2998      if ((z = cmkey(onoff,2,"","off",xxstring)) < 0) return(z);
2999      if ((y = cmcfm()) < 0) return(y);
3000      success = no_delay(z) ;
3001      return(success);
3002#endif /* TCP_NODELAY */
3003#ifdef SO_LINGER
3004    case XYTCP_LINGER:
3005      if ((z = cmkey(onoff,2,"","on",xxstring)) < 0)
3006        return(z);
3007      if (z) {                          /* if on, we need a timeout value */
3008          if ((x = cmnum("Linger timeout in 10th of a millisecond",
3009                         "0",10,&y,xxstring)) < 0)
3010            return(x);
3011      } else
3012        y = 0;
3013      if ((x = cmcfm()) < 0)
3014        return(x);
3015      success = ck_linger(z,y);
3016      return(success);
3017#endif /* SO_LINGER */
3018#ifdef SO_SNDBUF
3019   case XYTCP_SENDBUF:
3020      x = cmnum("Send buffer size, bytes","8192",10,&z,xxstring);
3021      if (x < 0) return(x);
3022      if ((x = cmcfm()) < 0) return(x);   
3023      success = sendbuf(z);
3024      return(success);
3025#endif /* SO_SNDBUF */
3026#ifdef SO_RCVBUF
3027   case XYTCP_RECVBUF:   
3028      x = cmnum("Receive buffer size, bytes","8192",10,&z,xxstring);
3029      if (x < 0) return(x);
3030      if ((x = cmcfm()) < 0) return(x);   
3031      success = recvbuf(z);
3032      return(success);
3033#endif /* SO_RCVBUF */
3034   default:
3035      return(0);
3036   }
3037#endif /* SOL_SOCKET */
3038#endif /* TCPSOCKET */
3039#endif /* NOTCPOPTS */
3040#endif /* NETCONN */
3041}
3042
3043switch (xx) {
3044
3045#ifndef NOLOCAL
3046case XYHOST:                            /* SET HOST or SET LINE */
3047case XYLINE:
3048    return(setlin(xx,1));
3049#endif /* NOLOCAL */
3050 
3051#ifndef NOSETKEY
3052case XYKEY:                             /* SET KEY */
3053    return(set_key());
3054#endif /* NOSETKEY */
3055
3056#ifndef NOCSETS
3057case XYLANG:                            /* Language */
3058    if ((y = cmkey(lngtab,nlng,"","none",xxstring)) < 0) /* language code */
3059      return(y);
3060    if ((x = cmcfm()) < 0) return(x);   /* And confirmation of command */
3061
3062    /* Look up language and get associated character sets */
3063    for (i = 0; (i < nlangs) && (langs[i].id != y); i++) ;
3064    if (i >= nlangs) {
3065        printf("?internal error, sorry\n");
3066        return(success = 0);
3067    }
3068    language = i;                       /* All good, set the language, */
3069    return(success = 1);
3070#endif /* NOCSETS */
3071
3072#ifndef MAC
3073case XYBACK:                            /* BACKGROUND */
3074    if ((z = cmkey(onoff,2,"","",xxstring)) < 0) return(z);
3075    if ((y = cmcfm()) < 0) return(y);
3076    bgset = z;
3077    success = 1;
3078    bgchk();
3079    return(success);
3080#endif /* MAC */
3081
3082case XYQUIE:                            /* QUIET */
3083    return(success = seton(&quiet));
3084
3085case XYBUF: {                           /* BUFFERS */
3086#ifdef DYNAMIC
3087    int sb, rb;
3088    char sbs[10];
3089    if ((y = cmnum("Send buffer size","",10,&sb,xxstring)) < 0) {
3090        if (y == -3) printf("?Buffer size required\n");
3091        return(y);
3092    }
3093    if (sb < 0) {
3094        if (*atmbuf == '-') printf("?Negative numbers can't be used here\n");
3095        else printf("?Integer overflow, use a smaller number please\n");
3096        return(-9);
3097    } else if (sb < 80) {
3098        printf("?Too small\n");
3099        return(-9);
3100    }
3101    sprintf(sbs,"%d",sb);               /* Default second size == first */
3102    if ((y = cmnum("Receive buffer size",sbs,10,&rb,xxstring)) < 0)
3103      return(y);
3104    if (rb < 0) {
3105        if (*atmbuf == '-') printf("?Negative numbers can't be used here\n");
3106        else printf("?Integer overflow, use a smaller number please\n");
3107        return(-9);
3108    } else if (rb < 80) {
3109        printf("?Too small\n");
3110        return(-9);
3111    }
3112    if ((y = cmcfm()) < 0) return(y);
3113    if ((y = inibufs(sb,rb)) < 0) return(y);
3114    y = adjpkl(urpsiz,wslotr,bigrbsiz); /* Maybe adjust packet sizes */
3115    if (y != urpsiz) urpsiz = y;
3116    y = adjpkl(spsiz,wslotr,bigsbsiz);
3117    if (y != spsiz) spsiz = spmax = spsizr = y;
3118    return(success = 1);
3119#else
3120    printf("?Sorry, not available\n");
3121    return(success = 0);
3122#endif /* DYNAMIC */
3123}
3124
3125case XYCHKT:                            /* BLOCK-CHECK */
3126    if ((x = cmkey(chktab,4,"","3",xxstring)) < 0) return(x);
3127    if ((y = cmcfm()) < 0) return(y);
3128    bctr = x;                        /* Set locally too, even if REMOTE SET */
3129    if (rmsflg) {
3130        if (x == 4) {
3131            tmpbuf[0] = 'B';
3132            tmpbuf[1] = '\0';
3133        } else sprintf(tmpbuf,"%d",x);
3134        sstate = setgen('S', "400", tmpbuf, "");
3135        return((int) sstate);
3136    } else {
3137        return(success = 1);
3138    }
3139 
3140#ifndef NOLOCAL
3141#ifndef MAC
3142/*
3143  The Mac has no carrier...
3144*/
3145case XYCARR:                            /* CARRIER */
3146    return(success = setdcd());
3147#endif /* MAC */
3148#endif /* NOLOCAL */
3149}
3150
3151#ifdef TNCODE
3152switch (xx) {                           /* Avoid long switch statements... */
3153case XYTEL:                             /* TELNET */
3154    if ((z = cmkey(tntab,ntn,"parameter for TELNET negotiations", "",
3155                   xxstring)) < 0)
3156      return(z);
3157    switch (z) {
3158      case CK_TN_EC:                    /* ECHO */
3159        if ((x = cmkey(rltab,nrlt,
3160                       "initial TELNET echoing state","local",xxstring)) < 0)
3161          return(x);
3162        if ((y = cmcfm()) < 0) return(y);
3163        tn_duplex = x;
3164        return(success = 1);
3165
3166      case CK_TN_TT:                    /* TERMINAL TYPE */
3167        if ((y = cmtxt("terminal type for TELNET connections","",
3168                       &s,xxstring)) < 0)
3169          return(y);
3170        if (tn_term) {
3171            free(tn_term);              /* Free any previous storage */
3172            tn_term = NULL;
3173        }
3174        if (s == NULL || *s == NUL) {   /* If none given */
3175            tn_term = NULL;             /* remove the override string */
3176            return(success = 1);
3177        } else if (tn_term = malloc(strlen(s)+1)) { /* Make storage for new */
3178            strcpy(tn_term,s);          /* Copy string into new storage */
3179            return(success = 1);
3180        } else return(success = 0);
3181
3182      case CK_TN_NL:                    /* TELNET NEWLINE-MODE */
3183        if ((x = cmkey(tn_nlmtab,ntn_nlm,"","nvt",xxstring)) < 0)
3184          return(x);
3185        if (x == TN_NL_BIN) {
3186            if ((x = cmkey(tnlmtab,ntnlm,"","raw",xxstring)) < 0)
3187              return(x);
3188            if ((y = cmcfm()) < 0)
3189              return(y);
3190            tn_b_nlm = x;
3191            return(success = 1);
3192        } else if (x == TN_NL_NVT) {
3193            if ((x = cmkey(tnlmtab,ntnlm,"","on",xxstring)) < 0)
3194              return(x);
3195            if ((y = cmcfm()) < 0)
3196              return(y);
3197            tn_nlm = x;
3198            return(success = 1);
3199        } else {
3200            if ((y = cmcfm()) < 0)
3201              return(y);
3202            tn_nlm = x;
3203            return(success = 1);
3204        }
3205
3206      case CK_TN_BM:                    /* BINARY-MODE */
3207        if ((x = cmkey(tnbmtab,3,"","refused",xxstring)) < 0)
3208          return(x);
3209        if ((y = cmcfm()) < 0)
3210          return(y);
3211        tn_binary = x;
3212        return(success = 1);
3213
3214      case CK_TN_BUG:                   /* BUG */
3215        if ((x = cmkey(tnbugtab,2,"","binary-me-means-u-too",xxstring)) < 0)
3216          return(x);
3217        if ((z = cmkey(onoff,2,"","off",xxstring)) < 0) return(z);
3218        if ((y = cmcfm()) < 0) return(y);
3219        switch (x) {
3220          case 0:
3221            tn_b_meu = z;
3222            break;
3223          case 1:
3224            tn_b_ume = z;
3225            break;
3226        }
3227        return(success = 1);
3228
3229#ifdef CK_ENVIRONMENT
3230    case CK_TN_ENV: {
3231        char * msg = "value of telnet environment variable";
3232        extern char tn_env_acct[], tn_env_disp[], tn_env_job[],
3233                    tn_env_prnt[], tn_env_sys[]; 
3234        if ((x = cmkey(tnenvtab,ntnenv,"","",xxstring)) < 0)
3235          return(x);
3236        if (x == TN_ENV_UVAR) {
3237            /* Get the user variable name */
3238        }       
3239
3240        /* Get the value */
3241        if ((y = cmtxt(msg, x == TN_ENV_USR ? uidbuf : "", &s, xxstring)) < 0)
3242          return(y);
3243        if ((y = cmcfm()) < 0) return(y);
3244        switch (x) {
3245          case TN_ENV_USR:
3246            strncpy(uidbuf,s,63);
3247            break;
3248          case TN_ENV_ACCT:
3249            strncpy(tn_env_acct,s,63);
3250            break;
3251          case TN_ENV_DISP:
3252            strncpy(tn_env_disp,s,63);
3253            break;
3254          case TN_ENV_JOB:
3255            strncpy(tn_env_job,s,63);
3256            break;
3257          case TN_ENV_PRNT:
3258            strncpy(tn_env_prnt,s,63);
3259            break;
3260          case TN_ENV_SYS:
3261            strncpy(tn_env_sys,s,63);
3262            break;
3263          case TN_ENV_UVAR:
3264            printf("\n?Not yet implemented\n");
3265            break;
3266        }
3267        return(success = 1);
3268        break;
3269    }
3270#endif /* CK_ENVIRONMENT */
3271
3272      default:
3273        return(-2);
3274    }
3275}
3276#endif /* TNCODE */
3277
3278switch (xx) {
3279#ifndef NOSPL
3280case XYCOUN:                            /* SET COUNT */
3281    x = cmnum("Positive number","0",10,&z,xxstring);
3282    if (x < 0) return(x);
3283    if ((x = cmcfm()) < 0) return(x);
3284    if (z < 0) {
3285        printf("?A positive number, please\n");
3286        return(0);
3287    }
3288    debug(F101,"XYCOUN: z","",z);
3289    return(success = setnum(&count[cmdlvl],z,0,10000));
3290#endif /* NOSPL */
3291
3292#ifndef NOSPL
3293case XYCASE:
3294    return(success = seton(&inpcas[cmdlvl]));
3295#endif /* NOSPL */
3296
3297case XYCMD:                             /* COMMAND ... */
3298    if ((y = cmkey(scmdtab,nbytt,"","",xxstring)) < 0) return(y);
3299    switch(y) {
3300      case SCMD_BSZ:
3301        if ((y = cmnum("bytesize for command characters, 7 or 8","7",10,&x,
3302                       xxstring)) < 0)
3303          return(y);
3304        if (x != 7 && x != 8) {
3305            printf("\n?The choices are 7 and 8\n");
3306            return(success = 0);
3307        }
3308        if ((y = cmcfm()) < 0) return(y);
3309        if (x == 7) cmdmsk = 0177;
3310        else if (x == 8) cmdmsk = 0377;
3311        return(success = 1);
3312#ifdef CK_RECALL
3313      case SCMD_RCL:
3314        if ((y = cmnum("maximum number of commands in recall buffer","10",
3315                       10,&x,xxstring)) < 0)
3316          return(y);
3317        if ((y = cmcfm()) < 0) return(y);
3318        return(success = cmrini(x));
3319#endif /* CK_RECALL */
3320#ifdef CK_RECALL
3321      case SCMD_RTR:
3322        return(success = seton(&cm_retry));
3323#endif /* CK_RECALL */
3324      case SCMD_MOR:                    /* More-prompting */
3325        return(success = seton(&xaskmore));
3326      case SCMD_QUO:
3327        if ((x = seton(&y)) < 0) return(x);
3328        cmdsquo(y);                     /* Do it the right way */
3329        cmd_quoting = y;                /* Also keep a global copy */
3330        /* Set string-processing function */
3331#ifdef datageneral
3332        xxstring = y ? zzstring : (xx_strp) NULL;
3333#else
3334#ifdef CK_ANSIC
3335        xxstring = y ? zzstring : (xx_strp) NULL;
3336#else
3337        xxstring = y ? zzstring : NULL;
3338#endif /* CK_ANSIC */
3339#endif /* datageneral */
3340        return(success = 1);
3341
3342#ifdef OS2
3343      case SCMD_COL: {                  /* Command-screen colors */
3344         int fg, bg;
3345         fg = cmkey(ttyclrtab, nclrs,
3346                     "foreground color and then background color",
3347                     "white",
3348                     xxstring);
3349         if (fg < 0)   
3350            return(fg);
3351         if ((bg = cmkey(ttyclrtab,nclrs,
3352                          "background color","black",xxstring)) < 0)
3353            return(bg);
3354         if ((y = cmcfm()) < 0) 
3355            return(y);
3356         colorcmd = fg | bg << 4;   
3357         return(success = 1);
3358      }
3359
3360    case SCMD_SCR:       /* Command Scrollback size */
3361          if ((y = cmnum("COMMAND scrollback buffer size, lines","512",10,&x,
3362                          xxstring)) < 0)
3363            return(y);
3364#ifdef __32BIT__
3365        /* The max number of lines is the RAM  */
3366        /* we can actually dedicate to a       */
3367        /* scrollback buffer given the maximum */
3368        /* process memory space of 512MB       */
3369        if (x < 256 || x > 2000000L) {
3370            printf("\n?The size must be between 256 and 2,000,000.\n");
3371            return(success = 0);
3372        }
3373#else
3374        if (x < 64 || x > 240) {
3375            printf("\n?The size must be between 64 and 240.\n");
3376            return(success = 0);
3377        }
3378#endif /* __32BIT__ */
3379        if ((y = cmcfm()) < 0) return(y);
3380#ifndef VSCRNINIT
3381        if ( (ULONG) x < VscrnGetBufferSize(VCMD) ) {
3382            printf("\nWarning: the scrollback buffer will be emptied on the");
3383            printf(" next CONNECT,\n");
3384            printf("unless the buffer is restored to %d lines.\n",
3385                   VscrnGetBufferSize(VCMD) ) ;
3386        }
3387#endif /* VSCRNINIT */
3388          tt_scrsize[VCMD] = x;
3389#ifdef VSCRNINIT
3390          VscrnInit( VCMD ) ;
3391#endif /* VSCRNINIT */
3392        return(success = 1);
3393
3394          break;
3395
3396      case SCMD_WID: {
3397          if ((y = cmnum("number of columns in display window during CONNECT",
3398                         "80",10,&x,xxstring)) < 0)
3399            return(y);
3400          if ((y = cmcfm()) < 0) return(y);
3401
3402          if (IsOS2FullScreen()) {
3403              if (x != 40 && x != 80 && x != 132) {
3404                  printf("\n?The width must be 40, 80,");
3405#ifdef NT
3406                  printf(" or 132 under Windows 95.\n.");
3407#else /* NT */
3408                  printf(" or 132 in a Full Screen session.\n.");
3409#endif /* NT */
3410                  return(success = 0);
3411              }
3412          } else {
3413              if (!IsWARPed() && x != 80) {
3414                  printf("\n?OS/2 version is pre-WARP: the width must equal ");
3415                  printf("80 in a Windowed Session\n.");
3416                  return(success = 0);
3417              }
3418              if (x < 20 || x > MAXTERMCOL) {
3419                  printf(
3420                      "\n?The width must be between 20 and %d\n.",MAXTERMCOL);
3421                  return(success = 0);
3422              }
3423          }
3424          if (x > 8192/(tt_rows[VCMD]+1)) {
3425              printf(
3426"\n?The max screen area is 8192 cells: %d(rows) x %d(cols) = %d cells.\n",
3427                     tt_rows[VCMD]+1,x,x*(tt_rows[VCMD]+1));
3428              return(success = 0);
3429          }
3430          tt_cols[VCMD] = x;
3431#ifdef VSCRNINIT
3432          VscrnSetWidth(VCMD, x);
3433#else /* VSCRNINIT */
3434          VscrnSetWidth(VCMD, -1);
3435#endif /* VSCRNINIT */
3436          cmd_cols = x;
3437          SetCols(VCMD);
3438          return(success = 1);
3439      }
3440      case SCMD_HIG:
3441        if ((y = cmnum(
3442"number of rows in display window during CONNECT, not incl status line",
3443                       "24",10,&x,xxstring)) < 0)
3444          return(y);
3445          if ((y = cmcfm()) < 0) return(y);
3446
3447        if ( IsOS2FullScreen() ) {
3448            if ( x != 24 && x != 42 && x != 49 && x != 59 ) {
3449                printf("\n?The height must be 24, 42, 49");
3450#ifdef NT
3451                printf(" or 59 under Windows 95.\n.");
3452#else /* NT */
3453                printf(" or 59 in a Full Screen session.\n.");
3454#endif /* NT */
3455                return(success = 0);
3456            }
3457        } else {
3458            if (x < 8 || x > MAXTERMROW ) {
3459                printf("\n?The height must be between 8 and %d\n.",MAXTERMROW);
3460                return(success = 0);
3461            }
3462        }
3463        if (x > 8192/tt_cols[VCMD]) {
3464            printf(
3465"\n?The max screen area is 8192 cells: %d(rows) x %d(cols) = %d cells.\n",
3466                   x,tt_cols[VCMD],x*tt_cols[VCMD]);
3467            return(success = 0);
3468        }
3469#ifdef VSCRNINIT
3470     
3471        tt_szchng[VCMD] = 1;
3472        tt_rows[VCMD] = x;
3473        VscrnInit(VCMD);
3474#else /* VSCRNINIT */
3475        tt_rows[VCMD] = x;
3476        VscrnSetHeight(VCMD, -1);
3477        tt_szchng[VCMD] = 1;
3478#endif /* VSCRNINIT */
3479        SetCols(VCMD);
3480        cmd_rows = x;
3481        return(success = 1);
3482
3483    case SCMD_CUR: {
3484        int row, col;
3485        position * ppos;
3486
3487        ppos = VscrnGetCurPos(VCMD);
3488#ifdef NT
3489#define itoa _itoa
3490#endif
3491        itoa(ppos->y+1, tmpbuf, 10);
3492        if ((y = cmnum("row (1-based)",tmpbuf,10,&row,xxstring)) < 0)
3493          return(y);
3494
3495        itoa(ppos->x+1, tmpbuf, 10);
3496        if ((y = cmnum("col (1-based)",tmpbuf,10,&col,xxstring)) < 0)
3497          return(y);
3498        if ((x = cmcfm()) < 0) return(x);
3499
3500        VscrnSetCurPos( VCMD, col-1, row-1 ) ;
3501        VscrnIsDirty( VCMD );
3502        return(success=1);
3503    }
3504#else
3505      case SCMD_WID:
3506        y = cmnum("Command screen width, characters","80",10,&x,xxstring);
3507        return(setnum(&cmd_cols,x,y,1024));
3508
3509      case SCMD_HIG:
3510        y = cmnum("Command screen height, rows","24",10,&x,xxstring);
3511        return(setnum(&cmd_rows,x,y,1024));
3512#endif /* OS2 */
3513
3514      default:
3515        return(-2);
3516    }
3517}
3518
3519switch (xx) {
3520   
3521case XYDFLT:                            /* SET DEFAULT = CD */
3522    return(success = docd());
3523
3524case XYDEBU:                            /* SET DEBUG { on, off, session } */
3525    if ((y = cmkey(dbgtab,ndbg,"","",xxstring)) < 0) return(y);
3526    if ((x = cmcfm()) < 0) return(x);
3527    switch (y) {
3528      case 0:                           /* 0 = all debugging off. */
3529        debses = 0;
3530#ifdef DEBUG
3531        if (deblog) doclslog(LOGD);
3532#endif /* DEBUG */
3533        return(success = 1);
3534
3535      case 1:                           /* 1 = log debugging to debug.log */
3536#ifdef DEBUG
3537        deblog = debopn("debug.log", 0);
3538        return(success = deblog ? 1 : 0);
3539#else
3540        printf("?Sorry, debug log feature not enabled\n");
3541        return(success = 0);
3542#endif /* DEBUG */
3543
3544      case 2:                           /* 2 = session. */
3545        return(success = debses = 1);
3546    }
3547
3548case XYDELA:                            /* SET DELAY */
3549    y = cmnum("Number of seconds before starting to send","5",10,&x,xxstring);
3550    if (x < 0) x = 0;
3551    return(success = setnum(&delay,x,y,999));
3552
3553default:
3554    break;
3555}
3556
3557switch (xx) {
3558#ifndef NODIAL
3559#ifdef CK_TAPI
3560case XYTAPI:
3561    return(settapi());
3562#endif /* CK_TAPI */
3563case XYDIAL:                            /* SET MODEM or SET DIAL */
3564    return(setdial(-1));
3565case XYMODM:
3566    return(setmodem());
3567#endif /* NODIAL */
3568
3569#ifdef COMMENT                          /* Unused at present */
3570case XYDOUB:
3571    if ((x = cmfld("Character to double","none",&s,xxstring)) < 0) {
3572        if (x == -3) {
3573            dblchar = -1;
3574            if (msgflg) printf("Doubling Off\n");
3575            return(success = 1);
3576        } else return(x);
3577    }
3578    strcpy(line,s);
3579    lp = line;
3580    if ((x = cmcfm()) < 0) return(x);
3581    if (!xxstrcmp(lp,"none",4)) {
3582        dblchar = -1;
3583        if (msgflg) printf("Doubling Off\n");
3584        return(success = 1);
3585    }
3586    if ((int)strlen(lp) != 1) return(-2);
3587    dblchar = *lp & 0xFF;
3588    if (msgflg) printf("Doubled: %d\n",dblchar);
3589    return(success = 1);
3590#endif /* COMMENT */
3591
3592#ifndef NOLOCAL
3593case XYDUPL:                            /* SET DUPLEX */
3594    if ((y = cmkey(dpxtab,2,"","full",xxstring)) < 0) return(y);
3595    if ((x = cmcfm()) < 0) return(x);
3596    duplex = y;
3597    return(success = 1);
3598 
3599case XYLCLE:                            /* LOCAL-ECHO (= DUPLEX) */
3600    return(success = seton(&duplex));
3601
3602case XYESC:                             /* SET ESCAPE */
3603    sprintf(tmpbuf,"%d",DFESC);
3604    return(success = setcc(tmpbuf,&escape));
3605#endif /* NOLOCAL */
3606
3607case XYEXIT:                            /* SET EXIT */
3608    if ((z = cmkey(xittab,nexit,"","",xxstring)) < 0)
3609      return(z);
3610    switch (z) {
3611      case 0:                           /* STATUS */
3612        y = cmnum("EXIT status code","",10,&x,xxstring);
3613        return(success = setnum(&xitsta,x,y,-1));
3614      case 1:                           /* WARNING */
3615        if ((z = cmkey(xitwtab,nexitw,"","",xxstring)) < 0) return(z);
3616        if ((y = cmcfm()) < 0) return(y);
3617        xitwarn = z;
3618        return(success = 1);
3619      case 2:
3620        success = seton(&exitonclose);
3621#ifdef TCPSOCKET
3622        if (success) tn_exit = exitonclose;
3623#endif /* TCPSOCKET */
3624        return(success);
3625      default:
3626        return(-2);
3627    } /* End of SET EXIT switch() */
3628
3629default:
3630    break;
3631}
3632
3633switch (xx) {
3634case XYFILE:                            /* SET FILE */
3635    return(setfil(rmsflg));
3636
3637case XYFLOW:                            /* FLOW-CONTROL */
3638/*
3639  Note: flotab[] keyword table (defined above) only includes the legal
3640  flow-control options for each implementation, controlled by symbols
3641  defined in ckcdeb.h.
3642*/
3643    if ((y = cmkey(flotab,nflo,"","xon/xoff",xxstring)) < 0) return(y);
3644    if ((x = cmcfm()) < 0) return(x);
3645    flow = y;
3646#ifdef CK_SPEED
3647    if (flow == FLO_XONX)               /* Xon/Xoff forces prefixing */
3648      ctlp[XON] = ctlp[XOFF] = ctlp[XON+128] = ctlp[XOFF+128] = 1;
3649#endif /* CK_SPEED */
3650    autoflow = (flow == FLO_AUTO);
3651    debug(F101,"set flow","",flow);
3652    return(success = 1);
3653 
3654case XYHAND:                            /* HANDSHAKE */
3655    if ((y = cmkey(hshtab,nhsh,"","none",xxstring)) < 0) return(y);
3656    if (y == 998) {
3657        if ((x = cmnum("ASCII value","",10,&y,xxstring)) < 0)
3658          return(x);
3659        if ((y < 1) || ((y > 31) && (y != 127))) {
3660            printf("?Character must be in ASCII control range\n");
3661            return(-9);
3662        }
3663    }
3664    if ((x = cmcfm()) < 0) return(x);
3665    turn = (y > 0127) ? 0 : 1 ;
3666    turnch = y;
3667    return(success = 1);
3668 
3669#ifndef NOSPL
3670case XYMACR:                            /* SET MACRO */
3671    if ((y = cmkey(smactab,2,"","",xxstring)) < 0) return(y);
3672    switch (y) {
3673      case 0: return(success = seton(&mecho));
3674      case 1: return(success = seton(&merror[cmdlvl]));
3675      default: return(-2);
3676    }
3677#endif /* NOSPL */
3678
3679  case XYMSGS:
3680#ifdef VMS
3681    if ((z = cmkey(onoff,2,"","",xxstring)) < 0) return(z);
3682    if ((y = cmcfm()) < 0) return(y);
3683    vms_msgs = z;
3684    printf("Sorry, SET MESSAGES not implemented yet\n");
3685    return(success = 0);
3686#endif /* VMS */
3687default:
3688    break;
3689}
3690
3691switch (xx) {
3692       
3693case XYPARI:                            /* PARITY */
3694    if ((y = cmkey(partbl,npar,"","none",xxstring)) < 0) return(y);
3695    if ((x = cmcfm()) < 0) return(x);
3696 
3697/* If parity not none, then we also want 8th-bit prefixing */
3698 
3699    if (parity = y) ebqflg = 1; else ebqflg = 0;
3700    return(success = 1);
3701 
3702#ifndef NOFRILLS
3703case XYPROM:                            /* SET PROMPT */
3704/*
3705  Note: xxstring not invoked here.  Instead, it is invoked every time the
3706  prompt is issued.  This allows the prompt string to contain variables
3707  that can change, like \v(dir), \v(time), etc.
3708*/
3709    if ((x = cmtxt("Program's command prompt",ckprompt,&s,NULL)) < 0)
3710      return(x);
3711    s = brstrip(s);                     /* Remove enclosing braces, if any */
3712#ifdef COMMENT
3713/*
3714  Let's not do this any more -- we don't do it anywhere else.
3715*/
3716    else if (*s == '"') {               /* For compatibility with pre-5A */
3717        x = (int)strlen(s);
3718        if (s[x-1] == '"') {
3719            s[x-1] = NUL;
3720            s++;
3721        }
3722    }
3723#endif /* COMMENT */
3724    cmsetp(s);                          /* Set the prompt */
3725    return(success = 1);
3726#endif /* NOFRILLS */
3727 
3728case XYRETR:                            /* RETRY: per-packet retry limit */
3729    y = cmnum("Maximum retries per packet","10",10,&x,xxstring);
3730    if (x < 0) x = 0;
3731    if ((x = setnum(&maxtry,x,y,999)) < 0) return(x);
3732    if (maxtry <= wslotr) {
3733        printf("?Retry limit must be greater than window size\n");
3734        return(success = 0);
3735    }
3736    sprintf(tmpbuf,"%d",maxtry);
3737    if (rmsflg) {
3738        sstate = setgen('S', "403", tmpbuf, "");
3739        return((int) sstate);
3740    } else return(success = x);
3741 
3742#ifndef NOSERVER
3743case XYSERV:                            /* SET SERVER items */
3744    if ((y = cmkey(srvtab,nsrvt,"","",xxstring)) < 0) return(y);
3745    switch (y) {
3746#ifdef OS2
3747      case XYSERI:
3748        if ((y = cmnum("interval for server idle timeout, 0 = none",
3749                       "0",10,&x,xxstring)) < 0)
3750          return(y);
3751        if (x < 0) {
3752            printf("\n?Specify a positive number, or 0 for no server NAKs\n");
3753          return(0);
3754        }
3755        if ((y = cmcfm()) < 0) return(y);
3756        srvidl = x;             /* Set the server idle timeout variable */
3757        return(success = 1);
3758#endif /* OS2 */
3759      case XYSERT:
3760        tp = tmpbuf;
3761        sprintf(tp,"%d",DSRVTIM);
3762        if ((y = cmnum("interval for server NAKs, 0 = none",tp,10,&x,
3763                       xxstring)) < 0)
3764          return(y);
3765        if (x < 0) {
3766            printf("\n?Specify a positive number, or 0 for no server NAKs\n");
3767            return(0);
3768        }
3769        if ((y = cmcfm()) < 0) return(y);
3770        sprintf(tp,"%d",x);
3771        if (rmsflg) {
3772            sstate = setgen('S', "404", tp, "");
3773            return((int) sstate);
3774        } else {
3775            srvtim = x;                 /* Set the server timeout variable */
3776            return(success = 1);
3777        }
3778      case XYSERD:                      /* SERVER DISPLAY */
3779        return(success = seton(&srvdis)); /* ON or OFF... */
3780
3781      case XYSERP:                      /* SERVER GET-PATH */
3782        return(parsdir(2));
3783
3784      case XYSERL:                      /* SERVER LOGIN */
3785        return(cklogin());
3786
3787      default:
3788        return(-2);
3789    }
3790#endif /* NOSERVER */
3791}
3792
3793switch (xx) {
3794#ifdef UNIX
3795#ifndef NOJC
3796case XYSUSP:                            /* SET SUSPEND */
3797    seton(&suspend);                    /* on or off... */
3798    return(success = 1);
3799#endif /* NOJC */
3800#endif /* UNIX */
3801
3802case XYTAKE:                            /* SET TAKE */
3803    if ((y = cmkey(taktab,4,"","",xxstring)) < 0) return(y);
3804    switch (y) {
3805      case 0: return(success = seton(&techo));
3806#ifndef NOSPL
3807      case 1: return(success = seton(&takerr[cmdlvl]));
3808#else
3809      case 1: return(success = seton(&takerr[tlevel]));
3810#endif /* NOSPL */
3811      case 2: techo = 0; return(success = 1); /* For compatibility with */
3812      case 3: techo = 1; return(success = 1); /* MS-DOS Kermit */
3813      default: return(-2);
3814    }
3815
3816#ifndef NOSCRIPT
3817case XYSCRI:                            /* SET SCRIPT */
3818    if ((y = cmkey(scrtab,1,"","echo",xxstring)) < 0) return(y);
3819    switch (y) {
3820      case 0: return(success = seton(&secho));
3821      default: return(-2);
3822    }
3823#endif /* NOSCRIPT */
3824
3825default:
3826    break;
3827}
3828
3829#ifndef NOLOCAL
3830switch (xx) {
3831case XYTERM:                            /* SET TERMINAL */
3832    x = settrm();
3833    success = (x > 0) ? 1 : 0;
3834    return(x);
3835
3836#ifdef NT
3837case XYWIN95:                           /* SET WIN95 workarounds */
3838    x = setwin95();
3839    success = (x > 0 ? 1 : 0);
3840    return(x);
3841#endif /* NT */
3842
3843#ifdef OS2     
3844case XYDLR:                             /* SET DIALER workarounds */
3845    x = setdialer();
3846    success = (x > 0 ? 1 : 0);
3847    return(x);
3848
3849case XYTITLE:                           /* SET TITLE of window */
3850    x = settitle();
3851    success = (x > 0 ? 1 : 0);
3852    return(x);
3853#endif /* OS2 */
3854
3855#ifdef OS2MOUSE
3856case XYMOUSE:                           /* SET MOUSE */
3857    return(success = setmou());
3858#endif /* OS2MOUSE */
3859
3860#ifdef OS2
3861case XYBELL:                            /* SET BELL */
3862    return( success = setbell() );
3863
3864case XYPRTY:
3865    return( success = setprty() );
3866#endif /* OS2 */
3867
3868default:
3869    break;
3870}
3871#endif /* NOLOCAL */
3872
3873switch (xx) {
3874
3875/* SET SEND/RECEIVE protocol parameters. */
3876 
3877case XYRECV:
3878case XYSEND:
3879    return(setsr(xx,rmsflg));
3880 
3881#ifndef NOLOCAL                         /* Session log text/binary selection */
3882#ifdef UNIX                             /* UNIX needs it */
3883#define _XYSESS
3884#endif /* UNIX */
3885#ifdef OSK                              /* OS-9 too */
3886#define _XYSESS
3887#endif /* OSK */
3888
3889#ifdef _XYSESS
3890case XYSESS:                            /* SESSION-LOG */
3891    if ((x = cmkey(sfttab,nsfttab,"type of file","text",xxstring)) < 0)
3892      return(x);
3893    if ((y = cmcfm()) < 0) return(y);
3894    sessft = x;
3895    return(success = 1);
3896#undef _XYSESS
3897#endif /* _XYSESS */
3898
3899case XYSPEE:                            /* SET SPEED */
3900    if (network) {
3901        printf("\n?Speed cannot be set for network connections\n");
3902        return(success = 0);
3903    }
3904    lp = line;
3905    sprintf(lp,"Transmission rate for %s in bits per second",ttname);
3906
3907    if ((x = cmkey(spdtab,nspd,line,"",xxstring)) < 0) {
3908        if (x == -3) printf("?value required\n");
3909        return(x);
3910    }
3911    if ((y = cmcfm()) < 0) return(y);
3912    if (!local) {
3913        printf("?Sorry, you must SET LINE first\n");
3914        return(success = 0);
3915    }
3916    zz = (long) x * 10L;
3917    if (zz == 70) zz = 75;              /* (see spdtab[] definition) */
3918    if (ttsspd(x) < 0)  {               /* Call ttsspd with cps, not bps! */
3919        printf("?Unsupported line speed - %ld\n",zz);
3920        return(success = 0);
3921    } else {
3922        speed = ttgspd();               /* Read it back */
3923        if (speed != zz)  {             /* Call ttsspd with cps, not bps! */
3924            printf("?SET SPEED fails, speed is %ld\n",speed);
3925            return(success = 0);
3926        }
3927        if (pflag &&
3928#ifndef NOSPL
3929            cmdlvl == 0
3930#else
3931            tlevel < 0
3932#endif /* NOSPL */
3933            ) {
3934            if (speed == 8880)
3935              printf("%s, 75/1200 bps\n",ttname);
3936            else
3937              printf("%s, %ld bps\n",ttname,speed);
3938        }
3939        return(success = 1);
3940    }
3941#endif /* NOLOCAL */
3942 
3943  case XYXFER:                          /* SET TRANSFER */
3944    if ((y = cmkey(tstab,nts,"","character-set",xxstring)) < 0) return(y);
3945    switch (y) {
3946#ifdef XFRCAN
3947      case XYX_CAN:                     /* CANCELLATION */
3948        if ((z = cmkey(onoff,2,"","",xxstring)) < 0) return(z);
3949        if (z == 0) {                   /* OFF */
3950            if ((y = cmcfm()) < 0) return(y);
3951            xfrcan = 0;
3952        } else {
3953            if ((y = cmnum("ASCII code for cancellation character","3",10,&x,
3954                           xxstring)) < 0)
3955              return(y);
3956            if (x > 31 && x != 127) {
3957                printf("Cancel character must be in ASCII control range\n");
3958                return(-9);
3959            }
3960            if ((y = cmnum("How many required to cause cancellation",
3961                           "2",10,&z, xxstring)) < 0)
3962              return(y);
3963            if (z < 2) {
3964                printf("Number must be 2 or greater\n");
3965                return(-9);
3966            }
3967            if ((y = cmcfm()) < 0) return(y);
3968            xfrcan = 1;                 /* CANCELLATION ON */
3969            xfrchr = x;                 /* Using this character */
3970            xfrnum = z;                 /* Needing this many of them */
3971        }
3972        return(success = 1);
3973#endif /* XFRCAN */
3974#ifndef NOCSETS
3975      case XYX_CSE:                     /* CHARACTER-SET */
3976        if ((y = cmkey(tcstab,ntcs,"","transparent",xxstring)) < 0) return(y);
3977        if ((x = cmcfm()) < 0) return(x);
3978        if (rmsflg) {
3979            sstate = setgen('S', "405", tcsinfo[y].designator, "");
3980            return((int) sstate);
3981        } else {
3982            tslevel = (y == TC_TRANSP) ? 0 : 1; /* transfer syntax level */
3983            tcharset = y;               /* transfer character set */
3984            return(success = 1);
3985        }
3986#endif /* NOCSETS */
3987      case XYX_LSH:                     /* LOCKING-SHIFT */
3988          if ((y = cmkey(lstab,nls,"","on",xxstring)) < 0)
3989            return(y);
3990          if ((x = cmcfm()) < 0) return(x);
3991          lscapr = (y == 1) ? 1 : 0;    /* ON: requested = 1 */
3992          lscapu = (y == 2) ? 2 : 0;    /* FORCED:  used = 1 */
3993          return(success = 1);
3994#ifdef CK_XYZ   
3995      case XYX_PRO:                     /* Protocol */
3996        return(setproto());
3997#endif /* CK_XYZ */
3998
3999      case XYX_MOD:                     /* Mode */
4000        if ((y = cmkey(xfrmtab,2,"","automatic",xxstring)) < 0)
4001          return(y);
4002        if ((x = cmcfm()) < 0) return(x);       
4003        xfermode = y;
4004        return(success = 1);
4005
4006      case XYX_DIS:                     /* Display */
4007        return(doxdis());
4008
4009      case XYX_SLO:                     /* Slow-start */
4010        return(seton(&slostart));
4011
4012#ifndef NOSPL
4013      case XYX_CRC:                     /* CRC */
4014        return(seton(&docrc));
4015#endif /* NOSPL */
4016
4017      case XYX_BEL:                     /* Bell */
4018        return(seton(&xfrbel));
4019
4020      default:
4021        return(-2);
4022    }
4023}
4024
4025switch (xx) {
4026
4027#ifndef NOXMIT
4028  case XYXMIT:                          /* SET TRANSMIT */
4029    return(setxmit());
4030#endif /* NOXMIT */
4031
4032#ifndef NOCSETS
4033  case XYUNCS:                          /* UNKNOWN-CHARACTER-SET */
4034    if ((y = cmkey(ifdtab,2,"","discard",xxstring)) < 0) return(y);
4035    if ((x = cmcfm()) < 0) return(x);
4036    unkcs = y;
4037    return(success = 1);
4038#endif /* NOCSETS */
4039
4040#ifndef NOPUSH
4041#ifdef UNIX
4042case XYWILD:                            /* WILDCARD-EXPANSION */
4043    if (nopush) {
4044        if ((x = cmcfm()) < 0) return(x);
4045        printf("Wildcard expansion is disabled\n");
4046        return(success = 0);
4047    }
4048    if ((y = cmkey(wildtab,2,"who expands wildcards","kermit",xxstring)) < 0)
4049      return(y);
4050    if ((x = cmcfm()) < 0) return(x);
4051    wildxpand = y;
4052    return(success = 1);
4053#endif /* UNIX */
4054#endif /* NOPUSH */
4055
4056  case XYWIND:                          /* WINDOW-SLOTS */
4057    if (protocol == PROTO_K) {
4058        y = cmnum("Number of sliding-window slots, 1 to 32",
4059                  "1", 10, &x, xxstring);
4060        y = setnum(&z,x,y,MAXWS);
4061    } else {
4062        y = cmnum("Window size for current protocol", "" ,10, &x, xxstring);
4063        y = setnum(&z,x,y,65472);
4064    }
4065    if (y < 0) return(y);
4066    if (protocol == PROTO_K)
4067      if (z < 1)
4068        z = 1;
4069#ifdef CK_XYZ
4070    if (protocol == PROTO_Z)            /* Must be a multiple of 64 */
4071      z = (z >> 6) << 6;
4072#endif /* CK_XYZ */
4073
4074#ifdef COMMENT
4075    /* This is taken care of automatically now in protocol negotiation */
4076    if (maxtry < z) {
4077        printf("?Window slots must be less than retry limit\n");
4078        return(success = 0);
4079    }
4080#endif /* COMMENT */
4081    if (protocol == PROTO_K && rmsflg) { /* Set remote window size */
4082        wslotr = z;                     /* Set local window size too */
4083        ptab[protocol].winsize = wslotr;
4084        tp = tmpbuf;
4085        sprintf(tp,"%d",z);
4086        sstate = setgen('S', "406", tp, "");
4087        return((int) sstate);
4088    }
4089    wslotr = z;                         /* Set local window size */
4090    ptab[protocol].winsize = wslotr;
4091    swcapr = (wslotr > 1) ? 1 : 0;      /* Set window bit in capas word? */
4092    if (wslotr > 1) {                   /* Window size > 1? */
4093        y = adjpkl(urpsiz,wslotr,bigrbsiz); /* Maybe adjust packet size */
4094        if (y != urpsiz) {              /* Did it change? */
4095            urpsiz = y;
4096            if (msgflg)
4097            printf(
4098" Adjusting receive packet-length to %d for %d window slots\n",
4099                   urpsiz, wslotr);
4100        }
4101    }
4102    return(success = 1);
4103}
4104
4105switch (xx) {
4106
4107#ifndef NOSPL
4108  case XYOUTP:                          /* OUTPUT command parameters */
4109    if ((y = cmkey(outptab,1,"OUTPUT command parameter","pacing",
4110                   xxstring)) < 0)
4111      return(y);
4112    switch(y) {                         /* Which parameter */
4113      case 0:                           /* PACING */
4114        y = cmnum("Milliseconds to pause between each OUTPUT character","100",
4115                  10,&x,xxstring);
4116        y = setnum(&z,x,y,16383);       /* Verify and get confirmation */
4117        if (y < 0) return(y);
4118        if (z < 0) z = 0;               /* (save some space) */
4119        pacing = z;
4120        return(success = 1);   
4121      default:                          /* (shouldn't happen) */
4122        return(-2);
4123    }
4124#endif /* NOSPL */
4125
4126#ifdef CK_SPEED
4127  case XYQCTL: {
4128    short *p;
4129    int zz;
4130    if ((z = cmkey(ctltab,2, "control-character prefixing option",""
4131                   ,xxstring)) < 0)
4132      return(z);
4133    /* Make space for a temporary copy of the prefixing table */
4134
4135    p = (short *)malloc(256 * sizeof(short));
4136    if (!p) {
4137        printf("?Internal error - malloc failure\n");
4138        return(-9);
4139    }
4140    for (i = 0; i < 256; i++) p[i] = ctlp[i]; /* Copy current table */
4141
4142    switch(z) {
4143      case 0:                           /* UNPREFIXED control character */
4144      case 1:                           /* PREFIXED control character */
4145        while (1) {                     /* Collect a list of numbers */
4146#ifndef NOSPL
4147            x_ifnum = 1;                /* Turn off complaints from eval() */
4148#endif /* NOSPL */
4149            if ((x = cmnum((z == 0) ?
4150"\n Numeric ASCII value of control character that needs NO prefix,\n\
4151 or the word \"all\", or carriage return to complete the list" :
4152"\n Numeric ASCII value of control character that MUST BE prefixed,\n\
4153 or the word \"all\", or carriage return to complete the list",
4154                           "",10,&y,xxstring
4155                           )) < 0) {
4156#ifndef NOSPL
4157                x_ifnum = 0;
4158#endif /* NOSPL */
4159                if (x == -3)
4160                  break;
4161                if (x == -2) {
4162                    if (p) { free(p); p = NULL; }
4163                    debug(F110,"SET CONTROL atmbuf",atmbuf,0);
4164                    if (!xxstrcmp(atmbuf,"all",3) ||
4165                        !xxstrcmp(atmbuf,"al",2) ||
4166                        !xxstrcmp(atmbuf,"a",1)) {
4167                        if ((x = cmcfm()) < 0) /* Get confirmation */
4168                          return(x);
4169                        /* Set all values, but don't touch 0 */
4170                        for (y = 1; y < 32; y++) ctlp[y] = (short) z;
4171                        for (y = 127; y < 160; y++) ctlp[y] = (short) z;
4172                        ctlp[255] = (short) z;
4173                        /* Watch out for XON and XOFF */
4174                        if (flow == FLO_XONX && z == 0) {
4175                            if (msgflg) {
4176                                printf(
4177" XON/XOFF characters 17, 19, 145, 147 not affected.\n");
4178                                printf(
4179#ifdef CK_RTSCTS
4180" SET FLOW NONE or RTS/CTS to transmit these characters unprefixed.\n"
4181#else
4182" SET FLOW NONE to transmit these characters unprefixed.\n"
4183#endif /* CK_RTSCTS */
4184                                       );
4185                            }
4186                            ctlp[XON] =
4187                              ctlp[XOFF] =
4188                                ctlp[XON+128] =
4189                                  ctlp[XOFF+128] = 1;
4190                        }
4191#ifdef TNCODE
4192                        /* Watch out for TELNET IAC */
4193                        if (network && (ttnproto == NP_TELNET) && z == 0) {
4194                            ctlp[255] = 1;
4195                            if (parity == 'e' || parity == 'm') ctlp[127] = 1;
4196                            ctlp[13] = 1;
4197                            if (msgflg)
4198                              printf(
4199                               " TELNET IAC = 255, CR = 13, not affected.\n");
4200                        }
4201#endif /* TNCODE */
4202                        return(success = 1);
4203                    } else {
4204                        printf("?Please specify a number or the word ALL\n");
4205                        return(-9);
4206                    }
4207                } else {
4208                    if (p) free(p);
4209                    return(x);
4210                }
4211            }
4212#ifndef NOSPL
4213            x_ifnum = 0;
4214#endif /* NOSPL */
4215            zz = 1 - z;
4216            if ((y >  31 && y < 127) || /* A specific numeric value */
4217                (y > 159 && y < 255) || /* Check that it is a valid */
4218                (y < zz) ||             /* control code. */
4219                (y > 255)) {
4220                printf("?Values allowed are: %d-31, 127-159, 255\n",zz);
4221                if (p) free(p);
4222                return(-9);
4223            }
4224            x = y & 127;                /* Get 7-bit value */
4225            if ((z == 0) &&             /* If they are saying it is safe... */
4226                (y == 0 ||              /* NUL = string terminator isn't */
4227                 ((flow == FLO_XONX) && /* If flow control is Xon/Xoff */
4228                  (x == XON || x == XOFF)) /* XON & XOFF chars not safe. */
4229                 )) {
4230                if (msgflg)
4231                  printf("Sorry, not while Xon/Xoff is in effect.\n");
4232                if (p) free(p);
4233                return(-9);
4234            }
4235            p[y] = (char) z;            /* All OK, set flag */
4236        }                               /* End of while loop */
4237/*
4238  Get here only if they have made no mistakes.  Copy temporary table back to
4239  permanent one, then free temporary table and return successfully.
4240*/
4241        for (i = 0; i < 256; i++) ctlp[i] = p[i];
4242        if (p) free(p);
4243        return(success = 1);
4244      default:
4245        return(-2);
4246    }
4247  }
4248#endif /* CK_SPEED */
4249}
4250
4251switch (xx) {
4252
4253  case XYREPT:
4254    if ((y = cmkey(rpttab,2,"repeat-count compression parameter","",xxstring))
4255        < 0)
4256      return(y);
4257    switch(y) {
4258      case 0:
4259        return(success = seton(&rptena)); /* REPEAT COUNTS = ON, OFF */
4260      case 1:                           /* REPEAT MININUM number */
4261        printf("(not implemented yet, nothing happens)\n");
4262        return(-9);
4263      case 2:                           /* REPEAT PREFIX char */
4264        if ((x = cmnum("ASCII value","",10,&z,xxstring)) < 0)
4265          return(x);
4266        if ((x = cmcfm()) < 0) return(x);
4267        if ((z > 32 && z < 63) || (z > 95 && z < 127)) {
4268            if (y == 1) rptmin = (CHAR) z; else myrptq = (CHAR) z;
4269            return(success = 1);
4270        } else {
4271            printf("?Illegal value for prefix character\n");
4272            return(-9);
4273        }
4274    }
4275
4276#ifndef NOSPL
4277  case XYALRM: {
4278#ifndef COMMENT
4279      long zz;
4280      zz = -1L;
4281      x_ifnum = 1;                      /* Turn off internal complaints */
4282      y = cmnum("Seconds from now, or time of day as hh:mm:ss",
4283                "0" ,10, &x, xxstring);
4284      if (y < 0) {
4285          if (y == -2) {                /* Invalid number or expression */
4286              zz = tod2sec(atmbuf);     /* Convert to secs since midnight */
4287              if (zz < 0L) {
4288                  printf("?Number, expression, or time of day required\n");
4289                  return(-9);
4290              } else {
4291                  char now[32];         /* Current time */
4292                  char *p;
4293                  long tnow;
4294                  p = now;
4295                  ztime(&p);
4296                  tnow = atol(p+11) * 3600L + atol(p+14) * 60L + atol(p+17);
4297                  if (zz < tnow)        /* User's time before now */
4298                    zz += 86400L;       /* So make it tomorrow */
4299                  zz -= tnow;           /* Seconds from now. */
4300              }
4301          } else
4302            return(y);
4303      }
4304      if (x < 0) x = 0;
4305      if ((y = cmcfm()) < 0) return(y);
4306      if (zz > -1L) {                   /* Time of day given? */
4307          x = zz;
4308          if (zz != (long) x) {
4309              printf(
4310"Sorry, arithmetic overflow - hh:mm:ss not usable on this platform.\n"
4311                     );
4312              return(-9);
4313          }
4314      }
4315      return(setalarm((long)x));
4316  }
4317#else
4318/*
4319  This is to allow long values where int and long are not the same, e.g.
4320  on 16-bit systems.  But something is wrong with it.
4321*/
4322    if ((y = cmtxt("seconds from now", "0", &s, xxstring)) < 0)
4323      return(y);
4324    if (rdigits(s)) {
4325        return(setalarm(atol(s)));
4326    } else {
4327        printf("%s - not a number\n",s);
4328        return(-9);
4329    }
4330#endif /* COMMENT */
4331#endif /* NOSPL */
4332
4333case XYPROTO:
4334    return(setproto());
4335
4336#ifdef CK_SPEED
4337case XYPREFIX:   
4338    if ((z = cmkey(pfxtab, 4, "control-character prefixing option",
4339                   "", xxstring)) < 0) 
4340      return(z);
4341    if ((x = cmcfm()) < 0) return(x);
4342    setprefix(z);
4343    return(success = 1);
4344#endif /* CK_SPEED */
4345
4346#ifndef NOSPL
4347case XYLOGIN:
4348    if ((z = cmkey(logintab, 3, "value for login script","userid",
4349                   xxstring)) < 0) 
4350      return(z);
4351    x = cmdgquo();
4352    cmdsquo(0);
4353    if ((y = cmtxt("text", /* z == LOGI_UID ? uidbuf : */ "", &s, NULL)) < 0) {
4354        cmdsquo(x);
4355        return(y);
4356    }
4357    cmdsquo(x);
4358    if ((int)strlen(s) > 63) {
4359        printf("Sorry, too long\n");
4360        return(-9);
4361    }
4362    switch(z) {
4363      case LOGI_UID:
4364        strcpy(uidbuf,s);
4365        break;
4366      case LOGI_PSW:
4367        strcpy(pwbuf,s);
4368        break;
4369      case LOGI_PRM:
4370        strcpy(prmbuf,s);
4371    }
4372    return(success = 1);
4373#endif /* NOSPL */
4374}
4375
4376switch (xx) {
4377
4378#ifndef NOSPL
4379  case XYSTARTUP:
4380    if ((y = cmkey(ifdtab,2,"","discard",xxstring)) < 0) return(y);
4381    if ((x = cmcfm()) < 0) return(x);
4382    DeleteStartupFile = (y != 0) ? 0 : 1;
4383    return(success = 1);
4384#endif /* NOSPL */
4385
4386case XYTMPDIR:
4387    x = cmdir("Name of temporary directory","",&s,xxstring);
4388    if (x == -3)
4389      s = "";
4390    else if (x < 0)
4391      return(x);
4392    if ((x = cmcfm()) < 0) return(x);
4393    makestr(&tempdir,s);
4394    return(tempdir ? 1 : 0);
4395
4396case XYDEST:                            /* DESTINATION */
4397    return(setdest());
4398
4399default:
4400    if ((x = cmcfm()) < 0) return(x);
4401    printf("Not implemented - %s\n",cmdbuf);
4402    return(success = 0);
4403    }
4404}
4405
4406#ifdef CK_TTYFD
4407extern int ttyfd;
4408#endif /* CK_TTYFD */
4409
4410/*
4411  H U P O K  --  Is Hangup OK?
4412
4413  Issues a warning and gets OK from user depending on whether a connection
4414  seems to be open and what the SET EXIT WARNING setting is.  Returns:
4415    0 if not OK to hang up or exit (i.e. user said No);
4416    nonzero if OK. 
4417  Argument x is used to differentiate the EXIT command from SET LINE / HOST.
4418*/
4419int
4420hupok(x) int x; {                       /* Returns 1 if OK, 0 if not OK */
4421    int y, z = 1;
4422
4423#ifdef VMS
4424    extern int batch;
4425    if (batch) return(1);
4426#endif /* VMS */
4427
4428    debug(F101,"hupok x","",x);
4429    debug(F101,"hupok xitwarn","",xitwarn);
4430    debug(F101,"hupok network","",network);
4431#ifdef CK_TTYFD
4432    debug(F101,"hupok ttyfd","",ttyfd);
4433#endif /* CK_TTYFD */
4434
4435    if ((local && xitwarn) ||           /* Is a connection open? */
4436        (!x && xitwarn == 2)) {         /* Or Always give warning on EXIT */
4437        int needwarn = 0;
4438
4439        if (
4440#ifdef NETCONN
4441            network
4442#else
4443            0
4444#endif /* NETCONN */
4445            ) {         /* Network? */
4446            if (
4447#ifdef CK_TTYFD
4448                ttyfd > -1 &&
4449#endif /* CK_TTYFD */
4450                ttchk() >= 0
4451                )
4452              needwarn = 1;
4453            if (needwarn) {
4454                if (strcmp(ttname,"*"))
4455                  printf(
4456" A network connection to %s might still be active.\n",
4457                         ttname
4458                         );
4459                else
4460                  printf(
4461                   " An incoming network connection might still be active.\n"
4462                         );
4463            }
4464        } else {                        /* Serial connection */
4465            if (carrier == CAR_OFF)     /* SET CARRIER OFF */
4466              needwarn = 0;             /* so we don't care about carrier. */
4467            else if ((y = ttgmdm()) >= 0) /* else, get modem signals */
4468              needwarn = (y & BM_DCD);  /* Check for carrier */
4469            else                        /* If we can't get modem signals... */
4470              needwarn =
4471#ifdef CK_TTYFD
4472                (ttyfd > -1)            /* check tty file descriptor */
4473#else
4474                  1                     /* or can't check ttyfd, then warn */
4475#endif /* CK_TTYFD */
4476                    ;
4477            if (needwarn)
4478              printf(
4479                     " A serial connection might still be active on %s.\n",
4480                     ttname
4481                     );
4482        }
4483
4484/* If a warning was issued, get user's permission to EXIT. */
4485
4486        if (needwarn || !x && xitwarn == 2 && local) {
4487            z = getyesno(x ? "OK to close? " : "OK to exit? ");
4488            if (z < -3) z = 0;
4489        }
4490    }
4491    return(z);
4492}
4493
4494VOID
4495shoctl() {                              /* SHOW CONTROL-PREFIXING */
4496#ifdef CK_SPEED
4497    int i;
4498    printf(
4499"\ncontrol quote = %d, applied to (0 = unprefixed, 1 = prefixed):\n\n",
4500           myctlq);
4501    for (i = 0; i < 16; i++) {
4502        printf("  %3d: %d   %3d: %d ",i,ctlp[i], i+16, ctlp[i+16]);
4503        if (i == 15)
4504          printf("  127: %d",ctlp[127]);
4505        else
4506          printf("        ");
4507        printf("  %3d: %d   %3d: %d ",i+128,ctlp[i+128], i+144, ctlp[i+144]);
4508        if (i == 15)  printf("  255: %d",ctlp[255]);
4509        printf("\n");
4510    }
4511    printf("\n");
4512#endif /* CK_SPEED */
4513}
4514
4515#ifndef NOPUSH
4516#ifdef CK_REXX
4517/*
4518  Rexx command.  Note, this is not OS/2-specific, because Rexx also runs
4519  on other systems where C-Kermit also runs, like the Amiga.
4520*/
4521#define REXBUFL 100                     /* Change this if neccessary */
4522char rexxbuf[REXBUFL] = { '\0' };       /* Rexx's return value (string) */
4523
4524int
4525dorexx() {
4526    int x, y;
4527    char *rexxcmd;
4528
4529        if ((x = cmtxt("Rexx command","",&rexxcmd,xxstring)) < 0)   
4530          return(x);
4531        strcpy(line,rexxcmd);
4532        rexxcmd = line;
4533#ifdef OS2
4534        return(os2rexx(rexxcmd,rexxbuf,REXBUFL));
4535#else /* !OS2 */
4536        printf("Sorry, nothing happens.\n");
4537        return(success = 0);
4538#endif /* OS2 */
4539}
4540#endif /* CK_REXX */
4541#endif /* NOPUSH */
4542#endif /* NOICP */
Note: See TracBrowser for help on using the repository browser.