home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / ckv192.zip / ckuus7.c < prev    next >
C/C++ Source or Header  |  1996-12-28  |  165KB  |  6,060 lines

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