home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / old / ckermit5a190 / ckuus3.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  59KB  |  2,217 lines

  1. #include "ckcsym.h"            /* Symbol definitions */
  2. #ifndef NOICP
  3.  
  4. /*  C K U U S 3 --  "User Interface" for Unix Kermit, part 3  */
  5.  
  6. /*
  7.   Author: Frank da Cruz (fdc@columbia.edu, FDCCU@CUVMA.BITNET),
  8.   Columbia University Academic Information Systems, New York City.
  9.  
  10.   Copyright (C) 1985, 1994, Trustees of Columbia University in the City of New
  11.   York.  The C-Kermit software may not be, in whole or in part, licensed or
  12.   sold for profit as a software product itself, nor may it be included in or
  13.   distributed with commercial products or otherwise distributed by commercial
  14.   concerns to their clients or customers without written permission of the
  15.   Office of Kermit Development and Distribution, Columbia University.  This
  16.   copyright notice must not be removed, altered, or obscured.
  17. */
  18.  
  19. /*  SET command (but much material has been split off into ckuus7.c). */
  20.  
  21. /*
  22.   Kermit-specific includes.
  23.   Definitions here supersede those from system include files.
  24. */
  25. #include "ckcdeb.h"            /* Debugging & compiler things */
  26. #include "ckcasc.h"            /* ASCII character symbols */
  27. #include "ckcker.h"            /* Kermit application definitions */
  28. #include "ckcxla.h"            /* Character set translation */
  29. #include "ckcnet.h"            /* Network symbols */
  30. #include "ckuusr.h"            /* User interface symbols */
  31. #ifdef OS2
  32. #ifdef CK_NETBIOS
  33. #include <os2.h>
  34. #ifdef COMMENT                /* Would you believe */
  35. #undef COMMENT                /* <os2.h> defines this ? */
  36. #endif /* COMMENT */
  37. #include "ckonbi.h"
  38. extern UCHAR NetBiosAdapter ;
  39. #endif /* CK_NETBIOS */
  40. #endif /* OS2 */
  41.  
  42. /* Variables */
  43.  
  44. extern xx_strp xxstring;
  45.  
  46. extern int size, spsiz, spmax, urpsiz, srvtim, 
  47.   local, server, success,
  48.   flow, binary, delay, parity, escape, what, srvdis,
  49.   turn, duplex, backgrd,
  50.   turnch, bctr, mdmtyp, keep, maxtry, unkcs, network,
  51.   ebqflg, quiet, swcapr, nettype,
  52.   wslotr, lscapr, lscapu,
  53.   carrier, debses,
  54.   cdtimo, nlangs, bgset, pflag, msgflg, dblchar,
  55.   cmdmsk, spsizr, wildxpand, suspend,
  56.   techo, rptena, rptmin,
  57.   xfrcan, xfrchr, xfrnum, pacing, xitwarn, xitsta,
  58.   cmd_cols, cmd_rows, ckxech;
  59.  
  60. #ifndef NOKVERBS
  61. extern int nkverbs;
  62. extern struct keytab kverbs[];
  63. #endif /* NOKVERBS */
  64.  
  65. #ifdef CM_RETRY
  66. extern int cm_retry;
  67. #endif /* CM_RETRY */
  68.  
  69. #ifdef TNCODE
  70.   extern int ttnproto;
  71. #endif /* TNCODE */
  72.  
  73. extern char *ccntab[];            /* Names of control chars */
  74. #ifdef CK_SPEED
  75. extern short ctlp[];            /* Control-prefix table */
  76. #endif /* CK_SPEED */
  77.  
  78. #ifndef NOSCRIPT
  79. extern int secho;            /* Whether SCRIPT cmd should echo */
  80. #endif /* NOSCRIPT */
  81.  
  82. #ifdef DCMDBUF
  83. extern char *atmbuf, *atxbuf;
  84. #else
  85. extern char atmbuf[], atxbuf[];
  86. #endif /* DCMDBUF */
  87.  
  88. extern char psave[];
  89.  
  90. #ifndef NOSPL
  91. #ifdef DCMDBUF
  92. extern int *count, *takerr, *merror, *inpcas;
  93. #else
  94. extern int count[], takerr[], merror[], inpcas[];
  95. #endif /* DCMDBUF */
  96. extern int mecho;            /* Macro echo */
  97. #else
  98. extern int takerr[];
  99. #endif /* NOSPL */
  100.  
  101. extern int bigsbsiz, bigrbsiz;        /* Packet buffers */
  102.  
  103. extern long speed;            /* Terminal speed */
  104.  
  105. extern CHAR sstate;            /* Protocol start state */
  106. extern CHAR myctlq;            /* Control-character prefix */
  107. extern CHAR myrptq;            /* Repeat-count prefix */
  108. extern CHAR mystch, seol;        /* Packet start and end chars */
  109. extern char ttname[];            /* Communication device name */
  110. extern char myhost[] ;
  111.  
  112. #ifndef NOSETKEY
  113. extern KEY *keymap;            /* Character map for SET KEY (1:1)  */
  114. extern MACRO *macrotab;            /* Macro map for SET KEY (1:string) */
  115. #ifdef OS2
  116. int wideresult;              /* for SET KEY, wide OS/2 scan codes */
  117. char * printfile = NULL;        /* NULL if printer not redirected */
  118. #endif /* OS2 */
  119. #endif /* NOSETKEY */
  120.  
  121. #ifdef OS2
  122. extern int tcp_avail;            /* Nonzero if TCP/IP is available */
  123. extern int dnet_avail;            /* Ditto for DECnet */
  124. #endif /* OS2 */
  125.  
  126. #ifndef NOCSETS
  127. /* system-independent character sets, defined in ckcxla.[ch] */
  128. extern struct csinfo tcsinfo[];
  129. extern struct langinfo langs[];
  130.  
  131. /* Other character-set related variables */
  132. extern int tcharset, tslevel, language;
  133. #endif /* NOCSETS */ 
  134.  
  135. /* Declarations from cmd package */
  136.  
  137. #ifdef DCMDBUF
  138. extern char *cmdbuf;            /* Command buffer */
  139. extern char *line;
  140. extern char *tmpbuf;
  141. #else
  142. extern char cmdbuf[];            /* Command buffer */
  143. extern char line[];            /* Character buffer for anything */
  144. extern char tmpbuf[];
  145. #endif /* DCMDBUF */
  146.  
  147. /* From main ckuser module... */
  148.  
  149. extern char *tp, *lp;            /* Temporary buffer */
  150.  
  151. extern int tlevel;            /* Take Command file level */
  152.  
  153. #ifndef NOSPL
  154. extern int cmdlvl;            /* Overall command level */
  155. #endif /* NOSPL */
  156.  
  157. #ifndef NOLOCAL
  158. #ifdef UNIX
  159. extern int sessft;            /* Session-log file type */
  160. #endif /* UNIX */
  161. #endif /* NOLOCAL */
  162.  
  163. #ifdef VMS
  164. int vms_msgs = 1;            /* SET MESSAGES */
  165. #endif /* VMS */
  166.  
  167. /* Keyword tables for SET commands */
  168.  
  169. #ifdef CK_SPEED
  170. struct keytab ctltab[] = {
  171.     "prefixed",   1, 0,            /* Note, the values are important. */
  172.     "unprefixed", 0, 0
  173. };
  174. #endif /* CK_SPEED */
  175.  
  176. #ifndef NOSPL
  177. struct keytab outptab[] = {        /* SET OUTPUT parameters */
  178.     "pacing", 0, 0            /* only one so far... */
  179. };
  180. #endif /* NOSPL */
  181.  
  182. struct keytab chktab[] = {        /* Block check types */
  183.     "1", 1, 0,                /* 1 =  6-bit checksum */
  184.     "2", 2, 0,                /* 2 = 12-bit checksum */
  185.     "3", 3, 0,                /* 3 = 16-bit CRC */
  186.     "blank-free-2", 4, 0        /* B = 12-bit checksum, no blanks */
  187. };
  188.  
  189. struct keytab rpttab[] = {        /* SET REPEAT */
  190.     "counts",    0, 0,            /* On or Off */
  191. #ifdef COMMENT
  192.     "minimum",   1, 0,            /* Threshhold */
  193. #endif /* COMMENT */
  194.     "prefix",    2, 0            /* Repeate-prefix character value */
  195. };
  196.  
  197. #ifndef NOLOCAL
  198. /* For SET CARRIER */
  199.  
  200. struct keytab crrtab[] = {
  201.     "auto", CAR_AUT, 0,
  202.     "off",  CAR_OFF, 0,
  203.     "on",   CAR_ON, 0
  204. };
  205. int ncrr = 3;
  206. #endif /* NOLOCAL */
  207.  
  208. /* For SET DEBUG */
  209.  
  210. struct keytab dbgtab[] = {
  211.     "off",     0,  0,
  212.     "on",      1,  0,
  213.     "session", 2,  0
  214. };
  215. int ndbg = 3;
  216.  
  217. #ifndef NOLOCAL
  218. /* Transmission speeds */
  219.  
  220. /*
  221.   Note, the values are encoded in cps rather than bps because 19200 and higher
  222.   are too big for some ints.  All but 75bps are multiples of ten.  Result of
  223.   lookup in this table must be multiplied by 10 to get actual speed in bps.
  224.   If this number is 70, it must be changed to 75.  If it is 888, this means
  225.   75/1200 split speed.
  226.  
  227.   The values are generic, rather than specific to UNIX.  We can't use B75,
  228.   B1200, B9600, etc, because non-UNIX versions of C-Kermit will not
  229.   necessarily have these symbols defined.  The BPS_xxx symbols are
  230.   Kermit-specific, and are defined in ckcdeb.h or on the CC command line.
  231.  
  232.   Like all other keytabs, this one must be in "alphabetical" order,
  233.   rather than numeric order.
  234. */
  235. struct keytab spdtab[] = {
  236.     "0",      0,  CM_INV,
  237.     "110",   11,  0,
  238. #ifdef BPS_115K
  239.  "115200",11520,  0,
  240. #endif /* BPS_115K */
  241.   "1200",   120,  0,
  242. #ifdef BPS_134
  243.   "134.5",  134,  0,
  244. #endif /* BPS_134 */
  245. #ifdef BPS_14K
  246.   "14400", 1440,  0,
  247. #endif /* BPS_14K */
  248. #ifdef BPS_150
  249.   "150",     15,  0,
  250. #endif /* BPS_150 */
  251. #ifdef BPS_19K
  252.   "19200", 1920,  0,
  253. #endif /* BPS_19K */
  254. #ifdef BPS_200
  255.   "200",     20,  0,
  256. #endif /* BPS_200 */
  257.   "2400",   240,  0,
  258. #ifdef BPS_28K
  259.   "28800", 2880,  0,
  260. #endif /* BPS_28K */
  261. #ifdef BPS_230K
  262.   "230400", 2304, 0,
  263. #endif /* BPS_230K */
  264.   "300",     30,  0,
  265. #ifdef BPS_3600
  266.   "3600",   360,  0,
  267. #endif /* BPS_3600 */
  268. #ifdef BPS_38K
  269.   "38400", 3840,  0,
  270. #endif /* BPS_38K */
  271.   "4800",   480,  0,
  272. #ifdef BPS_50
  273.   "50",       5,  0,
  274. #endif /* BPS_50 */
  275. #ifdef BPS_57K
  276.   "57600", 5760,  0,
  277. #endif /* BPS_57K */
  278.   "600",     60,  0,
  279. #ifdef BPS_7200
  280.   "7200",   720,  0,
  281. #endif /* BPS_7200 */
  282. #ifdef BPS_75
  283.   "75",       7,  0,
  284. #endif /* BPS_75 */
  285. #ifdef BPS_7512
  286.   "75/1200",888,  0,        /* Special code "888" for split speed */
  287. #endif /* BPS_7512 */
  288. #ifdef BPS_76K
  289.   "76800", 7680,  0,
  290. #endif /* BPS_76K */
  291.   "9600",   960,  0
  292. };
  293. int nspd = (sizeof(spdtab) / sizeof(struct keytab)); /* How many speeds */
  294. #endif /* NOLOCAL */
  295.  
  296. #ifndef NOCSETS
  297. extern struct keytab lngtab[];        /* Languages for SET LANGUAGE */
  298. extern int nlng;
  299. #endif /* NOCSETS */
  300.  
  301. #ifndef NOLOCAL
  302. /* Duplex keyword table */
  303.  
  304. struct keytab dpxtab[] = {
  305.     "full",      0, 0,
  306.     "half",      1, 0
  307. };
  308. #endif /* NOLOCAL */
  309.  
  310. /* SET FILE parameters */
  311.  
  312. struct keytab filtab[] = {
  313.     "bytesize",         XYFILS, 0,
  314. #ifndef NOCSETS
  315.     "character-set",    XYFILC, 0,
  316. #endif /* NOCSETS */
  317.     "collision",        XYFILX, 0,
  318.     "display",          XYFILD, 0,
  319.     "incomplete",       XYFILI, 0,
  320. #ifdef CK_LABELED
  321.     "label",            XYFILL, 0,
  322. #endif /* CK_LABELED */
  323.     "names",            XYFILN, 0,
  324. #ifdef VMS
  325.     "record-length",    XYFILR, 0,
  326. #endif /* VMS */
  327.     "type",             XYFILT, 0,
  328.     "warning",          XYFILW, CM_INV
  329. };
  330. int nfilp = (sizeof(filtab) / sizeof(struct keytab));
  331.  
  332. /* Flow Control */
  333.  
  334. struct keytab flotab[] = {        /* SET FLOW-CONTROL keyword table */
  335. #ifdef CK_DTRCD
  336.     "dtr/cd",   FLO_DTRC, 0,
  337. #endif /* CK_DTRCD */
  338. #ifdef CK_DTRCTS
  339.     "dtr/cts",FLO_DTRT, 0,
  340. #endif /* CK_DTRCTS */
  341.     "keep",     FLO_KEEP, 0,
  342.     "none",     FLO_NONE, 0,
  343. #ifdef CK_RTSCTS
  344.     "rts/cts",  FLO_RTSC, 0,
  345. #endif /* CK_RTSCTS */
  346.     "xon/xoff", FLO_XONX, 0
  347. };
  348. int nflo = (sizeof(flotab) / sizeof(struct keytab));
  349.  
  350. /*  Handshake characters  */
  351.  
  352. struct keytab hshtab[] = {
  353.     "bell", 007, 0,
  354.     "code", 998, 0,
  355.     "cr",   015, 0,
  356.     "esc",  033, 0,
  357.     "lf",   012, 0,
  358.     "none", 999, 0,            /* (can't use negative numbers) */
  359.     "xoff", 023, 0,
  360.     "xon",  021, 0
  361. };
  362. int nhsh = (sizeof(hshtab) / sizeof(struct keytab));
  363.  
  364. #ifndef NOLOCAL
  365. static struct keytab sfttab[] = {    /* File types for SET SESSION-LOG */
  366.     "ascii",     XYFT_B, CM_INV,
  367.     "binary",    XYFT_B, 0,
  368.     "text",      XYFT_T, 0
  369. };
  370. static int nsfttab = (sizeof(sfttab) / sizeof(struct keytab));
  371. #endif /* NOLOCAL */
  372.  
  373. #ifndef NODIAL
  374. extern struct keytab mdmtab[] ;        /* Modem types (in module ckudia.c) */
  375. extern int nmdm;            /* Number of them */
  376. #ifndef MINIDIAL
  377. extern int tbmodel;            /* Telebit model ID */
  378. #endif /* MINIDIAL */
  379. #endif /* NODIAL */
  380.  
  381. #ifndef NOPUSH
  382. #ifdef UNIX
  383. struct keytab wildtab[] = {        /* SET WILDCARD-EXPANSION */
  384.     "kermit",  0, 0,
  385.     "shell",   1, 0
  386. };
  387. #endif /* UNIX */
  388. #endif /* NOPUSH */
  389.  
  390. #ifdef NETCONN
  391. extern struct keytab netcmd[];
  392. extern int nnets;
  393. #ifdef NPIPE
  394. char pipename[PIPENAML+1];
  395. #endif /* NPIPE */
  396. #ifdef CK_NETBIOS
  397. extern unsigned char NetBiosName[] ;
  398. #endif /* CK_NETBIOS */
  399. #endif /* NETCONN */
  400.  
  401. #ifdef ANYX25
  402. struct keytab x25tab[] = {
  403.     "call-user-data",    XYUDAT, 0,
  404.     "closed-user-group", XYCLOS, 0,
  405.     "reverse-charge",    XYREVC, 0  
  406. };
  407. int nx25 = (sizeof(x25tab) / sizeof(struct keytab));
  408.  
  409. struct keytab padx3tab[] = {
  410.     "break-action",         PAD_BREAK_ACTION,           0,
  411.     "break-character",      PAD_BREAK_CHARACTER,        0,
  412.     "character-delete",     PAD_CHAR_DELETE_CHAR,       0,
  413.     "cr-padding",           PAD_PADDING_AFTER_CR,       0,
  414.     "discard-output",       PAD_SUPPRESSION_OF_DATA,    0,
  415.     "echo",                 PAD_ECHO,                   0,
  416.     "editing",              PAD_EDITING,                0,
  417.     "escape",               PAD_ESCAPE,                 0,
  418.     "forward",              PAD_DATA_FORWARD_CHAR,      0,
  419.     "lf-padding",           PAD_PADDING_AFTER_LF,       0,
  420.     "lf-insert",            PAD_LF_AFTER_CR,            0,
  421.     "line-delete",          PAD_BUFFER_DELETE_CHAR,     0,
  422.     "line-display",         PAD_BUFFER_DISPLAY_CHAR,    0,
  423.     "line-fold",            PAD_LINE_FOLDING,           0,
  424.     "pad-flow-control",     PAD_FLOW_CONTROL_BY_PAD,    0,
  425.     "service-signals",      PAD_SUPPRESSION_OF_SIGNALS, 0,
  426.     "timeout",              PAD_DATA_FORWARD_TIMEOUT,   0,
  427. /* Speed is read-only */
  428.     "transmission-rate",    PAD_LINE_SPEED,             0,
  429.     "user-flow-control",    PAD_FLOW_CONTROL_BY_USER,   0
  430. };
  431. int npadx3 = (sizeof(padx3tab) / sizeof(struct keytab));
  432. #endif /* ANYX25 */
  433.  
  434. /* Parity keyword table */
  435.  
  436. struct keytab partbl[] = {
  437.     "even",    'e', 0,
  438.     "mark",    'm', 0,
  439.     "none",     0 , 0,
  440.     "odd",     'o', 0,
  441.     "space",   's', 0
  442. };
  443. int npar = (sizeof(partbl) / sizeof(struct keytab));
  444.  
  445. /* On/Off table */
  446.  
  447. struct keytab onoff[] = {
  448.     "off",       0, 0,
  449.     "on",        1, 0
  450. };
  451.  
  452. static
  453. struct keytab xittab[] = {        /* SET EXIT */
  454.     "status",    0, 0,            /* ...STATUS */
  455.     "warning",   1, 0            /* ...WARNING */
  456. };
  457. int nexit = (sizeof(xittab) / sizeof(struct keytab));
  458.  
  459. struct keytab rltab[] = {
  460.     "local",     1, 0,
  461.     "off",       0, CM_INV,
  462.     "on",        1, CM_INV,
  463.     "remote",    0, 0
  464. };
  465. int nrlt = (sizeof(rltab) / sizeof(struct keytab));
  466.  
  467. /* Incomplete File Disposition table */
  468. static
  469. struct keytab ifdtab[] = {
  470.     "discard",   0, 0,
  471.     "keep",      1, 0
  472. };
  473.  
  474. /* SET TAKE parameters table */
  475. static
  476. struct keytab taktab[] = {
  477.     "echo",  0, 0,
  478.     "error", 1, 0,
  479.     "off",   2, CM_INV,            /* For compatibility */
  480.     "on",    3, CM_INV            /* with MS-DOS Kermit... */
  481. };
  482.  
  483. #ifndef NOSPL
  484. /* SET MACRO parameters table */
  485. static
  486. struct keytab smactab[] = {
  487.     "echo",  0, 0,
  488.     "error", 1, 0
  489. };
  490. #endif /* NOSPL */
  491.  
  492. #ifndef NOSCRIPT
  493. static
  494. struct keytab scrtab[] = {
  495.     "echo",  0, 0
  496. };
  497. #endif /* NOSCRIPT */
  498.  
  499. #define SCMD_BSZ 0            /* SET COMMAND items */
  500. #define SCMD_RCL 1
  501. #define SCMD_RTR 2
  502. #define SCMD_QUO 3
  503.  
  504. /* SET COMMAND table */
  505. struct keytab scmdtab[] = {
  506.     "bytesize",  SCMD_BSZ, 0,
  507.     "quoting",   SCMD_QUO, 0
  508. #ifdef CK_RECALL
  509. ,   "recall-buffer-size", SCMD_RCL, 0
  510. #endif /* CK_RECALL */
  511. #ifdef CM_RETRY
  512. ,   "retry", SCMD_RTR, 0
  513. #endif /* CM_RETRY */
  514. };
  515. int nbytt = (sizeof(scmdtab) / sizeof(struct keytab));
  516.  
  517. #ifndef NOSERVER
  518. /* Server parameters table */
  519. struct keytab srvtab[] = {
  520.     "display", XYSERD, 0,
  521.     "timeout", XYSERT, 0
  522. };
  523. #endif /* NOSERVER */
  524.  
  525. /* SET TRANSFER/XFER table */
  526.  
  527. struct keytab tstab[] = {
  528. #ifdef XFRCAN
  529. /*
  530.   This should be propogated to all versions...
  531. */
  532.     "cancellation",   0,   0,
  533. #endif /* XFRCAN */
  534. #ifndef NOCSETS
  535.     "character-set", 1,   0,
  536. #endif /* NOCSETS */
  537.     "locking-shift", 2,   0
  538. };
  539. int nts = (sizeof(tstab) / sizeof(struct keytab));
  540.  
  541. #ifndef NOCSETS
  542. /* SET TRANSFER CHARACTER-SET table */
  543.  
  544. extern struct keytab tcstab[];
  545. extern int ntcs;
  546. #endif /* NOCSETS */
  547.  
  548. /* SET TRANSFER LOCKING-SHIFT table */
  549. struct keytab lstab[] = {
  550.     "forced", 2,   0,
  551.     "off",    0,   0,
  552.     "on",     1,   0
  553. };
  554. int nls = (sizeof(lstab) / sizeof(struct keytab));
  555.  
  556. /* SET TELNET tables */
  557. #ifdef TNCODE
  558. extern int tn_duplex, tn_nlm;
  559. extern char *tn_term;
  560.  
  561. static struct keytab tnlmtab[] = {    /* NEWLINE-MODE table */
  562.     "off",    TNL_CRNUL, 0,        /* CR-NUL (TELNET spec) */
  563.     "on",     TNL_CRLF, 0,        /* CR-LF (TELNET spec) */
  564.     "raw",    TNL_CR, 0            /* CR only (out of spec) */
  565. };
  566. static int ntnlm = (sizeof(tnlmtab) / sizeof(struct keytab));
  567.  
  568. struct keytab tntab[] = {
  569.     "echo",          CK_TN_EC,   0,
  570.     "newline-mode",  CK_TN_NL,   0,
  571.     "terminal-type", CK_TN_TT,   0
  572. };
  573. int ntn = (sizeof(tntab) / sizeof(struct keytab));
  574. #endif /* TNCODE */
  575.  
  576. struct keytab ftrtab[] = {        /* Feature table */
  577. #ifndef NOCSETS                /* 0 = we have it, 1 = we don't */
  578. "character-sets",    0, 0,
  579. #else
  580. "character-sets",    1, 0,
  581. #endif /* NOCSETS */
  582. #ifndef NOCYRIL
  583. "cyrillic",        0, 0,
  584. #else
  585. "cyrillic",        1, 0,
  586. #endif /* NOCYRIL */
  587.  
  588. #ifndef NODEBUG
  589. "debug",        0, 0,
  590. #else
  591. "debug",        1, 0,
  592. #endif /* NODEBUG */
  593.  
  594. #ifndef NODIAL
  595. "dial",            0, 0,
  596. #else
  597. "dial",            1, 0,
  598. #endif /* NODIAL */
  599.  
  600. #ifdef DYNAMIC
  601. "dynamic-memory",       0, 0,
  602. #else
  603. "dynamic-memory",       1, 0,
  604. #endif /* DYNAMIC */
  605.  
  606. #ifdef XXFWD
  607. "forward",              0, 0,
  608. #else
  609. "forward",              1, 0,
  610. #endif /* XXFWD */
  611.  
  612. #ifdef CK_CURSES
  613. "fullscreen-display",    0, 0,
  614. #else
  615. "fullscreen-display",    1, 0,
  616. #endif /* CK_CURSES */
  617. #ifdef HEBREW
  618. "hebrew",               0, 0,
  619. #else
  620. "hebrew",               1, 0,
  621. #endif /* HEBREW */
  622. #ifndef NOHELP
  623. "help",            0, 0,
  624. #else
  625. "help",            1, 0,
  626. #endif /* NOHELP */
  627. #ifndef NOSPL
  628. "if-command",        0, 0,
  629. #else
  630. "if-command",        1, 0,
  631. #endif /* NOSPL */
  632. #ifndef NOJC
  633. #ifdef UNIX
  634. "job-control",        0, 0,
  635. #else
  636. "job-control",        1, 0,
  637. #endif /* UNIX */
  638. #else
  639. "job-control",        1, 0,
  640. #endif /* NOJC */
  641. #ifdef KANJI
  642. "kanji",        0, 0,
  643. #else
  644. "kanji",        1, 0,
  645. #endif /* KANJI */
  646. #ifndef NOCSETS
  647. "latin1",        0, 0,
  648. #else
  649. "latin1",        1, 0,
  650. #endif /* NOCSETS */
  651. #ifdef LATIN2
  652. "latin2",        0, 0,
  653. #else
  654. "latin2",        1, 0,
  655. #endif /* LATIN2 */
  656. #ifdef NETCONN
  657. "network",        0, 0,
  658. #else
  659. "network",        1, 0,
  660. #endif /* NETCONN */
  661. #ifndef NOPUSH
  662. "push",            0, 0,
  663. #else
  664. "push",            1, 0,
  665. #endif /* PUSH */
  666. #ifdef CK_RTSCTS
  667. "rts/cts",        0, 0,
  668. #else
  669. "rts/cts",        1, 0,
  670. #endif /* RTS/CTS */
  671.  
  672. #ifdef CK_REDIR
  673. "redirect",             0, 0,
  674. #else
  675. "redirect",             1, 0,
  676. #endif /* CK_REDIR */
  677.  
  678. #ifndef NOSCRIPT
  679. "script-command",    0, 0,
  680. #else
  681. "script-command",    1, 0,
  682. #endif /* NOSCRIPT */
  683. #ifndef NOSERVER
  684. "server-mode",        0, 0,
  685. #else
  686. "server-mode",        1, 0,
  687. #endif /* NOSERVER */
  688. #ifndef NOSHOW
  689. "show-command",        0, 0,
  690. #else
  691. "show-command",        1, 0,
  692. #endif /* NOSHOW */
  693. #ifndef NOXMIT
  694. "transmit",        0, 0,
  695. #else
  696. "transmit",        1, 0
  697. #endif /* NOXMIT */
  698. };
  699. int nftr = (sizeof(ftrtab) / sizeof(struct keytab));
  700.  
  701. #ifndef NOSPL /* Present this is used only with script programming items... */
  702.  
  703. /*  K W D H E L P  --  Given a keyword table, print keywords in columns.  */
  704. /*
  705.   Call with:
  706.     s     - keyword table
  707.     n     - number of entries
  708.     pre   - prefix for each keyword
  709.     post  - suffix for each keyword
  710.     off   - offset on first screenful, allowing room for introductory text
  711.  
  712.   Arranges keywords in columns with width based on longest keyword.
  713.   Does "more?" prompting at end of screen.  
  714.   Uses global cmd_rows and cmd_cols for screen size.
  715. */
  716. VOID
  717. kwdhelp(s,n,pre,post,off) struct keytab s[]; int n, off; char *pre, *post; {
  718.     int width = 0;
  719.     int cols, height, i, j, k, lc, n2 = 0;
  720.     char *b, *p, *q;
  721.     char *pa, *px;
  722.     char **s2;
  723.     
  724.     if (!s) return;            /* Nothing to do */
  725.     if (n < 1) return;            /* Ditto */
  726.     if (off < 0) off = 0;        /* Offset for first page */
  727.     if (!pre) pre = "";            /* Handle null string pointers */
  728.     if (!post) post = "";
  729.     lc = off;                /* Screen-line counter */
  730.  
  731.     if (s2 = (char **) malloc(n * sizeof(char *))) {
  732.     for (i = 0; i < n; i++) {    /* Find longest keyword */
  733.         if (s[i].flgs & CM_INV)    /* Skip invisible ones */
  734.           continue;
  735.         s2[n2++] = s[i].kwd;    /* Copy pointers to visible ones */
  736.         j = strlen(s[i].kwd);
  737.         if (j > width) width = j;
  738.     }
  739.     /* Column width */
  740.     n = n2;
  741.     }
  742.     if (s2 && (b = (char *) malloc(cmd_cols + 1))) { /* Make a line buffer   */
  743.     width += (int)strlen(pre) + (int)strlen(post) + 2; 
  744.     cols = cmd_cols / width;        /* How many columns? */
  745.     height = n / cols;        /* How long is each column? */
  746.     if (n % cols) height++;        /* Add one for remainder, if any */
  747.  
  748.     for (i = 0; i < height; i++) {        /* Loop for each row */
  749.         for (j = 0; j < cmd_cols; j++)  /* First fill row with blanks */
  750.           b[j] = SP;
  751.         for (j = 0; j < cols; j++) {    /* Loop for each column in row */
  752.         k = i + (j * height);       /* Index of next keyword */
  753.         if (k < n) {            /* In range? */
  754.             pa = pre; px = post;
  755.             p = s2[k];            /* Point to verb name */
  756.             q = b + (j * width) + 1; /* Where to copy it to */
  757.             while (*q++ = *pa++) ;  /* Copy prefix */
  758.             q--;            /* Back up over NUL */
  759.             while (*q++ = *p++) ;   /* Copy the keyword */
  760.             q--;            /* Back up over NUL */
  761.             while (*q++ = *px++) ;  /* Copy suffix */
  762.             q--;
  763.             *q = SP;        /* Replace the space */
  764.         }
  765.         }
  766.         p = b + cmd_cols - 1;
  767.         while (*p-- == SP) ;
  768.         *(p+2) = NUL;
  769.         printf("%s\n",b);        /* Print the line */
  770.         if (++lc > (cmd_rows - 3)) { /* Screen full? */
  771.         if (!askmore()) {    /* Do more-prompting... */
  772.             free(b);
  773.             return;
  774.         } else
  775.           lc = 0;
  776.         }
  777.     } 
  778.     printf("\n");            /* Blank line at end of report */
  779.     free(s2);            /* Free array copy */
  780.     free(b);            /* Free line buffer */
  781.     return;
  782.     } else {                /* Malloc failure, no columns */
  783.     for (i = 0; i < n; i++) {
  784.         if (s[i].flgs & CM_INV)    /* Use original keyword table */
  785.           continue;            /* skipping invisible entries */
  786.         printf("%s%s%s\n",pre,s[i].kwd,post);
  787.         if (++lc > (cmd_rows - 3)) { /* Screen full? */
  788.         if (!askmore()) {     /* Do more-prompting... */
  789.             return;
  790.         } else lc = 0;
  791.         }        
  792.     }
  793.     if (s2) free(s2);        /* Free array copy, if any */
  794.     return;
  795.     }
  796. }
  797. #endif /* NOSPL */
  798.  
  799. int                    /* CHECK command */
  800. dochk() {
  801.     int x, y;
  802.     if ((y = cmkey(ftrtab,nftr,"","",xxstring)) < 0)
  803.       return(y);
  804.     strcpy(line,atmbuf);
  805.     if ((y = cmcfm()) < 0)
  806.       return(y);
  807.     y = lookup(ftrtab,line,nftr,&x);    /* This will succeed. */
  808.     if (msgflg)                /* If at top level... */
  809.       printf(" %s%s available\n", ftrtab[x].kwd, y ? " not" : "");
  810.     else if (y && !backgrd)
  811.       printf(" CHECK: %s not available\n", ftrtab[x].kwd);
  812.     return(success = 1 - y);
  813. }
  814.  
  815. #ifndef NOSETKEY
  816. int
  817. set_key() {                /* SET KEY */
  818.     int x, y;
  819.     int flag = 0;
  820.     int kc;                /* Key code */
  821.     char *s;                /* Key binding */
  822.     char *p;                /* Worker */
  823.  
  824.     if ((y = cmnum("numeric key code, or the word CLEAR,",
  825.            "",10,&kc,xxstring)) < 0) {
  826.     debug(F111,"SET KEY",atmbuf,y);
  827.     if (y == -2) {            /* Not a valid number */
  828.         if ((y = strlen(atmbuf)) < 0) /* Check for SET KEY CLEAR */
  829.           return(-2);
  830.         if (xxstrcmp(atmbuf,"clear",y))
  831.           return(-2);
  832.         for (y = 0; y < KMSIZE; y++) {
  833.         keymap[y] = y;
  834.         macrotab[y] = NULL;
  835.         }
  836. #ifdef OS2
  837.         keymapinit();        /* Special OS/2 initializations */
  838. #endif /* OS2 */
  839.         return(1);
  840.     } else if (y == -3) {        /* SET KEY <Return> */
  841.         printf(" Press key to be defined: "); /* Prompt for a keystroke */
  842. #ifdef UNIX
  843. #ifdef NOSETBUF
  844.         fflush(stdout);
  845. #endif /* NOSETBUF */
  846. #endif /* UNIX */
  847.         conbin((char)escape);    /* Put terminal in binary mode */
  848.         kc = congks(0);        /* Get character or scan code */
  849.         concb((char)escape);    /* Restore terminal to cbreak mode */
  850.         if (kc < 0) {        /* Check for error */
  851.         printf("?Error reading key\n");
  852.         return(0);
  853.         }
  854.         shokeycode(kc);        /* Show current definition */
  855.         flag = 1;            /* Remember it's a multiline command */
  856.     } else                /* Error */
  857.       return(y);
  858.     }
  859.  
  860.     /* Normal SET KEY <scancode> <value> command... */
  861.  
  862.     if (kc < 0 || kc >= KMSIZE) {
  863.     printf("?key code must be between 0 and %d\n", KMSIZE - 1);
  864.     return(-9);
  865.     }
  866.     if (kc == escape) {
  867.     printf("Sorry, %d is the CONNECT-mode escape character\n",kc);
  868.     return(-9);
  869.     }
  870. #ifdef OS2
  871.     wideresult = -1;
  872. #endif /* OS2 */
  873.     if (flag) {
  874.     cmsavp(psave,PROMPTL);
  875.     cmsetp(" Enter new definition: ");
  876.     cmini(ckxech);
  877.     }
  878.   def_again:
  879.     if (flag) prompt(NULL);
  880.     if ((y = cmtxt("key definition,\n\
  881. or Ctrl-C to cancel this command,\n\
  882. or Enter to restore default definition",
  883.            "",&s,NULL)) < 0) {
  884.     if (flag)            /* Handle parse errors */
  885.       goto def_again;
  886.     else
  887.       return(y);
  888.     }
  889.     s = brstrip(s);
  890.     p = s;                /* Save this place */
  891. /*
  892.   If the definition included any \Kverbs, quote the backslash so the \Kverb
  893.   will still be in the definition when the key is pressed.  We don't do this
  894.   in zzstring(), because \Kverbs are valid only in this context and nowhere
  895.   else.
  896.  
  897.   We use this code active for all versions that support SET KEY, even if they
  898.   don't support \Kverbs, because otherwise \K would behave differently for
  899.   different versions.
  900. */
  901.     for (x = 0, y = 0; s[x]; x++, y++) { /* Convert \K to \\K */
  902.     if ((x > 0) &&
  903.         (s[x] == 'K' || s[x] == 'k')
  904.         ) {                /* Have K */
  905.   
  906.         if ((x == 1 && s[x-1] == CMDQ) ||
  907.         (x > 1 && s[x-1] == CMDQ && s[x-2] != CMDQ)) {
  908.         line[y++] = CMDQ;    /* Make it \\K */
  909.         }
  910.         if (x > 1 && s[x-1] == '{' && s[x-2] == CMDQ) {
  911.           line[y-1] = CMDQ;    /* Have \{K */
  912.           line[y++] = '{';    /* Make it \\{K */
  913.         }
  914.     }
  915.     line[y] = s[x];
  916.     }
  917.     line[y++] = NUL;            /* Terminate */
  918.     s = line + y + 1;            /* Point to after it */
  919.     x = LINBUFSIZ - (int) strlen(line) - 1; /* Calculate remaining space */
  920.     if ((x < (LINBUFSIZ / 2)) ||
  921.     (zzstring(line, &s, &x) < 0)) { /* Expand variables, etc. */
  922.     printf("?Key definition too long\n");
  923.     if (flag) cmsetp(psave);
  924.     return(-9);
  925.     }
  926.     s = line + y + 1;            /* Point to result. */
  927.  
  928. #ifndef NOKVERBS
  929. /*
  930.   Special case: see if the definition starts with a \Kverb.
  931.   If it does, point to it with p, otherwise set p to NULL.
  932. */
  933.     p = s;
  934.     if (*p++ == CMDQ) {
  935.     if (*p == '{') p++;
  936.     p = (*p == 'k' || *p == 'K') ? p + 1 : NULL; 
  937.     }
  938. #else
  939.     p = NULL;
  940. #endif /* NOKVERBS */
  941.  
  942.     if (macrotab[kc]) {            /* Possibly free old macro from key. */
  943.     free(macrotab[kc]);
  944.     macrotab[kc] = NULL;
  945.     }
  946.     switch (strlen(s)) {        /* Action depends on length */
  947.       case 0:                /* Reset to default binding */
  948.     keymap[kc] = kc;
  949.     break;
  950.       case 1:                /* Single character */
  951.       keymap[kc] = (CHAR) *s;
  952.       break;
  953.       default:                /* Character string */
  954. #ifndef NOKVERBS
  955.     if (p) {
  956.         y = xlookup(kverbs,p,nkverbs,&x); /* Look it up */
  957.         debug(F101,"set key kverb lookup",0,y); /* exact match required */
  958.         if (y > -1) {
  959.         keymap[kc] = F_KVERB | y;
  960.         break;
  961.         }
  962.     }
  963. #endif /* NOKVERBS */
  964.     keymap[kc] = kc;
  965.     macrotab[kc] = (MACRO) malloc(strlen(s)+1);
  966.     if (macrotab[kc])
  967.       strcpy((char *) macrotab[kc], s);
  968.     break;
  969.     }
  970.     if (flag) cmsetp(psave);
  971.     return(1);
  972. }
  973. #endif /* NOSETKEY */
  974.  
  975. /*  D O P R M  --  Set a parameter.  */
  976. /*
  977.  Returns:
  978.   -2: illegal input
  979.   -1: reparse needed
  980.    0: success
  981. */
  982. int
  983. doprm(xx,rmsflg) int xx, rmsflg; {
  984.     int i, x, y = 0, z;
  985.     long zz;
  986.     char *s;
  987.  
  988. #ifdef OS2
  989.     if (xx == XYPRTR) {            /* SET PRINTER */
  990.     if ((x = cmofi("printer file","PRN",&s,xxstring)) < 0)
  991.       return(x);
  992.     if (x > 1) {
  993.         printf("?Directory names not allowed\n");
  994.         return(-9);
  995.     }
  996.     strcpy(line,s);            /* Make a temporary safe copy */
  997.     if ((x = cmcfm()) < 0)        /* Confirm the command */
  998.       return(x);
  999.     if (printfile) {        /* Had a print file before? */
  1000.         free(printfile);        /* Remove its name */
  1001.         printfile = NULL;
  1002.     }
  1003.     x = strlen(line);        /* Length of name of new print file */
  1004.     if ((x != 3) || (xxstrcmp(line,"PRN",3) != 0)) {
  1005.         printfile = (char *) malloc(x + 1);    /* Allocate space for it */
  1006.         if (!printfile) {
  1007.          printf("?Memory allocation failure\n");
  1008.         return(-9);
  1009.         }
  1010.         strcpy(printfile,line);    /* Copy new name to new space */
  1011.         debug(F110,"printfile name",printfile,0);
  1012.     } else
  1013.         debug(F101,"printfile is NULL","",printfile);
  1014.     /* Return with printfile pointing to a file or device name */
  1015.     /* or NULL to indicate the default printer. */
  1016.     return(success = 1);
  1017.     }
  1018. #endif /* OS2 */
  1019.  
  1020. switch (xx) {
  1021.  
  1022. #ifdef ANYX25                /* SET X25 ... */
  1023. case XYX25:
  1024.     return(setx25());
  1025.  
  1026. case XYPAD:                /* SET PAD ... */
  1027.     return(setpadp());
  1028. #endif /* ANYX25 */
  1029.  
  1030. case XYEOL:    /* These have all been moved to set send/receive... */
  1031. case XYLEN:     /* Let the user know what to do. */
  1032. case XYMARK:
  1033. case XYNPAD:
  1034. case XYPADC:
  1035. case XYTIMO:
  1036.     printf("...Use SET SEND or SET RECEIVE instead.\n");
  1037.     printf("Type HELP SET SEND or HELP SET RECEIVE for more info.\n");
  1038.     return(success = 0);
  1039.  
  1040. case XYATTR:                /* File Attribute packets */
  1041.     return(setat(rmsflg));
  1042.  
  1043. case XYIFD:                /* Incomplete file disposition */
  1044.     if ((y = cmkey(ifdtab,2,"","discard",xxstring)) < 0) return(y);
  1045.     if ((x = cmcfm()) < 0) return(x);
  1046.     if (rmsflg) {
  1047.     sstate = setgen('S', "310", y ? "1" : "0", "");
  1048.     return((int) sstate);
  1049.     } else {
  1050.     keep = y;
  1051.     return(success = 1);
  1052.     }
  1053.  
  1054. #ifndef NOSPL
  1055. case XYINPU:                /* SET INPUT */
  1056.     return(setinp());
  1057. #endif /* NOSPL */
  1058.  
  1059. #ifdef NETCONN
  1060. case XYNET:                /* SET NETWORK */
  1061.  
  1062. #ifdef OS2     /* Hide network-type keywords for networks not installed */
  1063.     for (z = 0; z < nnets; z++) {
  1064.     if (netcmd[z].kwval == NET_TCPB && tcp_avail == 0)
  1065.       netcmd[z].flgs =  CM_INV;
  1066. #ifdef DECNET
  1067.     else if (netcmd[z].kwval == NET_DEC  && dnet_avail == 0)
  1068.       netcmd[z].flgs =  CM_INV;
  1069. #endif /* DECNET */
  1070. #ifdef CK_NETBIOS
  1071.     else if (netcmd[z].kwval == NET_BIOS && netbiosAvail == 0)
  1072.       netcmd[z].flgs =  CM_INV;
  1073. #endif /* CK_NETBIOS */
  1074.     }
  1075.     if (tcp_avail)            /* Default network type */
  1076.       strcpy(tmpbuf,"tcp/ip");
  1077. #ifdef DECNET
  1078.     else if (dnet_avail)
  1079.       strcpy(tmpbuf,"decnet");
  1080. #endif /* DECNET */
  1081. #ifdef CK_NETBIOS
  1082.     else if (netbiosAvail)
  1083.       strcpy(tmpbuf,"netbios");
  1084. #endif /* CK_NETBIOS */
  1085.     else strcpy(tmpbuf,"named-pipe");
  1086. #else
  1087. #ifdef TCPSOCKET
  1088.     strcpy(tmpbuf,"tcp/ip");
  1089. #else
  1090. #ifdef ANYX25
  1091.     strcpy(tmpbuf,"x.25");
  1092. #else
  1093.     strcpy(tmpbuf,"");    
  1094. #endif /* ANYX25 */
  1095. #endif /* TCPSOCKET */
  1096. #endif /* OS2 */
  1097.  
  1098.     if ((z = cmkey(netcmd,nnets,"",tmpbuf,xxstring)) < 0)
  1099.       return(z);
  1100.  
  1101. #ifdef OS2
  1102.     if (z == NET_TCPB && tcp_avail == 0) {
  1103.     printf("?Sorry, TCP/IP is not available on this system.\n") ;
  1104.     return(-9);
  1105. #ifdef CK_NETBIOS
  1106.     } else if (z == NET_BIOS && netbiosAvail == 0) {
  1107.     printf("?Sorry, NETBIOS is not available on this system.\n") ;
  1108.     return(-9);
  1109. #endif /* CK_NETBIOS */
  1110. #ifdef DECNET
  1111.     } else if (z == NET_DEC && dnet_avail == 0) {
  1112.     printf("?Sorry, DECnet is not available on this system.\n") ;
  1113.     return(-9);
  1114. #endif /* DECNET */
  1115.     }
  1116. #endif /* OS2 */
  1117.  
  1118. #ifdef NPIPEORBIOS
  1119.     if (z == NET_PIPE ||         /* Named pipe -- also get pipename */
  1120.     z == NET_BIOS) {        /* NETBIOS -- also get local name */
  1121.     char *defnam;
  1122. #ifdef CK_NETBIOS
  1123.     char tmpnbnam[NETBIOS_NAME_LEN+1];
  1124. #endif /* CK_NETBIOS */
  1125.     /* Construct default name  */
  1126.     if (z == NET_PIPE) {        /* Named pipe */
  1127.         defnam = "kermit";        /* Default name is always "kermit" */
  1128.     } else {            /* NetBIOS */
  1129.         if (NetBiosName[0] != SP) {    /* If there is already a name, */
  1130.         char *p; int n;        /* use it as the default. */
  1131.         strcpy(tmpnbnam,NetBiosName);
  1132.         p=tmpnbnam + NETBIOS_NAME_LEN - 1;
  1133.         while ( *p == SP ) {
  1134.             *p = NUL ;
  1135.             p-- ;
  1136.         }
  1137.         defnam = tmpnbnam;
  1138.         } else if (*myhost)        /* Otherwise use this PC's host name */
  1139.           defnam = (char *) myhost;
  1140.         else            /* Otherwise use "kermit" */
  1141.           defnam = "kermit";
  1142.     }
  1143.     if ((y = cmtxt((z == NET_PIPE) ? "pipe name" : "local NETBIOS name",
  1144.                defnam, &s, xxstring)) < 0)
  1145.       return(y);
  1146. #ifdef NPIPE
  1147.     pipename[0] = NUL;
  1148. #endif /* NPIPE */
  1149.     if ((y = (int) strlen(s)) < 1) {
  1150.         printf("?You must also specify a %s name\n",
  1151.            (z == NET_PIPE) ? "pipe" : "local NETBIOS" );
  1152.          return(-9);
  1153.     }
  1154. #ifdef CK_NETBIOS
  1155.     if (z == NET_BIOS) {
  1156.         if ( !netbiosAvail ) {
  1157.         printf("?NETBIOS support is not available on this system.\n") ;
  1158.         return(-9) ;
  1159.         }
  1160.         if ( y - NETBIOS_NAME_LEN > 0) {
  1161.         printf("?NETBIOS name too long, %ld maximum\n",
  1162.                NETBIOS_NAME_LEN);
  1163.         return(-9);
  1164.         } else if ( !strcmp(s,tmpnbnam) ) {
  1165.               nettype = z;        /* Returning to old connection... */
  1166.         return(success = 1);    /* Done */
  1167.         } else if (strcmp("                ",NetBiosName)) {
  1168.            printf("?Local NETBIOS name already assigned to \"%s\"\n",
  1169.                NetBiosName);
  1170.            return(-9) ;
  1171.        } else {
  1172.         NCB ncb ;
  1173.         APIRET rc ;
  1174.         strcpy(NetBiosName,s);
  1175.         for (x = y; x < NETBIOS_NAME_LEN; x++)
  1176.           NetBiosName[x] = SP;
  1177.         NetBiosName[NETBIOS_NAME_LEN] = NUL;
  1178.         printf("Verifying \"%s\" is a unique NetBIOS node name ...\n",
  1179.                NetBiosName) ;
  1180.         rc = NCBAddName( NetbeuiAPI,
  1181.                 &ncb, NetBiosAdapter, NetBiosName ) ;
  1182.         if ( rc ) {
  1183.             printf(
  1184.         "?Sorry, \"%s\" is already in use by another NetBIOS node.\n",
  1185.                NetBiosName);
  1186.             for ( x=0; x < NETBIOS_NAME_LEN; x++)
  1187.               NetBiosName[x] = SP ;
  1188.             return(-9) ;
  1189.         } 
  1190.         }
  1191.     }
  1192. #endif /* CK_NETBIOS */
  1193. #ifdef NET_PIPE
  1194.     if (z == NET_PIPE)
  1195.       strncpy(pipename,s,PIPENAML);
  1196. #endif /* NET_PIPE */
  1197.     } else
  1198. #endif /* NPIPEORBIOS */
  1199.       if ((x = cmcfm()) < 0) return(x);
  1200.     nettype = z;
  1201.     if (
  1202.     (nettype != NET_DEC)  &&
  1203. #ifdef NPIPE
  1204.     (nettype != NET_PIPE) &&
  1205. #endif /* NPIPE */
  1206. #ifdef CK_NETBIOS
  1207.     (nettype != NET_BIOS) &&
  1208. #endif /* CK_NETBIOS */
  1209.     (nettype != NET_SX25) &&
  1210.     (nettype != NET_VX25) &&
  1211.         (nettype != NET_TCPB)) {
  1212.     printf("?Network type not supported\n");
  1213.     return(success = 0);
  1214.     } else {
  1215.     return(success = 1);
  1216.     }
  1217. #endif /* NETCONN */
  1218.  
  1219. case XYHOST:                /* SET HOST or SET LINE */
  1220. case XYLINE:
  1221.     return(setlin(xx,1));
  1222.  
  1223. #ifndef NOSETKEY
  1224. case XYKEY:                /* SET KEY */
  1225.     return(set_key());
  1226. #endif /* NOSETKEY */
  1227.  
  1228. #ifndef NOCSETS
  1229. case XYLANG:                 /* Language */
  1230.     if ((y = cmkey(lngtab,nlng,"","none",xxstring)) < 0) /* language code */
  1231.       return(y);
  1232.     if ((x = cmcfm()) < 0) return(x);    /* And confirmation of command */
  1233.  
  1234.     /* Look up language and get associated character sets */
  1235.     for (i = 0; (i < nlangs) && (langs[i].id != y); i++) ;
  1236.     if (i >= nlangs) {
  1237.     printf("?internal error, sorry\n");
  1238.     return(success = 0);
  1239.     }
  1240.     language = i;            /* All good, set the language, */
  1241.     return(success = 1);
  1242. #endif /* NOCSETS */
  1243.  
  1244. #ifndef MAC
  1245. case XYBACK:                /* BACKGROUND */
  1246.     if ((z = cmkey(onoff,2,"","",xxstring)) < 0) return(z);
  1247.     if ((y = cmcfm()) < 0) return(y);
  1248.     bgset = z;
  1249.     success = 1;
  1250.     bgchk();
  1251.     return(success);
  1252. #endif /* MAC */
  1253.  
  1254. case XYQUIE:                /* QUIET */
  1255.     return(success = seton(&quiet));
  1256.  
  1257. case XYBUF: {                /* BUFFERS */
  1258. #ifdef DYNAMIC
  1259.     int sb, rb;
  1260.     char sbs[10];
  1261.     if ((y = cmnum("Send buffer size","",10,&sb,xxstring)) < 0) {
  1262.     if (y == -3) printf("?Buffer size required\n");
  1263.     return(y);
  1264.     }
  1265.     if (sb < 0) {
  1266.     if (*atmbuf == '-') printf("?Negative numbers can't be used here\n");
  1267.     else printf("?Integer overflow, use a smaller number please\n");
  1268.     return(-9);
  1269.     } else if (sb < 80) {
  1270.     printf("?Too small\n");
  1271.     return(-9);
  1272.     }
  1273.     sprintf(sbs,"%d",sb);        /* Default second size == first */
  1274.     if ((y = cmnum("Receive buffer size",sbs,10,&rb,xxstring)) < 0)
  1275.       return(y);
  1276.     if (rb < 0) {
  1277.     if (*atmbuf == '-') printf("?Negative numbers can't be used here\n");
  1278.     else printf("?Integer overflow, use a smaller number please\n");
  1279.     return(-9);
  1280.     } else if (rb < 80) {
  1281.     printf("?Too small\n");
  1282.     return(-9);
  1283.     }
  1284.     if ((y = cmcfm()) < 0) return(y);
  1285.     if ((y = inibufs(sb,rb)) < 0) return(y);
  1286.     y = adjpkl(urpsiz,wslotr,bigrbsiz); /* Maybe adjust packet sizes */
  1287.     if (y != urpsiz) urpsiz = y;
  1288.     y = adjpkl(spsiz,wslotr,bigsbsiz);
  1289.     if (y != spsiz) spsiz = spmax = spsizr = y;
  1290.     return(success = 1);
  1291. #else
  1292.     printf("?Sorry, not available\n");
  1293.     return(success = 0);
  1294. #endif /* DYNAMIC */
  1295. }
  1296.  
  1297. case XYCHKT:                /* BLOCK-CHECK */
  1298.     if ((x = cmkey(chktab,4,"","1",xxstring)) < 0) return(x);
  1299.     if ((y = cmcfm()) < 0) return(y);
  1300.     bctr = x;                 /* Set locally too, even if REMOTE SET */
  1301.     if (rmsflg) {
  1302.     if (x == 4) {
  1303.         tmpbuf[0] = 'B';
  1304.         tmpbuf[1] = '\0';
  1305.     } else sprintf(tmpbuf,"%d",x);
  1306.     sstate = setgen('S', "400", tmpbuf, "");
  1307.     return((int) sstate);
  1308.     } else {
  1309.     return(success = 1);
  1310.     }
  1311.  
  1312. #ifndef NOLOCAL
  1313. #ifndef MAC
  1314. /*
  1315.   The Mac has no carrier...
  1316. */
  1317. case XYCARR:                /* CARRIER */
  1318.     if ((y = cmkey(crrtab,ncrr,"","auto",xxstring)) < 0) return(y);
  1319.     if (y == CAR_ON) {
  1320.     x = cmnum("Carrier wait timeout, seconds","0",10,&z,xxstring);
  1321.     if (x < 0) return(z);
  1322.     }
  1323.     if ((x = cmcfm()) < 0) return(x);
  1324.     carrier = ttscarr(y);
  1325.     cdtimo = z;
  1326.     return(success = 1);
  1327. #endif /* MAC */
  1328. #endif /* NOLOCAL */
  1329. #ifdef TNCODE
  1330. case XYTEL:                /* TELNET */
  1331.     if ((z = cmkey(tntab,ntn,"parameter for TELNET negotiations", "",
  1332.            xxstring)) < 0) return(z);
  1333.     switch (z) {
  1334.       case CK_TN_EC:            /* ECHO */
  1335.     if ((x = cmkey(rltab,nrlt,
  1336.                "initial TELNET echoing state","local",xxstring)) < 0)
  1337.       return(x);
  1338.     if ((y = cmcfm()) < 0) return(y);
  1339.     tn_duplex = x;
  1340.     return(success = 1);
  1341.  
  1342.       case CK_TN_TT:            /* TERMINAL TYPE */
  1343.     if ((y = cmtxt("terminal type for TELNET connections","",
  1344.                &s,xxstring)) < 0)
  1345.       return(y);
  1346.     if (tn_term) free(tn_term);    /* Free any previous storage */
  1347.     if (s == NULL || *s == NUL) {    /* If none given */
  1348.         tn_term = NULL;        /* remove the override string */
  1349.         return(success = 1);
  1350.     } else if (tn_term = malloc(strlen(s)+1)) { /* Make storage for new */
  1351.         strcpy(tn_term,s);        /* Copy string into new storage */
  1352.         return(success = 1);
  1353.     } else return(success = 0);
  1354.  
  1355.       case CK_TN_NL:            /* NEWLINE-MODE */
  1356.         if ((x = cmkey(tnlmtab,ntnlm,"","on",xxstring)) < 0)
  1357.       return(x);
  1358.     if ((y = cmcfm()) < 0)
  1359.       return(y);
  1360.     tn_nlm = x;
  1361.     return(success = 1);
  1362.  
  1363.       default:
  1364.     return(-2);
  1365.     }
  1366. #endif /* TNCODE */
  1367.  
  1368. default:
  1369.     break;
  1370. }
  1371.  
  1372. switch (xx) {
  1373. #ifndef NOSPL
  1374. case XYCOUN:                /* SET COUNT */
  1375.     x = cmnum("Positive number","0",10,&z,xxstring);
  1376.     if (x < 0) return(x);
  1377.     if ((x = cmcfm()) < 0) return(x);
  1378.     if (z < 0) {
  1379.     printf("?A positive number, please\n");
  1380.     return(0);
  1381.     }
  1382.     debug(F101,"XYCOUN: z","",z);
  1383.     return(success = setnum(&count[cmdlvl],z,0,10000));
  1384. #endif /* NOSPL */
  1385.  
  1386. #ifndef NOSPL
  1387. case XYCASE:
  1388.     return(success = seton(&inpcas[cmdlvl]));
  1389. #endif /* NOSPL */
  1390.  
  1391. case XYCMD:                /* COMMAND ... */
  1392.     if ((y = cmkey(scmdtab,nbytt,"","",xxstring)) < 0) return(y);
  1393.     switch(y) {
  1394.       case SCMD_BSZ:
  1395.     if ((y = cmnum("bytesize for command characters, 7 or 8","7",10,&x,
  1396.                xxstring)) < 0)
  1397.       return(y);
  1398.     if (x != 7 && x != 8) {
  1399.         printf("\n?The choices are 7 and 8\n");
  1400.         return(success = 0);
  1401.     }
  1402.     if ((y = cmcfm()) < 0) return(y);
  1403.     if (x == 7) cmdmsk = 0177;
  1404.     else if (x == 8) cmdmsk = 0377;
  1405.     return(success = 1);
  1406. #ifdef CK_RECALL
  1407.       case SCMD_RCL:
  1408.     if ((y = cmnum("maximum number of commands in recall buffer","10",
  1409.                10,&x,xxstring)) < 0)
  1410.       return(y);
  1411.     if ((y = cmcfm()) < 0) return(y);
  1412.     return(success = cmrini(x));
  1413. #endif /* CK_RECALL */
  1414. #ifdef CM_RETRY
  1415.       case SCMD_RTR:
  1416.     return(success = seton(&cm_retry));
  1417. #endif /* CM_RETRY */
  1418.       case SCMD_QUO:
  1419.     if ((x = seton(&y)) < 0) return(x);
  1420.     cmdsquo(y);
  1421.     /* Set string-processing function */
  1422. #ifdef datageneral
  1423.     xxstring = y ? zzstring : (xx_strp) NULL;
  1424. #else
  1425.     xxstring = y ? zzstring : NULL;
  1426. #endif /* datageneral */
  1427.     return(success = 1);
  1428.       default:
  1429.     return(-2);
  1430.     }
  1431.     
  1432. case XYDFLT:                /* SET DEFAULT = CD */
  1433.     return(success = docd());
  1434.  
  1435. case XYDEBU:                /* SET DEBUG { on, off, session } */
  1436.     if ((y = cmkey(dbgtab,ndbg,"","",xxstring)) < 0) return(y);
  1437.     if ((x = cmcfm()) < 0) return(x);
  1438.     switch (y) {
  1439.       case 0:                /* 0 = all debugging off. */
  1440.     debses = 0;
  1441. #ifdef DEBUG
  1442.     if (deblog) doclslog(LOGD);
  1443. #endif /* DEBUG */
  1444.         return(success = 1);
  1445.  
  1446.       case 1:                /* 1 = log debugging to debug.log */
  1447. #ifdef DEBUG
  1448.     deblog = debopn("debug.log", 0);
  1449.     return(success = deblog ? 1 : 0);
  1450. #else
  1451.     printf("?Sorry, debug log feature not enabled\n");
  1452.     return(success = 0);
  1453. #endif /* DEBUG */
  1454.  
  1455.       case 2:                /* 2 = session. */
  1456.     return(success = debses = 1);
  1457.     }
  1458.  
  1459. case XYDELA:                /* SET DELAY */
  1460.     y = cmnum("Number of seconds before starting to send","5",10,&x,xxstring);
  1461.     if (x < 0) x = 0;
  1462.     return(success = setnum(&delay,x,y,999));
  1463.  
  1464. default:
  1465.     break;
  1466. }
  1467.  
  1468. switch (xx) {
  1469.  
  1470. #ifndef NODIAL
  1471. case XYDIAL:                /* SET DIAL */
  1472.     return(setdial());
  1473. #endif /* NODIAL */
  1474.  
  1475. #ifdef COMMENT                /* Unused at present */
  1476. case XYDOUB:
  1477.     if ((x = cmfld("Character to double","none",&s,xxstring)) < 0) {
  1478.     if (x == -3) {
  1479.         dblchar = -1;
  1480.         if (msgflg) printf("Doubling Off\n");
  1481.         return(success = 1);
  1482.     } else return(x);
  1483.     }
  1484.     strcpy(line,s);
  1485.     lp = line;
  1486.     if ((x = cmcfm()) < 0) return(x);
  1487.     if (!xxstrcmp(lp,"none",4)) {
  1488.     dblchar = -1;
  1489.     if (msgflg) printf("Doubling Off\n");
  1490.     return(success = 1);
  1491.     }
  1492.     if ((int)strlen(lp) != 1) return(-2);
  1493.     dblchar = *lp & 0xFF;
  1494.     if (msgflg) printf("Doubled: %d\n",dblchar);
  1495.     return(success = 1);
  1496. #endif /* COMMENT */
  1497.  
  1498. #ifndef NOLOCAL
  1499. case XYDUPL:                /* SET DUPLEX */
  1500.     if ((y = cmkey(dpxtab,2,"","full",xxstring)) < 0) return(y);
  1501.     if ((x = cmcfm()) < 0) return(x);
  1502.     duplex = y;
  1503.     return(success = 1);
  1504.  
  1505. case XYLCLE:                /* LOCAL-ECHO (= DUPLEX) */
  1506.     return(success = seton(&duplex));
  1507.  
  1508. case XYESC:                /* SET ESCAPE */
  1509.     sprintf(tmpbuf,"%d",DFESC);
  1510.     y = cmnum("Decimal ASCII code for CONNECT-mode escape character",
  1511.           tmpbuf, 10,&x,xxstring);
  1512.     success = setcc(&escape,x,y);
  1513. #ifdef COMMENT
  1514. /* This is what SHOW ESCAPE is for. */
  1515.     if (success && msgflg)
  1516.       printf(" CONNECT-mode escape character: %d (Ctrl-%c, %s)\n",
  1517.          escape,ctl(escape),(escape == 127 ? "DEL" : ccntab[escape]));
  1518. #endif /* COMMENT */
  1519.     return(success);
  1520. #endif /* NOLOCAL */
  1521.  
  1522. case XYEXIT:                /* SET EXIT */
  1523.     if ((z = cmkey(xittab,nexit,"","",xxstring)) < 0)
  1524.       return(z);
  1525.     switch (z) {
  1526.       case 0:                /* STATUS */
  1527.     y = cmnum("EXIT status code","",10,&x,xxstring);
  1528.     return(success = setnum(&xitsta,x,y,-1));
  1529.       case 1:                /* WARNING */
  1530.     if ((z = cmkey(onoff,2,"","",xxstring)) < 0) return(z);
  1531.     if ((y = cmcfm()) < 0) return(y);
  1532.     xitwarn = z;
  1533.     return(success = 1);
  1534.       default:
  1535.     return(-2);
  1536.     } /* End of SET EXIT switch() */
  1537.  
  1538. default:
  1539.     break;
  1540. }
  1541.  
  1542. switch (xx) {
  1543. case XYFILE:                /* SET FILE */
  1544.     return(setfil(rmsflg));
  1545.  
  1546. case XYFLOW:                /* FLOW-CONTROL */
  1547. /*
  1548.   Note: flotab[] keyword table (defined above) only includes the legal 
  1549.   flow-control options for each implementation, controlled by symbols
  1550.   defined in ckcdeb.h.
  1551. */
  1552.     if ((y = cmkey(flotab,nflo,"","xon/xoff",xxstring)) < 0) return(y);
  1553.     if ((x = cmcfm()) < 0) return(x);
  1554.     flow = y;
  1555. #ifdef CK_SPEED
  1556.     if (flow == FLO_XONX)        /* Xon/Xoff forces prefixing */
  1557.       ctlp[XON] = ctlp[XOFF] = ctlp[XON+128] = ctlp[XOFF+128] = 1;
  1558. #endif /* CK_SPEED */
  1559.     debug(F101,"set flow","",flow);
  1560.     return(success = 1);
  1561.  
  1562. case XYHAND:                /* HANDSHAKE */
  1563.     if ((y = cmkey(hshtab,nhsh,"","none",xxstring)) < 0) return(y);
  1564.     if (y == 998) {
  1565.     if ((x = cmnum("ASCII value","",10,&y,xxstring)) < 0)
  1566.       return(x);
  1567.     if ((y < 1) || ((y > 31) && (y != 127))) {
  1568.         printf("?Character must be in ASCII control range\n");
  1569.         return(-9);
  1570.     }
  1571.     }
  1572.     if ((x = cmcfm()) < 0) return(x);
  1573.     turn = (y > 0127) ? 0 : 1 ;
  1574.     turnch = y;
  1575.     return(success = 1);
  1576.  
  1577. #ifndef NOSPL
  1578. case XYMACR:                /* SET MACRO */
  1579.     if ((y = cmkey(smactab,2,"","",xxstring)) < 0) return(y);
  1580.     switch (y) {
  1581.       case 0: return(success = seton(&mecho));
  1582.       case 1: return(success = seton(&merror[cmdlvl]));
  1583.       default: return(-2);
  1584.     }
  1585. #endif /* NOSPL */
  1586.  
  1587. #ifndef NODIAL
  1588. case XYMODM:                /* SET MODEM */
  1589.     if ((x = cmkey(mdmtab,nmdm,"type of modem","none", xxstring)) < 0)
  1590.     return(x);
  1591.     if ((z = cmcfm()) < 0) return(z);
  1592.     mdmtyp = x;
  1593. #ifndef MINIDIAL
  1594.     tbmodel = 0;          /* If it's a Telebit, we don't know the model yet */
  1595. #endif /* MINIDIAL */
  1596.     return(success = 1);
  1597. #endif /* NODIAL */
  1598.  
  1599.   case XYMSGS:
  1600. #ifdef VMS
  1601.     if ((z = cmkey(onoff,2,"","",xxstring)) < 0) return(z);
  1602.     if ((y = cmcfm()) < 0) return(y);
  1603.     vms_msgs = z;
  1604.     printf("Sorry, SET MESSAGES not implemented yet\n");
  1605.     return(success = 0);
  1606. #endif /* VMS */
  1607. default:
  1608.     break;
  1609. }
  1610.  
  1611. switch (xx) {
  1612.     
  1613. case XYPARI:                /* PARITY */
  1614.     if ((y = cmkey(partbl,npar,"","none",xxstring)) < 0) return(y);
  1615.     if ((x = cmcfm()) < 0) return(x);
  1616.  
  1617. /* If parity not none, then we also want 8th-bit prefixing */
  1618.  
  1619.     if (parity = y) ebqflg = 1; else ebqflg = 0;
  1620.     return(success = 1);
  1621.  
  1622. #ifndef NOFRILLS
  1623. case XYPROM:                /* SET PROMPT */
  1624. /*
  1625.   Note: xxstring not invoked here.  Instead, it is invoked every time the
  1626.   prompt is issued.  This allows the prompt string to contain variables
  1627.   that can change, like \v(dir), \v(time), etc.
  1628. */
  1629. #ifdef MAC
  1630.     if ((x = cmtxt("Program's command prompt","Mac-Kermit>",&s,NULL)) < 0)
  1631. #else
  1632.     if ((x = cmtxt("Program's command prompt","C-Kermit>",&s,NULL)) < 0)
  1633. #endif /* MAC */
  1634.       return(x);
  1635.     s = brstrip(s);            /* Remove enclosing braces, if any */
  1636. #ifdef COMMENT
  1637. /*
  1638.   Let's not do this any more -- we don't do it anywhere else.
  1639. */
  1640.     else if (*s == '"') {        /* For compatibility with pre-5A */
  1641.     x = (int)strlen(s);
  1642.     if (s[x-1] == '"') {
  1643.         s[x-1] = NUL;
  1644.         s++;
  1645.     }
  1646.     }
  1647. #endif /* COMMENT */
  1648.     cmsetp(s);                /* Set the prompt */
  1649.     return(success = 1);
  1650. #endif /* NOFRILLS */
  1651.  
  1652. case XYRETR:                /* RETRY: per-packet retry limit */
  1653.     y = cmnum("Maximum retries per packet","10",10,&x,xxstring);
  1654.     if (x < 0) x = 0;
  1655.     if ((x = setnum(&maxtry,x,y,999)) < 0) return(x);
  1656.     if (maxtry <= wslotr) {
  1657.     printf("?Retry limit must be greater than window size\n");
  1658.     return(success = 0);
  1659.     }
  1660.     sprintf(tmpbuf,"%d",maxtry);
  1661.     if (rmsflg) {
  1662.     sstate = setgen('S', "403", tmpbuf, "");
  1663.     return((int) sstate);
  1664.     } else return(success = x);
  1665.  
  1666. #ifndef NOSERVER
  1667. case XYSERV:                /* SET SERVER items */
  1668.     if ((y = cmkey(srvtab,2,"","",xxstring)) < 0) return(y);
  1669.     switch (y) {
  1670.       case XYSERT:
  1671.     tp = tmpbuf;
  1672.         sprintf(tp,"%d",DSRVTIM);
  1673.     if ((y = cmnum("interval for server NAKs, 0 = none",tp,10,&x,
  1674.                xxstring)) < 0)
  1675.       return(y);
  1676.     if (x < 0) {
  1677.         printf("\n?Specify a positive number, or 0 for no server NAKs\n");
  1678.         return(0);
  1679.     }
  1680.     if ((y = cmcfm()) < 0) return(y);
  1681.     sprintf(tp,"%d",x);
  1682.     if (rmsflg) {
  1683.         sstate = setgen('S', "404", tp, "");
  1684.         return((int) sstate);
  1685.     } else {
  1686.         srvtim = x;            /* Set the server timeout variable */
  1687.         return(success = 1);
  1688.     }
  1689.       case XYSERD:            /* SERVER DISPLAY */
  1690.     return(success = seton(&srvdis)); /* ON or OFF... */
  1691.       default:
  1692.     return(-2);
  1693.     }
  1694. #endif /* NOSERVER */
  1695.  
  1696. #ifdef UNIX
  1697. #ifndef NOJC
  1698. case XYSUSP:                /* SET SUSPEND */
  1699.     seton(&suspend);            /* on or off... */
  1700.     return(success = 1);
  1701. #endif /* NOJC */
  1702. #endif /* UNIX */
  1703.  
  1704. case XYTAKE:                /* SET TAKE */
  1705.     if ((y = cmkey(taktab,4,"","",xxstring)) < 0) return(y);
  1706.     switch (y) {
  1707.       case 0: return(success = seton(&techo));
  1708. #ifndef NOSPL
  1709.       case 1: return(success = seton(&takerr[cmdlvl]));
  1710. #else
  1711.       case 1: return(success = seton(&takerr[tlevel]));
  1712. #endif /* NOSPL */
  1713.       case 2: techo = 0; return(success = 1); /* For compatibility with */
  1714.       case 3: techo = 1; return(success = 1); /* MS-DOS Kermit */
  1715.       default: return(-2);
  1716.     }
  1717.  
  1718. #ifndef NOSCRIPT
  1719. case XYSCRI:                /* SET SCRIPT */
  1720.     if ((y = cmkey(scrtab,1,"","echo",xxstring)) < 0) return(y);
  1721.     switch (y) {
  1722.       case 0: return(success = seton(&secho));
  1723.       default: return(-2);
  1724.     }
  1725. #endif /* NOSCRIPT */
  1726.  
  1727. default:
  1728.     break;
  1729. }
  1730.  
  1731. #ifndef NOLOCAL
  1732. switch (xx) {
  1733. case XYTERM:                /* SET TERMINAL */
  1734.     x = settrm();
  1735.     success = (x > 0) ? 1 : 0; 
  1736.     return(x);
  1737.  
  1738. default:
  1739.     break;
  1740. }
  1741. #endif /* NOLOCAL */
  1742.  
  1743. switch (xx) {
  1744.  
  1745. /* SET SEND/RECEIVE protocol parameters. */
  1746.  
  1747. case XYRECV:
  1748. case XYSEND:
  1749.     return(setsr(xx,rmsflg));
  1750.  
  1751. #ifndef NOLOCAL
  1752. #ifdef UNIX
  1753. case XYSESS:                /* SESSION-LOG */
  1754.     if ((x = cmkey(sfttab,nsfttab,"type of file","text",xxstring)) < 0)
  1755.       return(x);
  1756.     if ((y = cmcfm()) < 0) return(y);
  1757.     sessft = x;
  1758.     return(success = 1);
  1759. #endif /* UNIX */
  1760.  
  1761. case XYSPEE:                /* SET SPEED */
  1762.     if (network) {
  1763.     printf("\n?Speed cannot be set for network connections\n");
  1764.     return(success = 0);
  1765.     }
  1766.     lp = line;
  1767.     sprintf(lp,"Transmission rate for %s in bits per second",ttname);
  1768.  
  1769.     if ((x = cmkey(spdtab,nspd,line,"",xxstring)) < 0) {
  1770.     if (x == -3) printf("?value required\n");
  1771.     return(x);
  1772.     }
  1773.     if ((y = cmcfm()) < 0) return(y);
  1774.     if (!local) {
  1775.     printf("?Sorry, you must SET LINE first\n");
  1776.     return(success = 0);
  1777.     }
  1778.     zz = (long) x * 10L;
  1779.     if (zz == 70) zz = 75;        /* (see spdtab[] definition) */
  1780.     if (ttsspd(x) < 0)  {        /* Call ttsspd with cps, not bps! */
  1781.     printf("?Unsupported line speed - %ld\n",zz);
  1782.     return(success = 0);
  1783.     } else {
  1784.     speed = ttgspd();        /* Read it back */
  1785.     if (speed != zz)  {        /* Call ttsspd with cps, not bps! */
  1786.         printf("?SET SPEED fails, speed is %ld\n",speed);
  1787.         return(success = 0);
  1788.     }
  1789.     if (pflag &&
  1790. #ifndef NOSPL
  1791.         cmdlvl == 0
  1792. #else
  1793.         tlevel < 0
  1794. #endif /* NOSPL */
  1795.         ) {
  1796.         if (speed == 8880)
  1797.           printf("%s, 75/1200 bps\n",ttname);
  1798.         else
  1799.           printf("%s, %ld bps\n",ttname,speed);
  1800.     }
  1801.     return(success = 1);
  1802.     }
  1803. #endif /* NOLOCAL */
  1804.  
  1805.   case XYXFER:                /* SET TRANSFER */
  1806.     if ((y = cmkey(tstab,nts,"","character-set",xxstring)) < 0) return(y);
  1807. #ifdef XFRCAN
  1808.     if (y == 0) {            /* CANCELLATION */
  1809.     if ((z = cmkey(onoff,2,"","",xxstring)) < 0) return(z);
  1810.     if (z == 0) {            /* OFF */
  1811.         if ((y = cmcfm()) < 0) return(y);
  1812.         xfrcan = 0;
  1813.     } else {
  1814.         if ((y = cmnum("ASCII code for cancellation character","3",10,&x,
  1815.                xxstring)) < 0)
  1816.           return(y);
  1817.         if (x > 31 && x != 127) {
  1818.         printf("Cancel character must be in ASCII control range\n");
  1819.         return(-9);
  1820.         }
  1821.         if ((y = cmnum("How many required to cause cancellation",
  1822.                "2",10,&z, xxstring)) < 0)
  1823.           return(y);
  1824.         if (z < 2) {
  1825.         printf("Number must be 2 or greater\n");
  1826.         return(-9);
  1827.         }
  1828.         if ((y = cmcfm()) < 0) return(y);
  1829.         xfrcan = 1;            /* CANCELLATION ON */
  1830.         xfrchr = x;            /* Using this character */
  1831.         xfrnum = z;            /* Needing this many of them */
  1832.     }
  1833.     return(success = 1);
  1834.     } else
  1835. #endif /* XFERCAN */
  1836. #ifndef NOCSETS
  1837.       if (y == 1) {            /* CHARACTER-SET */
  1838.     if ((y = cmkey(tcstab,ntcs,"","transparent",xxstring)) < 0) return(y);
  1839.     if ((x = cmcfm()) < 0) return(x);
  1840.     if (rmsflg) {
  1841.         sstate = setgen('S', "405", tcsinfo[y].designator, "");
  1842.         return((int) sstate);
  1843.     } else {
  1844.         tslevel = (y == TC_TRANSP) ? 0 : 1; /* transfer syntax level */
  1845.         tcharset = y;        /* transfer character set */
  1846.         return(success = 1);
  1847.     }
  1848.     } else
  1849. #endif /* NOCSETS */
  1850.       if (y == 2) {            /* LOCKING-SHIFT */
  1851.       if ((y = cmkey(lstab,nls,"","on",xxstring)) < 0)
  1852.         return(y);
  1853.       if ((x = cmcfm()) < 0) return(x);
  1854.       lscapr = (y == 1) ? 1 : 0;    /* ON: requested = 1 */
  1855.       lscapu = (y == 2) ? 2 : 0;    /* FORCED:  used = 1 */
  1856.       return(success = 1);
  1857.       } else return(-2);
  1858.  
  1859. #ifndef NOXMIT
  1860.   case XYXMIT:                /* SET TRANSMIT */
  1861.     return(setxmit());
  1862. #endif /* NOXMIT */
  1863.  
  1864. #ifndef NOCSETS
  1865.   case XYUNCS:                /* UNKNOWN-CHARACTER-SET */
  1866.     if ((y = cmkey(ifdtab,2,"","discard",xxstring)) < 0) return(y);
  1867.     if ((x = cmcfm()) < 0) return(x);
  1868.     unkcs = y;
  1869.     return(success = 1);
  1870. #endif /* NOCSETS */
  1871.  
  1872. #ifndef NOPUSH
  1873. #ifdef UNIX
  1874.   case XYWILD:                /* WILDCARD-EXPANSION */
  1875.     if ((y = cmkey(wildtab,2,"who expands wildcards","kermit",xxstring)) < 0)
  1876.       return(y);
  1877.     if ((x = cmcfm()) < 0) return(x);
  1878.     wildxpand = y;
  1879.     return(success = 1);
  1880. #endif /* UNIX */
  1881. #endif /* NOPUSH */
  1882.  
  1883.   case XYWIND:                /* WINDOW-SLOTS */
  1884.     y = cmnum("Number of sliding-window slots, 1 to 32","1",10,&x,xxstring);
  1885.     y = setnum(&z,x,y,MAXWS);
  1886.     if (y < 0) return(y);
  1887.     if (z < 1) z = 1;
  1888. #ifdef COMMENT
  1889.     /* This is taken care of automatically now in protocol negotiation */
  1890.     if (maxtry < z) {
  1891.     printf("?Window slots must be less than retry limit\n");
  1892.     return(success = 0);
  1893.     }
  1894. #endif /* COMMENT */
  1895.     if (rmsflg) {            /* Set remote window size */
  1896.     wslotr = z;            /* Set local window size too */
  1897.     tp = tmpbuf;
  1898.     sprintf(tp,"%d",z);
  1899.     sstate = setgen('S', "406", tp, "");
  1900.     return((int) sstate);
  1901.     }
  1902.     wslotr = z;                /* Set local window size */
  1903.     swcapr = (wslotr > 1) ? 1 : 0;    /* Set window bit in capas word? */
  1904.     if (wslotr > 1) {            /* Window size > 1? */
  1905.     y = adjpkl(urpsiz,wslotr,bigrbsiz); /* Maybe adjust packet size */
  1906.     if (y != urpsiz) {        /* Did it change? */
  1907.         urpsiz = y;
  1908.         if (msgflg)
  1909.         printf(
  1910. " Adjusting receive packet-length to %d for %d window slots\n",
  1911.            urpsiz, wslotr);
  1912.     }
  1913.     }
  1914.     return(success = 1);
  1915.  
  1916. #ifndef NOSPL
  1917.   case XYOUTP:                /* OUTPUT command parameters */
  1918.     if ((y = cmkey(outptab,1,"OUTPUT command parameter","pacing",
  1919.            xxstring)) < 0)
  1920.       return(y);
  1921.     switch(y) {                /* Which parameter */
  1922.       case 0:                /* PACING */
  1923.     y = cmnum("Milliseconds to pause between each OUTPUT character","100",
  1924.           10,&x,xxstring);
  1925.     y = setnum(&z,x,y,16383);    /* Verify and get confirmation */
  1926.     if (y < 0) return(y);
  1927.     if (z < 0) z = 0;        /* (save some space) */
  1928.     pacing = z;
  1929.     return(success = 1);    
  1930.       default:                /* (shouldn't happen) */
  1931.     return(-2);
  1932.     }
  1933. #endif /* NOSPL */
  1934.  
  1935. #ifdef CK_SPEED
  1936.   case XYQCTL: {
  1937.     short *p;
  1938.     int zz;
  1939.     if ((z = cmkey(ctltab,2, "control-character prefixing option",""
  1940.            ,xxstring)) < 0)  
  1941.       return(z);
  1942.  
  1943.     /* Make space for a temporary copy of the prefixing table */
  1944.  
  1945.     p = (short *)malloc(256 * sizeof(short));
  1946.     if (!p) {
  1947.     printf("?Internal error - malloc failure\n");
  1948.     return(-9);
  1949.     }
  1950.     for (i = 0; i < 256; i++) p[i] = ctlp[i]; /* Copy current table */
  1951.  
  1952.     switch(z) {
  1953.       case 0:                /* UNPREFIXED control character */
  1954.       case 1:                /* PREFIXED control character */
  1955.     while (1) {        /* Collect a list of numbers */
  1956.         if ((x = cmnum((z == 0) ?
  1957. "\n Numeric ASCII value of control character that needs NO prefix,\n\
  1958.  or the word \"all\", or carriage return to complete the list" :
  1959. "\n Numeric ASCII value of control character that MUST BE prefixed,\n\
  1960.  or the word \"all\", or carriage return to complete the list",
  1961.                "",10,&y,xxstring
  1962.                )) < 0) {
  1963.         if (x == -3)
  1964.           break;
  1965.         if (x == -2) {
  1966.             if (p) free(p);
  1967.             debug(F110,"SET CONTROL atmbuf",atmbuf,0);
  1968.             if (!xxstrcmp(atmbuf,"all",3) ||
  1969.             !xxstrcmp(atmbuf,"al",2) ||
  1970.             !xxstrcmp(atmbuf,"a",1)) {
  1971.             if ((x = cmcfm()) < 0) /* Get confirmation */
  1972.               return(x);
  1973.             /* Set all values, but don't touch 0 */
  1974.             for (y = 1; y < 32; y++) ctlp[y] = z;
  1975.             for (y = 127; y < 160; y++) ctlp[y] = z;
  1976.             ctlp[255] = z;
  1977.             /* Watch out for XON and XOFF */
  1978.             if (flow == FLO_XONX && z == 0) {
  1979.                 if (msgflg) {
  1980.                 printf(
  1981. " XON/XOFF characters 17, 19, 145, 147 not affected.\n");
  1982.                 printf(
  1983. #ifdef CK_RTSCTS
  1984. " SET FLOW NONE or RTS/CTS to transmit these characters unprefixed.\n"
  1985. #else
  1986. " SET FLOW NONE to transmit these characters unprefixed.\n"
  1987. #endif /* CK_RTSCTS */
  1988.                        );
  1989.                 }
  1990.                 ctlp[XON] =
  1991.                   ctlp[XOFF] =
  1992.                 ctlp[XON+128] =
  1993.                   ctlp[XOFF+128] = 1;
  1994.             }
  1995. #ifdef TNCODE
  1996.             /* Watch out for TELNET IAC */
  1997.             if (network && (ttnproto == NP_TELNET) && z == 0) {
  1998.                 ctlp[255] = 1;
  1999.                 if (parity == 'e' || parity == 'm') ctlp[127] = 1;
  2000.                 ctlp[13] = 1;
  2001.                 if (msgflg)
  2002.                   printf(
  2003.                    " TELNET IAC = 255, CR = 13, not affected.\n");
  2004.             }
  2005. #endif /* TNCODE */
  2006.             return(success = 1);
  2007.             } else {
  2008.             printf("?Please specify a number or the word ALL\n");
  2009.             return(-9);
  2010.             }
  2011.         } else {
  2012.             if (p) free(p);
  2013.             return(x);
  2014.         }
  2015.         }
  2016.         zz = 1 - z;
  2017.         if ((y >  31 && y < 127) ||    /* A specific numeric value */
  2018.         (y > 159 && y < 255) ||    /* Check that it is a valid */
  2019.         (y < zz) ||        /* control code. */
  2020.         (y > 255)) {
  2021.         printf("?Values allowed are: %d-31, 127-159, 255\n",zz);
  2022.         if (p) free(p);
  2023.         return(-9);
  2024.         }
  2025.         x = y & 127;        /* Get 7-bit value */
  2026.         if ((z == 0) &&        /* If they are saying it is safe... */
  2027.         (y == 0    ||        /* NUL = string terminator isn't */
  2028.          ((flow == FLO_XONX) &&    /* If flow control is Xon/Xoff */
  2029.           (x == XON || x == XOFF)) /* XON & XOFF chars not safe. */
  2030.          )) {
  2031.         if (msgflg)
  2032.           printf("Sorry, not while Xon/Xoff is in effect.\n");
  2033.         if (p) free(p);
  2034.         return(-9);
  2035.         }
  2036.         p[y] = z;            /* All OK, set flag */
  2037.     }                /* End of while loop */
  2038. /*
  2039.   Get here only if they have made no mistakes.  Copy temporary table back to
  2040.   permanent one, then free temporary table and return successfully.
  2041. */
  2042.     for (i = 0; i < 256; i++) ctlp[i] = p[i];
  2043.     if (p) free(p);
  2044.     return(success = 1);
  2045.       default:
  2046.     return(-2);
  2047.     }
  2048. }
  2049. #endif /* CK_SPEED */
  2050.  
  2051.   case XYREPT:
  2052.     if ((y = cmkey(rpttab,2,"repeat-count compression parameter","",xxstring))
  2053.     < 0)
  2054.       return(y);
  2055.     switch(y) {
  2056.       case 0:
  2057.     return(success = seton(&rptena)); /* REPEAT COUNTS = ON, OFF */
  2058.       case 1:                /* REPEAT MININUM number */
  2059.     printf("(not implemented yet, nothing happens)\n");
  2060.     return(-9);
  2061.       case 2:                /* REPEAT PREFIX char */
  2062.     if ((x = cmnum("ASCII value","",10,&z,xxstring)) < 0)
  2063.       return(x);
  2064.     if ((x = cmcfm()) < 0) return(x);
  2065.     if ((z > 32 && z < 63) || (z > 95 && z < 127)) {
  2066.         if (y == 1) rptmin = (CHAR) z; else myrptq = (CHAR) z;
  2067.         return(success = 1); 
  2068.     } else {
  2069.         printf("?Illegal value for prefix character\n");
  2070.         return(-9);
  2071.     }
  2072.     }
  2073.  
  2074. default:
  2075.     if ((x = cmcfm()) < 0) return(x);
  2076.     printf("Not working yet - %s\n",cmdbuf);
  2077.     return(success = 0);
  2078.     }
  2079. }
  2080.  
  2081. #ifdef CK_TTYFD
  2082. extern int ttyfd;
  2083. #endif /* CK_TTYFD */ 
  2084.  
  2085. extern struct keytab yesno[];
  2086. extern int nyesno;
  2087.  
  2088. int
  2089. hupok(x) int x; {            /* Returns 1 if OK, 0 if not OK */
  2090.     int y, z = 1;
  2091.     if (local && xitwarn) {        /* Is a connection open? */
  2092.     int needwarn = 0;
  2093.     if (
  2094. #ifdef NETCONN
  2095.         network
  2096. #else
  2097.         0
  2098. #endif /* NETCONN */
  2099.         ) {        /* Network? */
  2100. #ifdef CK_TTYFD
  2101.         if (ttyfd > -1)
  2102. #endif /* CK_TTYFD */
  2103.           needwarn = 1;
  2104.         if (needwarn)
  2105.           printf(
  2106. " A network connection to %s might still be active.\n",
  2107.              ttname
  2108.              );
  2109.     } else {            /* Serial connection */
  2110.         if (carrier == CAR_OFF)    /* SET CARRIER OFF */
  2111.           needwarn = 0;        /* so we don't care about carrier. */
  2112.         else if ((y = ttgmdm()) > 0) /* Otherwise, get modem signals */
  2113.           needwarn = (y & BM_DCD);    /* Check for carrier */
  2114.         else            /* If we can't get modem signals... */
  2115.           needwarn =
  2116. #ifdef CK_TTYFD 
  2117.         (ttyfd > -1)        /* check tty file descriptor */
  2118. #else
  2119.           1            /* or can't check ttyfd, then warn */
  2120. #endif /* CK_TTYFD */ 
  2121.             ;
  2122.         if (needwarn)
  2123.           printf(
  2124. " A serial connection might still be active on %s.\n",
  2125.              ttname
  2126.              );
  2127.     }
  2128.  
  2129. /* If a warning was issued, get user's permission to EXIT. */
  2130.  
  2131.     if (needwarn) {
  2132. #ifdef VMS
  2133. /*
  2134.   In VMS, whenever a TAKE file or macro is active, we restore the 
  2135.   original console modes so Ctrl-C/Ctrl-Y can work.  But here we
  2136.   go interactive again, so we have to temporarily put them back.
  2137. */
  2138.         if (cmdlvl > 0)
  2139.           concb((char)escape);
  2140. #endif /* VMS */
  2141.       
  2142.         cmsavp(psave,PROMPTL);    /* Save old prompt */
  2143.         cmsetp(x ? "OK to close? " : "OK to exit? "); /* Make new prompt */
  2144.         z = 0;            /* Initialize answer to No. */
  2145.         cmini(ckxech);        /* Initialize parser. */
  2146.         do {
  2147.         prompt(NULL);        /* Issue prompt. */
  2148.         y = cmkey(yesno,nyesno,"","",NULL); /* Get Yes or No */
  2149.         if (y < 0) {
  2150.             if (y == -3)     /* No answer? */
  2151.               printf(" Please respond Yes or No\n");
  2152.             cmini(ckxech);
  2153.         } else {
  2154.             z = y;        /* Save answer */
  2155.             y = cmcfm();    /* Get confirmation */
  2156.         }
  2157.         } while (y < 0);        /* Continue till done */
  2158.         cmsetp(psave);        /* Restore real prompt */
  2159. #ifdef VMS
  2160.         if (cmdlvl > 0)        /* In VMS and not at top level, */
  2161.           conres();            /*  restore console again. */
  2162. #endif /* VMS */
  2163.     }
  2164.     }
  2165.     return(z);
  2166. }
  2167.  
  2168. VOID
  2169. shoctl() {                /* SHOW CONTROL-PREFIXING */
  2170. #ifdef CK_SPEED
  2171.     int i;
  2172.     printf(
  2173. "\ncontrol quote = %d, applied to (0 = unprefixed, 1 = prefixed):\n\n",
  2174.        myctlq);
  2175.     for (i = 0; i < 16; i++) {
  2176.     printf("  %3d: %d   %3d: %d ",i,ctlp[i], i+16, ctlp[i+16]);
  2177.     if (i == 15)
  2178.       printf("  127: %d",ctlp[127]);
  2179.     else
  2180.       printf("        ");
  2181.     printf("  %3d: %d   %3d: %d ",i+128,ctlp[i+128], i+144, ctlp[i+144]);
  2182.     if (i == 15)  printf("  255: %d",ctlp[255]);
  2183.     printf("\n");
  2184.     }
  2185.     printf("\n");
  2186. #endif /* CK_SPEED */
  2187. }
  2188.  
  2189. #ifndef NOPUSH
  2190. #ifdef CK_REXX
  2191. /*
  2192.   Rexx command.  Note, this is not OS/2-specific, because Rexx also runs
  2193.   on other systems where C-Kermit also runs, like the Amiga.
  2194. */
  2195. #define REXBUFL 100            /* Change this if neccessary */
  2196. char rexxbuf[REXBUFL] = { '\0' };    /* Rexx's return value (string) */
  2197.  
  2198. int
  2199. dorexx() {
  2200.     int x, y;
  2201.     char *rexxcmd;
  2202.  
  2203.     if ((x = cmtxt("Rexx command","",&rexxcmd,xxstring)) < 0)    
  2204.       return(x);
  2205.     strcpy(line,rexxcmd);
  2206.     rexxcmd = line;
  2207. #ifdef OS2
  2208.     return(os2rexx(rexxcmd,rexxbuf,REXBUFL));
  2209. #else /* !OS2 */
  2210.     printf("Sorry, nothing happens.\n");
  2211.     return(success = 0);
  2212. #endif /* OS2 */
  2213. }
  2214. #endif /* CK_REXX */
  2215. #endif /* NOPUSH */
  2216. #endif /* NOICP */
  2217.