home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / ckc190.zip / ckuus7.c < prev    next >
C/C++ Source or Header  |  1994-11-12  |  80KB  |  2,728 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, 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. /*
  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.  
  34. #ifdef STRATUS                /* Stratus Computer, Inc.  VOS */
  35. #ifdef putchar
  36. #undef putchar
  37. #endif /* putchar */
  38. #define putchar(x) conoc(x)
  39. #ifdef getchar
  40. #undef getchar
  41. #endif /* getchar */
  42. #define getchar(x) coninc(0)
  43. #endif /* STRATUS */
  44.  
  45. static int x, y = 0, z;
  46. static char *s;
  47.  
  48. #ifdef CK_SPEED
  49. extern short ctlp[];            /* Control-char prefixing table */
  50. #endif /* CK_SPEED */
  51.  
  52. #ifdef NETCONN
  53. static int mdmsav = -1;            /* Save modem type around network */
  54. static int oldplex = -1;        /* Duplex holder around network */
  55. #endif /* NETCONN */
  56.  
  57. extern xx_strp xxstring;
  58.  
  59. extern int success, nfilp, fmask, fncnv, frecl, binary, warn, msgflg;
  60. extern int cmask, maxrps, wslotr, bigsbsiz, bigrbsiz, urpsiz, rpsiz, spsiz;
  61. extern int spsizr, spsizf, maxsps, spmax, pflag, bctr, npad, timef, timint;
  62. extern int pkttim, rtimo, local, nfils, displa, atcapr, nettype, escape;
  63. extern int mdmtyp, duplex, dfloc, network, cdtimo, fncact, mypadn;
  64. extern int tnlm, sosi, tlevel, lf_opts, backgrd, flow, fdispla;
  65. extern int fnrpath, fnspath, debses, parity, pktpaus;
  66. extern int
  67.   atenci, atenco, atdati, atdato, atleni, atleno, atblki, atblko,
  68.   attypi, attypo, atsidi, atsido, atsysi, atsyso, atdisi, atdiso; 
  69.  
  70. #ifdef STRATUS
  71. extern int atfrmi, atfrmo, atcrei, atcreo, atacti, atacto;
  72. #endif /* STRATUS */
  73.  
  74. extern long speed;
  75.  
  76. extern CHAR sstate, eol, seol, stchr, mystch, mypadc, padch, ctlq, myctlq;
  77.  
  78. extern char *cmarg, *cmarg2, *dftty;
  79.  
  80. extern char *tp, *lp;            /* Temporary buffer & pointers */
  81. #ifndef NOFRILLS
  82. extern char optbuf[];            /* Buffer for MAIL or PRINT options */
  83. extern int rprintf;            /* REMOTE PRINT flag */
  84. #endif /* NOFRILLS */
  85. extern char ttname[];
  86. #ifdef NPIPE
  87. extern char pipename[];
  88. #endif /* NPIPE */
  89.  
  90. extern struct keytab onoff[], filtab[], rltab[];
  91. extern int nrlt;
  92.  
  93. static struct keytab fttab[] = {    /* File types for SET FILE TYPE */
  94.     "ascii",     XYFT_B, CM_INV,
  95. #ifdef VMS
  96.     "b",         XYFT_B, CM_INV|CM_ABR,
  97. #endif /* VMS */
  98.     "binary",    XYFT_B, 0,
  99. #ifdef VMS
  100.     "block",     XYFT_I, CM_INV,
  101.     "image",     XYFT_I, 0,
  102. #endif /* VMS */
  103. #ifdef CK_LABELED
  104.     "labeled",   XYFT_L, 0,
  105. #endif /* CK_LABELED */
  106. #ifdef MAC
  107.     "macbinary", XYFT_M, 0,
  108. #endif /* MAC */
  109.     "text",      XYFT_T, 0
  110. };
  111. static int nfttyp = (sizeof(fttab) / sizeof(struct keytab));
  112.  
  113. static struct keytab rfttab[] = {    /* File types for REMOTE SET FILE */
  114.     "ascii",     XYFT_B, CM_INV,
  115.     "binary",    XYFT_B, 0,
  116. #ifdef VMS
  117.     "labeled",   XYFT_L, 0,
  118. #else
  119. #ifdef OS2
  120.     "labeled",   XYFT_L, 0,
  121. #endif /* OS2 */
  122. #endif /* VMS */
  123.     "text",      XYFT_T, 0
  124. };
  125. static int nrfttyp = (sizeof(rfttab) / sizeof(struct keytab));
  126.  
  127. #ifndef NOSPL
  128. int query = 0;                /* Global flag for QUERY active */
  129.  
  130. static struct keytab vartyp[] = {    /* Variable types for REMOTE QUERY */
  131. "global", (int) 'G', CM_INV,
  132. "kermit", (int) 'K', 0,
  133. "system", (int) 'S', 0,
  134. "user",   (int) 'G', 0
  135. };
  136. static int nvartyp = (sizeof(vartyp) / sizeof(struct keytab));
  137.  
  138. #endif /* NOSPL */
  139.  
  140. #ifdef DCMDBUF
  141. extern char *atxbuf;            /* Atom buffer */
  142. extern char *cmdbuf;            /* Command buffer */
  143. extern char *line, *tmpbuf;        /* Character buffers for anything */
  144. extern int *intime;            /* INPUT TIMEOUT */
  145. #ifdef CK_CURSES
  146. /* This needs cleaning up... */
  147. #ifdef UNIX
  148. extern char *trmbuf;            /* Termcap buffer */
  149. #endif /* UNIX */
  150. #ifdef OS2
  151. extern char *trmbuf;            /* Termcap buffer */
  152. #endif /* OS2 */
  153. #ifdef OSK
  154. extern char *trmbuf;            /* Termcap buffer */
  155. #endif /* OSK */
  156. #ifdef AMIGA
  157. extern char *trmbuf;            /* Termcap buffer */
  158. #endif /* AMIGA */
  159. #ifdef STRATUS
  160. extern char *trmbuf;            /* Termcap buffer */
  161. #endif /* STRATUS */
  162. #endif /* CK_CURSES */
  163. #else
  164. extern char atxbuf[];            /* Atom buffer */
  165. extern char cmdbuf[];            /* Command buffer */
  166. extern char line[], tmpbuf[];        /* Character buffer for anything */
  167. extern int intime[];
  168. #ifdef CK_CURSES
  169. #ifdef UNIX
  170. extern char trmbuf[];            /* Termcap buffer */
  171. #endif /* UNIX */
  172. #endif /* CK_CURSES */
  173. #endif /* DCMDBUF */
  174.  
  175. #ifndef NOCSETS
  176. extern struct keytab fcstab[];        /* For SET FILE CHARACTER-SET */
  177. extern struct keytab ttcstab[];
  178. extern int nfilc, fcharset, ntermc, tcsr, tcsl;
  179. #ifdef OS2
  180. _PROTOTYP( int os2setcp, (int) );
  181. _PROTOTYP( int os2getcp, (void) );
  182. _PROTOTYP( void os2debugoff, (void) );
  183. _PROTOTYP( int os2settitle, (char *) );
  184. static int savtcsr = -1, savtcsl = -1, savfcs = -1, savcp = -1;
  185. #endif /* OS2 */
  186. #endif /* NOCSETS */
  187.  
  188. #ifndef NOSPL
  189. extern int cmdlvl;            /* Overall command level */
  190. #ifdef DCMDBUF
  191. extern int *inpcas;            /* INPUT CASE setting on cmd stack */
  192. #else
  193. extern int inpcas[];
  194. #endif /* DCMDBUF */
  195. #endif /* NOSPL */
  196.  
  197. #ifdef TNCODE
  198. extern int tn_init;
  199. #endif /* TNCODE */
  200.  
  201. #ifdef ANYX25
  202. extern int revcall, closgr, cudata, nx25, npadx3;
  203. extern char udata[MAXCUDATA];
  204. extern CHAR padparms[MAXPADPARMS+1];
  205. extern struct keytab x25tab[], padx3tab[];
  206. #endif /* ANYX25 */
  207.  
  208. #ifdef CK_CURSES
  209. #ifndef VMS
  210. #ifndef COHERENT
  211. _PROTOTYP(int tgetent,(char *, char *));
  212. #endif /* COHERENT */
  213. #endif /* VMS */
  214. #endif /* CK_CURSES */
  215.  
  216. #ifndef NODIAL
  217. extern int dialhng, dialtmo, dialksp, dialdpy, dialmnp, dialmhu;
  218. extern int mdmspd;
  219. extern char *dialini, *dialdir, *dialcmd, *dialnpr;
  220. extern FILE * dialfd;
  221.  
  222.  
  223. struct keytab dialtab[] = {
  224.     "dial-command", XYDDIA, 0,
  225.     "directory", XYDDIR, 0,
  226.     "display", XYDDPY, 0,
  227.     "hangup",  XYDHUP, 0,
  228.     "init-string", XYDINI, 0,
  229. #ifdef COMMENT
  230.     "hup-string", XYDHCM, 0,
  231. #endif /* COMMENT */
  232.     "kermit-spoof", XYDKSP, 0,
  233.     "mnp-enable", XYDMNP, 0,
  234. #ifdef MDMHUP
  235.     "modem-hangup", XYDMHU, 0,
  236. #endif /* MDMHUP */
  237.     "prefix", XYDNPR, 0,
  238.     "speed-matching", XYDSPD, 0,
  239.     "timeout", XYDTMO, 0
  240. };
  241. int ndial = (sizeof(dialtab) / sizeof(struct keytab));
  242. #endif /* NODIAL */
  243.  
  244. #ifndef NOXMIT
  245. /* set transmit */
  246. #define XMITF 0
  247. #define XMITL 1
  248. #define XMITP 2
  249. #define XMITE 3
  250. #define XMITX 4
  251. #define XMITS 5
  252. #define XMITW 6
  253.  
  254. #define XMBUFL 50
  255. extern int xmitf, xmitl, xmitp, xmitx, xmits, xmitw;
  256. char xmitbuf[XMBUFL+1] = { NUL };    /* TRANSMIT eof string */
  257.  
  258. struct keytab xmitab[] = {
  259.     "echo",     XMITX, 0,
  260.     "eof",      XMITE, 0,
  261.     "fill",     XMITF, 0,
  262.     "linefeed", XMITL, 0,
  263.     "locking-shift", XMITS, 0,
  264.     "pause",    XMITW, 0,
  265.     "prompt",   XMITP, 0
  266. };
  267. int nxmit = (sizeof(xmitab) / sizeof(struct keytab));
  268. #endif /* NOXMIT */
  269.  
  270. /* For SET FILE COLLISION */
  271. /* Some of the following may be possible for some C-Kermit implementations */
  272. /* but not others.  Those that are not possible for your implementation */
  273. /* should be ifdef'd out. */
  274.  
  275. struct keytab colxtab[] = { /* SET FILE COLLISION options */
  276. #ifndef MAC
  277.     "append",    XYFX_A, 0,  /* append to old file */
  278. #endif /* MAC */
  279. #ifdef COMMENT
  280.     "ask",       XYFX_Q, 0,  /* ask what to do (not implemented) */
  281. #endif
  282.     "backup",    XYFX_B, 0,  /* rename old file */
  283. #ifndef MAC
  284.     /* This crashes Mac Kermit. */
  285.     "discard",   XYFX_D, 0,  /* don't accept new file */
  286.     "no-supersede", XYFX_D, CM_INV, /* ditto (MSK compatibility) */
  287. #endif /* MAC */
  288.     "overwrite", XYFX_X, 0,  /* overwrite the old file == file warning off */
  289.     "rename",    XYFX_R, 0,  /* rename the incoming file == file warning on */
  290. #ifndef MAC
  291.     /* This crashes Mac Kermit. */
  292.     "update",    XYFX_U, 0,  /* replace if newer */
  293. #endif /* MAC */
  294. };
  295. int ncolx = (sizeof(colxtab) / sizeof(struct keytab));
  296.  
  297. static struct keytab rfiltab[] = {    /* for REMOTE SET FILE */
  298.     "collision",     XYFILX, 0,
  299.     "names",         XYFILN, 0,
  300.     "record-length", XYFILR, 0,
  301.     "type",          XYFILT, 0
  302. };
  303. int nrfilp = (sizeof(rfiltab) / sizeof(struct keytab));
  304.  
  305. struct keytab fntab[] = {           /* File naming */
  306.     "converted", 1, 0,
  307.     "literal",   0, 0
  308. };
  309.  
  310. #ifndef NOLOCAL
  311. /* Terminal parameters table */
  312. struct keytab trmtab[] = {
  313. #ifdef OS2
  314.     "answerback",    XYTANS, 0,
  315. #endif /* OS2 */
  316. #ifdef CK_APC
  317.     "apc",           XYTAPC, 0,
  318. #endif /* CK_APC */
  319. #ifdef OS2
  320.     "arrow-keys",    XYTARR, 0,
  321. #endif /* OS2 */
  322. #ifdef OS2
  323.     "bell",          XYTBEL, 0,
  324. #endif /* OS2 */
  325.     "bytesize",      XYTBYT, 0,
  326. #ifndef NOCSETS
  327.     "character-set", XYTCS,  0,
  328. #endif /* NOCSETS */
  329. #ifdef OS2
  330.     "code-page",     XYTCPG, 0,
  331.     "color",         XYTCOL, 0,
  332. #endif /* OS2 */
  333.     "cr-display",    XYTCRD, 0,
  334. #ifdef OS2
  335.     "cursor",        XYTCUR, 0,
  336. #endif /* OS2 */
  337.     "debug",         XYTDEB, 0,
  338.     "echo",          XYTEC,  0,
  339. #ifdef OS2
  340.     "hide-cursor",   XYTHCU, 0,
  341.     "keypad-mode",   XYTKPD, 0,
  342. #endif /* OS2 */
  343.     "locking-shift", XYTSO,  0,
  344. #ifdef OS2MOUSE
  345.     "mouse",         XYTMOU, 0,
  346. #endif /* OS2MOUSE */
  347.     "newline-mode",  XYTNL,  0
  348. #ifdef OS2
  349. ,   "output-pacing", XYTPAC, 0,
  350.     "roll",          XYTROL, 0,
  351.     "scrollback",    XYSCRS, 0,
  352.     "transmit-timeout", XYTCTS, 0,
  353.     "type",          XYTTYP, 0,
  354.     "wrap",          XYTWRP, 0
  355. #endif /* OS2 */
  356. };
  357. int ntrm = (sizeof(trmtab) / sizeof(struct keytab));
  358.  
  359. struct keytab crdtab[] = {        /* Carriage-return display */
  360.     "crlf",        1, 0,
  361.     "normal",      0, 0
  362. };
  363. extern int tt_crd;            /* Carriage-return display variable */
  364.  
  365. #ifdef CK_APC
  366. extern int apcstatus, apcactive;
  367. static struct keytab apctab[] = {    /* Terminal APC parameters */
  368.     "off",     APC_OFF,  0,
  369.     "on",     APC_ON,   0,
  370.     "unchecked", APC_UNCH, 0
  371. };
  372. #endif /* CK_APC */
  373. #endif /* NOLOCAL */
  374.  
  375. #ifdef OS2
  376. /*
  377.   OS/2 serial communication devices.
  378. */
  379. struct keytab os2devtab[] = {
  380.     "1",    1, CM_INV,            /* Invisible synonyms, like */
  381.     "2",    2, CM_INV,            /* "set port 1" */
  382.     "3",    3, CM_INV,
  383.     "4",    4, CM_INV,
  384.     "5",    5, CM_INV,
  385.     "6",    6, CM_INV,
  386.     "7",    7, CM_INV,
  387.     "8",    8, CM_INV,
  388.     "com1", 1, 0,            /* Real device names */
  389.     "com2", 2, 0,
  390.     "com3", 3, 0,
  391.     "com4", 4, 0,
  392.     "com5", 5, 0,
  393.     "com6", 6, 0,
  394.     "com7", 7, 0,
  395.     "com8", 8, 0
  396. };
  397. int nos2dev = (sizeof(os2devtab) / sizeof(struct keytab));
  398.  
  399. /*
  400.   Terminal parameters that can be set by SET commands.
  401.   Used by the ck?con.c terminal emulator code.  
  402.   For now, only use for OS/2.  Should add these for Macintosh.
  403. */
  404. int tt_arrow = TTK_NORM;        /* Arrow key mode: normal (cursor) */
  405. int tt_keypad = TTK_NORM;        /* Keypad mode: normal (numeric) */
  406. int tt_wrap = 1;            /* Terminal wrap, 1 = On */
  407. int tt_type = TT_VT220;            /* Terminal type, initially VT220 */
  408. int tt_cursor = 0;            /* Terminal cursor, 0 = Underline */
  409. int tt_answer = 0;            /* Terminal answerback (disabled) */
  410. int tt_scrsize = 240;                   /* Terminal scrollback buffer size */
  411. int tt_bell = 1;            /* Terminal bell (audible) */
  412. int tt_roll = 0;            /* Terminal roll (off) */
  413. int tt_pacing = 0;            /* Terminal output-pacing (none) */
  414. int tt_hide = 1;            /* Terminal hide-cursor (on) */
  415. int tt_ctstmo = 15;            /* Terminal transmit-timeout */
  416. int tt_codepage = -1;            /* Terminal code-page */
  417. int tt_mouse = 0;            /* Terminal mouse */
  418. static int savcolor = 0;        /* Terminal color */
  419. static int savcmask = 0;        /* For saving terminal bytesize */
  420. extern int colornormal, colorreverse,
  421.  colorunderline, colorstatus, colorhelp, colorborder, scrninitialised;
  422.  
  423. struct keytab beltab[] = {        /* Terminal bell mode */
  424.     "audible", 1, 0,
  425.     "none",    0, 0,
  426.     "visible", 2, 0
  427. };
  428. struct keytab akmtab[] = {        /* Arrow key mode */
  429.     "application", TTK_APPL, 0,
  430.     "cursor",      TTK_NORM, 0
  431. };
  432. struct keytab kpmtab[] = {        /* Keypad mode */
  433.     "application", TTK_APPL, 0,
  434.     "numeric",     TTK_NORM, 0
  435. };
  436.  
  437. struct keytab ttycoltab[] = {        /* Screen coloring during CONNECT */
  438.     "border",             5, 0,        /* Screen border */
  439.     "help-text",          4, 0,        /* Help screens */
  440.     "normal",             0, CM_INV,    /* Normal screen text */
  441.     "reverse-video",      1, CM_INV,    /* Reverse video */
  442.     "status-line",        3, 0,        /* Status line */
  443.     "terminal-screen",    0, 0,        /* Better name than "normal" */
  444.     "underlined-text",    2, 0        /* Underlined text */
  445. };
  446. int ncolors = (sizeof(ttycoltab) / sizeof(struct keytab));
  447.  
  448. struct keytab ttyclrtab[] = {        /* Colors */
  449.     "black",       0, 0,
  450.     "blue",        1, 0,
  451.     "brown",       6, 0,
  452.     "cyan",        3, 0,
  453.     "dgray",       8, 0,
  454.     "green",       2, 0,
  455.     "lblue",       9, 0,
  456.     "lcyan",      11, 0,
  457.     "lgray",       7, 0,
  458.     "lgreen",     10, 0,
  459.     "lmagenta",   13, 0,
  460.     "lred",       12, 0,
  461.     "magenta",     5, 0,
  462.     "red",         4, 0,
  463.     "white",      15, 0,
  464.     "yellow",     14, 0
  465. };
  466. int nclrs = 16;
  467.  
  468. struct keytab ttycurtab[] = {
  469.     "full",        2, 0,
  470.     "half",        1, 0,
  471.     "underline",   0, 0
  472. };
  473. int ncursors = 3;
  474.  
  475. struct keytab ttyptab[] = {
  476.     "ansi",    TT_ANSI,  0,        /* ANSI.SYS (BBS) */
  477. /*
  478.   The idea of NONE is to let the console driver handle the escape sequences,
  479.   which, in theory at least, would give not only ANSI emulation, but also any
  480.   other kind of emulation that might be provided by alternative console
  481.   drivers, if any existed.
  482.  
  483.   For this to work, ckocon.c would need to be modified to make higher-level
  484.   calls, like VioWrtTTY(), DosWrite(), or (simply) write(), rather than
  485.   VioWrt*Cell() and similar, and it would also have to give up its rollback
  486.   feature, and its status line and help screens would also have to be
  487.   forgotten or else done in an ANSI way.
  488.  
  489.   As matters stand, we already have perfectly good ANSI emulation built in,
  490.   and there are no alternative console drivers available, so there is no point
  491.   in having a terminal type of NONE, so it is commented out.  However, should
  492.   you uncomment it, it will work like a "glass tty" -- no escape sequence
  493.   interpretation at all; somewhat similar to debug mode, except without the
  494.   debugging (no highlighting of control chars or escape sequences); help
  495.   screens, status line, and rollback will still work.
  496. */
  497. #ifdef COMMENT
  498.     "none",    TT_NONE,  0,
  499. #endif /* COMMENT */
  500. #ifdef OS2PM
  501. #ifdef COMMENT
  502.     "tek4014", TT_TEK40, 0,
  503. #endif /* COMMENT */
  504. #endif /* OS2PM */
  505.     "vt100",   TT_VT100, 0,
  506.     "vt102",   TT_VT102, 0,
  507.     "vt220",   TT_VT220, 0,
  508. #ifdef COMMENT
  509.     /* Let's not get carried away! */
  510.     "vt320",   TT_VT320, 0,
  511. #endif /* COMMENT */
  512.     "vt52",    TT_VT52,  0
  513. };
  514. int nttyp = (sizeof(ttyptab) / sizeof(struct keytab));
  515. #endif /* OS2 */
  516.  
  517. /* #ifdef VMS */
  518. struct keytab fbtab[] = {        /* Binary record types for VMS */
  519.     "fixed",     XYFT_B, 0,        /* Fixed is normal for binary */
  520.     "undefined", XYFT_U, 0        /* Undefined if they ask for it */
  521. };
  522. int nfbtyp = (sizeof(fbtab) / sizeof(struct keytab));
  523. /* #endif */
  524.  
  525. #ifdef VMS
  526. struct keytab lbltab[] = {        /* Labeled File info */
  527.     "acl",         LBL_ACL, 0,
  528.     "backup-date", LBL_BCK, 0,
  529.     "name",        LBL_NAM, 0,
  530.     "owner",       LBL_OWN, 0,
  531.     "path",        LBL_PTH, 0
  532. };
  533. int nlblp = (sizeof(lbltab) / sizeof(struct keytab));
  534. #else
  535. #ifdef OS2
  536. struct keytab lbltab[] = {        /* Labeled File info */
  537.     "archive",   LBL_ARC, 0,
  538.     "extended",  LBL_EXT, 0,
  539.     "hidden",    LBL_HID, 0,
  540.     "read-only", LBL_RO,  0,
  541.     "system",    LBL_SYS, 0
  542. };
  543. int nlblp = (sizeof(lbltab) / sizeof(struct keytab));
  544. #endif /* OS2 */
  545. #endif /* VMS */
  546.  
  547. #ifdef CK_CURSES
  548. #ifdef CK_PCT_BAR
  549. static struct keytab fdftab[] = {    /* SET FILE DISPLAY FULL options */
  550.     "thermometer", 1, 0,
  551.     "no-thermometer", 0, 0
  552. };
  553. extern int thermometer;
  554. #endif /* CK_PCT_BAR */
  555. #endif /* CK_CURSES */
  556.  
  557. static struct keytab fdtab[] = {    /* SET FILE DISPLAY options */
  558. #ifdef MAC                /* Macintosh */
  559.     "fullscreen", XYFD_R, 0,        /* Full-screen but not curses */
  560.     "none",   XYFD_N, 0,
  561.     "off",    XYFD_N, CM_INV,
  562.     "on",     XYFD_R, CM_INV,
  563.     "quiet",  XYFD_N, CM_INV
  564.  
  565. #else                    /* Not Mac */
  566.     "crt", XYFD_S, 0,            /* CRT display */
  567. #ifdef CK_CURSES
  568. #ifdef COMMENT
  569.     "curses",     XYFD_C, CM_INV,    /* Full-screen, curses */
  570. #endif /* COMMENT */
  571.     "fullscreen", XYFD_C, 0,        /* Full-screen, whatever the method */
  572. #endif /* CK_CURSES */
  573.     "none",   XYFD_N, 0,        /* No display */
  574.     "off",    XYFD_N, CM_INV,        /* Ditto */
  575.     "on",     XYFD_R, CM_INV,        /* On = Serial */
  576.     "quiet",  XYFD_N, CM_INV,        /* No display */
  577.     "serial", XYFD_R, 0            /* Serial */
  578. #endif /* MAC */
  579. };
  580. int nfdtab = (sizeof(fdtab) / sizeof(struct keytab));
  581.  
  582. struct keytab rsrtab[] = {        /* For REMOTE SET RECEIVE */
  583.     "packet-length", XYLEN, 0,
  584.     "timeout", XYTIMO, 0
  585. };
  586. int nrsrtab = (sizeof(rsrtab) / sizeof(struct keytab));
  587.  
  588. /* Send/Receive Parameters */
  589.  
  590. struct keytab srtab[] = {
  591.     "control-prefix", XYQCTL, 0,
  592.     "end-of-packet", XYEOL, 0,
  593.     "packet-length", XYLEN, 0,
  594.     "pad-character", XYPADC, 0,
  595.     "padding", XYNPAD, 0,
  596.     "pathnames", XYFPATH, 0,
  597.     "pause", XYPAUS, 0,
  598.     "quote", XYQCTL, CM_INV,        /* = CONTROL-PREFIX */
  599.     "start-of-packet", XYMARK, 0,
  600.     "timeout", XYTIMO, 0
  601. };
  602. int nsrtab = (sizeof(srtab) / sizeof(struct keytab));
  603.  
  604. /* REMOTE SET */
  605.  
  606. struct keytab rmstab[] = {
  607.     "attributes",  XYATTR, 0,
  608.     "block-check", XYCHKT, 0,
  609.     "file",        XYFILE, 0,
  610.     "incomplete",  XYIFD,  0,
  611.     "receive",     XYRECV, 0,
  612.     "retry",       XYRETR, 0,
  613.     "server",      XYSERV, 0,
  614.     "transfer",    XYXFER, 0,
  615.     "window",      XYWIND, 0
  616. };
  617. int nrms = (sizeof(rmstab) / sizeof(struct keytab));
  618.  
  619. struct keytab attrtab[] = {
  620. #ifdef STRATUS
  621.     "account",         AT_ACCT, 0,
  622. #endif /* STRATUS */
  623.     "all",           AT_XALL, 0,
  624. #ifdef COMMENT
  625.     "blocksize",     AT_BLKS, 0,    /* not used */
  626. #endif /* COMMENT */
  627. #ifndef NOCSETS
  628.     "character-set", AT_ENCO, 0,
  629. #endif /* NOCSETS */
  630. #ifdef STRATUS
  631.     "creator",         AT_CREA, 0,
  632. #endif /* STRATUS */
  633.     "date",          AT_DATE, 0,
  634.     "disposition",   AT_DISP, 0,
  635.     "encoding",      AT_ENCO, CM_INV,
  636. #ifdef STRATUS
  637.     "format",         AT_RECF, 0,
  638. #endif /* STRATUS */
  639.     "length",        AT_LENK, 0,
  640.     "off",           AT_ALLN, 0,
  641.     "on",            AT_ALLY, 0,
  642. #ifdef COMMENT
  643.     "os-specific",   AT_SYSP, 0,    /* not used by UNIX or VMS */
  644. #endif /* COMMENT */
  645.     "system-id",     AT_SYSI, 0,
  646.     "type",          AT_FTYP, 0,
  647. };
  648. int natr = (sizeof(attrtab) / sizeof(struct keytab)); /* how many attributes */
  649.  
  650. #ifndef NOSPL
  651. extern int indef, inecho, insilence;
  652. struct keytab inptab [] = {        /* SET INPUT parameters */
  653.     "case",            IN_CAS, 0,
  654.     "default-timeout", IN_DEF, CM_INV,
  655.     "echo",            IN_ECH, 0,
  656.     "silence",         IN_SIL, 0,
  657.     "timeout-action",  IN_TIM, 0
  658. };
  659. int ninp = (sizeof(inptab) / sizeof(struct keytab));
  660.  
  661. struct keytab intimt[] = {        /* SET INPUT TIMEOUT parameters */
  662.     "proceed", 0, 0,            /* 0 = proceed */
  663.     "quit",    1, 0            /* 1 = quit */
  664. };
  665.  
  666. struct keytab incast[] = {        /* SET INPUT CASE parameters */
  667.     "ignore",  0, 0,            /* 0 = ignore */
  668.     "observe", 1, 0            /* 1 = observe */
  669. };
  670. #endif /* NOSPL */
  671.  
  672. /* The following routines broken out of doprm() to give compilers a break. */
  673.  
  674. /*  S E T O N  --  Parse on/off (default on), set parameter to result  */
  675.  
  676. int
  677. seton(prm) int *prm; {
  678.     int x, y;
  679.     if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
  680.     if ((x = cmcfm()) < 0) return(x);
  681.     *prm = y;
  682.     return(1);
  683. }
  684.  
  685. /*  S E T N U M  --  Set parameter to result of cmnum() parse.  */
  686. /*
  687.  Call with pointer to integer variable to be set,
  688.    x = number from cnum parse, y = return code from cmnum,
  689.    max = maximum value to accept, -1 if no maximum.
  690.  Returns -9 on failure, after printing a message, or 1 on success.
  691. */
  692. int
  693. setnum(prm,x,y,max) int x, y, *prm, max; {
  694.     extern int cmflgs;
  695.     debug(F101,"setnum","",y);
  696.     if (y == -3) {
  697.     printf("\n?Value required\n");
  698.     return(-9);
  699.     }
  700.     if (y == -2) {
  701.     printf("%s?Not a number: %s\n",cmflgs == 1 ? "" : "\n", atxbuf);
  702.     return(-9);
  703.     }
  704.     if (y < 0) return(y);
  705.     if (max > -1 && x > max) {
  706.     printf("?Sorry, %d is the maximum\n",max);
  707.     return(-9);
  708.     }
  709.     if ((y = cmcfm()) < 0) return(y);
  710.     *prm = x;
  711.     return(1);
  712. }
  713.  
  714. /*  S E T C C  --  Set parameter to an ASCII control character value.  */
  715.  
  716. int
  717. setcc(prm,x,y) int x, y, *prm; {
  718.     if (y == -3) {
  719.     printf("\n?Value required\n");
  720.     return(-3);
  721.     }
  722.     if (y < 0) return(y);
  723.     if ((x > 037) && (x != 0177)) {
  724.     printf("\n?Not in ASCII control range - %d\n",x);
  725.     return(-2);
  726.     }
  727.     if ((y = cmcfm()) < 0) return(y);
  728.     *prm = x;
  729.     return(1);
  730. }
  731.  
  732. #ifndef NODIAL
  733. _PROTOTYP(static int dialstr,(char **, char *));
  734. /*
  735.   Parse a DIAL-related string, stripping enclosing braces, if any.
  736. */
  737. static int
  738. dialstr(p,msg) char **p; char *msg; {
  739.     int x;
  740.     if ((x = cmtxt(msg, "", &s, xxstring)) < 0)
  741.       return(x);
  742.     s = brstrip(s);            /* Strip braces around. */
  743.     if (*p) {                /* Free any previous string. */
  744.     free(*p);
  745.     *p = (char *) 0;
  746.     }    
  747.     if ((x = strlen(s)) > 0) {
  748.     *p = malloc(x + 1);        /* Allocate space for it */
  749.     strcpy(*p,s);            /* and make a safe copy. */
  750.     } else *p = (char *) 0;
  751.     return(success = 1);
  752. }
  753.  
  754. int                    /* Set DIAL command options */
  755. setdial() {
  756.     if ((y = cmkey(dialtab,ndial,"","",xxstring)) < 0) return(y);
  757.     switch (y) {
  758.       case XYDHUP:            /* DIAL HANGUP */
  759.     return(seton(&dialhng));
  760.       case XYDINI:            /* DIAL INIT-STRING */
  761.     return(dialstr(&dialini,"Modem dialer initialization string"));
  762.       case XYDNPR:            /* DIAL NUMBER-PREFIX */
  763.     return(dialstr(&dialnpr,"Modem dialer telephone number prefix"));
  764.       case XYDDIA:            /* DIAL DIAL-COMMAND */
  765.     x = cmtxt("Dialing command for modem,\n\
  766.  include \"%s\" to stand for phone number,\n\
  767.  for example, \"set dial dial-command ATDT%s\\13\"",
  768.           "",
  769.           &s,
  770.           xxstring);
  771.     if (x < 0 && x != -3)        /* Handle parse errors */
  772.       return(x);
  773.     y = x = strlen(s);        /* Get length of text */
  774.     if (x > 0 && *s == '{') {    /* Strip enclosing braces, */
  775.         if (s[x-1] == '}') {    /* if any. */
  776.         s[x-1] = NUL;
  777.         s++;
  778.         y -= 2;
  779.         }
  780.     }
  781.     if (y > 0) {            /* If there is any text (left), */
  782.         for (x = 0; x < y; x++) {    /* make sure they included "%s" */
  783.         if (s[x] != '%') continue;
  784.         if (s[x+1] == 's') break;
  785.         }
  786.         if (x == y) {
  787.         printf(
  788. "?Dial-command must contain \"%cs\" for phone number.\n",'%');
  789.         return(-9);
  790.         }
  791.     }
  792.     if (dialcmd) {            /* Free any previous string. */
  793.         free(dialcmd);
  794.         dialcmd = (char *) 0;
  795.     }    
  796.     if (y > 0) {
  797.         dialcmd = malloc(y + 1);    /* Allocate space for it */
  798.         strcpy(dialcmd,s);        /* and make a safe copy. */
  799.     }
  800.     return(success = 1);
  801.       case XYDKSP:            /* DIAL KERMIT-SPOOF */
  802.     return(seton(&dialksp));
  803.       case XYDTMO:            /* DIAL TIMEOUT */
  804.     y = cmnum("Seconds to wait for call completion","0",10,&x,xxstring);
  805.     return(setnum(&dialtmo,x,y,10000));
  806.       case XYDDPY:            /* DIAL DISPLAY */
  807.     return(seton(&dialdpy));
  808.       case XYDSPD:            /* DIAL SPEED-MATCHING */
  809.                     /* used to be speed-changing */
  810.     if ((y = seton(&mdmspd)) < 0) return(y);
  811. #ifdef COMMENT
  812.     mdmspd = 1 - mdmspd;        /* so here we reverse the meaning */
  813. #endif /* COMMENT */
  814.     return(success = 1);
  815.       case XYDMNP:            /* DIAL MNP-ENABLE */
  816.     return(seton(&dialmnp));
  817. #ifdef MDMHUP
  818.       case XYDMHU:            /* DIAL MODEM-HANGUP */
  819.     return(seton(&dialmhu));
  820. #endif /* MDMHUP */
  821.       case XYDDIR:            /* DIAL DIRECTORY */
  822.     if ((y = cmifi("Name of dialing directory file","",&s,&x,
  823.                xxstring)) < 0) {
  824.         if (y == -3) {
  825.         if (dialdir) free(dialdir);    /* Free any previous storage */
  826.         dialdir = NULL;
  827.         return(success = 1);
  828.         } else return(y);
  829.     }
  830.     if (x) {
  831.         printf("?Wildcards not allowed\n");
  832.         return(-9);
  833.     }
  834.     strcpy(line,s);            /* Make safe copy of dial string */
  835.     if ((y = cmcfm()) < 0) return(y); /* Confirm the command */
  836.     if (dialdir) free(dialdir);    /* Free previous filename storage */
  837.     if (dialfd) {            /* Close previous file, if any */
  838.         fclose(dialfd);
  839.         dialfd = NULL;
  840.     }
  841.     s = line;            /* Point back to dial string */
  842.     if (s == NULL || *s == NUL) {    /* If no name given */
  843.         dialdir = NULL;        /* remove the name string */
  844.         return(success = 1);
  845.     } else if ((dialdir = malloc(strlen(s)+1)) == NULL) {
  846.         return(success = 0);    /* Can't malloc storage for name */
  847.     } else {            /* Have storage for name */
  848.         strcpy(dialdir,s);        /* Copy string into new storage */
  849.         if ((dialfd = fopen(dialdir,"r")) == NULL) { /* Open the file */
  850.         perror(dialdir);    /* Can't, print message saying why */
  851.         success = 0;        /* We didn't succeed */
  852.         return(-9);        /* Fail, message already printed */
  853.         }
  854.         return(success = 1);    /* Everything is OK */
  855.     }
  856. #ifdef COMMENT
  857.       case XYDHCM:            /* DIAL HUP-STRING */
  858.     return(dialstr(&hupcmd,"Modem dialer hangup command string"));
  859. #endif /* COMMENT */
  860.  
  861.       default:
  862.     printf("?Unexpected SET DIAL parameter\n");
  863.     return(-2);
  864.     }
  865. }
  866. #endif /* NODIAL */
  867.  
  868. int
  869. setfil(rmsflg) int rmsflg; {
  870.     if (rmsflg) {
  871.     if ((y = cmkey(rfiltab,nrfilp,"Remote file parameter","",
  872.                xxstring)) < 0) {
  873.         if (y == -3) {
  874.         printf("?Remote file parameter required\n");
  875.         return(-9);
  876.         } else return(y);
  877.     }
  878.     } else {
  879.     if ((y = cmkey(filtab,nfilp,"File parameter","",xxstring)) < 0)
  880.       return(y);
  881.     }
  882.     switch (y) {
  883. #ifdef COMMENT                /* Not needed */
  884.       case XYFILB:            /* Blocksize */
  885.     sprintf(tmpbuf,"%d",DBLKSIZ);
  886.     if ((y = cmnum("file block size",tmpbuf,10,&z,xxstring)) < 0)
  887.       return(y);
  888.     if ((x = cmcfm()) < 0) return(x);
  889.     if (rmsflg) {
  890.         sprintf(tmpbuf,"%d",z);
  891.         sstate = setgen('S', "311", tmpbuf, "");
  892.         return((int) sstate);
  893.     } else {
  894.         fblksiz = z;
  895.         return(success = 1);
  896.     }
  897. #endif /* COMMENT */
  898.  
  899.       case XYFILS:            /* Byte size */
  900.     if ((y = cmnum("file byte size (7 or 8)","8",10,&z,xxstring)) < 0)
  901.       return(y);
  902.     if (z != 7 && z != 8) {
  903.         printf("\n?The choices are 7 and 8\n");
  904.         return(0);
  905.     }
  906.     if ((y = cmcfm()) < 0) return(y);
  907.     if (z == 7) fmask = 0177;
  908.     else if (z == 8) fmask = 0377;
  909.     return(success = 1);
  910.  
  911. #ifndef NOCSETS
  912.       case XYFILC:            /* Character set */
  913.     if ((x = cmkey(fcstab,nfilc,"local file code","ascii", xxstring)) < 0)
  914.       return(x);
  915.     if ((z = cmcfm()) < 0) return(z);
  916.     fcharset = x;
  917.     return(success = 1);
  918. #endif /* NOCSETS */
  919.  
  920.       case XYFILD:            /* Display */
  921.     if ((x = cmkey(fdtab,nfdtab,"file transfer display style","",
  922.                xxstring)) < 0)
  923.       return(x);
  924. #ifdef CK_PCT_BAR
  925.     if ((y = cmkey(fdftab,2,"","thermometer",xxstring)) < 0)
  926.       return(y);
  927.     thermometer = y;
  928. #endif /* CK_PCT_BAR */
  929.     if ((z = cmcfm()) < 0) return(z);
  930. #ifdef CK_CURSES
  931.     if (x == XYFD_C) {
  932. #ifdef VMS
  933.         lp = line;
  934. #else
  935.         lp = trmbuf;
  936. #endif /* VMS */
  937. #ifndef MYCURSES
  938.         s = getenv("TERM");
  939.         if (!s) s = "unknown";
  940.         else if ((int)strlen(s) < 1) s = "unknown";
  941. #ifndef COHERENT
  942.         if (tgetent(lp,s) < 1) {
  943. #ifdef VMS
  944.         printf("Sorry, terminal type not supported: %s\n",s);
  945. #else
  946.         printf("Sorry, terminal type unknown: %s\n",s);
  947. #endif /* VMS */
  948.         return(success = 0);
  949.         }
  950. #endif /* COHERENT */
  951. #endif /* MYCURSES */
  952.         line[0] = '\0';
  953.     }
  954. #endif /* CK_CURSES */
  955.     fdispla = x;            /* It's OK. */
  956.     return(success = 1);
  957.  
  958.       case XYFILN:            /* Names */
  959.     if ((x = cmkey(fntab,2,"how to handle filenames","converted",
  960.                xxstring)) < 0)
  961.       return(x);
  962.     if ((z = cmcfm()) < 0) return(z);
  963.     if (rmsflg) {
  964.         sprintf(tmpbuf,"%d",1 - x);
  965.         sstate = setgen('S', "301", tmpbuf, "");
  966.         return((int) sstate);
  967.     } else {
  968.         fncnv = x;
  969.         return(success = 1);
  970.     }
  971.  
  972.       case XYFILR:            /* Record length */
  973.     sprintf(tmpbuf,"%d",DLRECL);
  974.     if ((y = cmnum("file record length",tmpbuf,10,&z,xxstring)) < 0)
  975.       return(y);
  976.     if ((x = cmcfm()) < 0) return(x);
  977.     if (rmsflg) {
  978.         sprintf(tmpbuf,"%d",z);
  979.         sstate = setgen('S', "312", tmpbuf, "");
  980.         return((int) sstate);
  981.     } else {
  982.         frecl = z;
  983.         return(success = 1);
  984.     }
  985.  
  986. #ifdef COMMENT
  987.       case XYFILO:            /* Organization */
  988.     if ((x = cmkey(forgtab,nforg,"file organization","sequential",
  989.                xxstring)) < 0)
  990.       return(x);
  991.     if ((y = cmcfm()) < 0) return(y);
  992.     if (rmsflg) {
  993.         sprintf(tmpbuf,"%d",x);
  994.         sstate = setgen('S', "314", tmpbuf, "");
  995.         return((int) sstate);
  996.     } else {
  997.         forg = x;
  998.         return(success = 1);
  999.     }    
  1000. #endif /* COMMENT */
  1001.  
  1002. #ifdef COMMENT                /* Not needed */
  1003.       case XYFILF:            /* Format */
  1004.     if ((x = cmkey(frectab,nfrec,"file record format","stream",
  1005.                xxstring)) < 0)
  1006.       return(x);
  1007.     if ((y = cmcfm()) < 0) return(y);
  1008.     if (rmsflg) {
  1009.         sprintf(tmpbuf,"%d",x);
  1010.         sstate = setgen('S', "313", tmpbuf, "");
  1011.         return((int) sstate);
  1012.     } else {
  1013.         frecfm = x;
  1014.         return(success = 1);
  1015.     }
  1016. #endif /* COMMENT */
  1017.  
  1018. #ifdef COMMENT
  1019.       case XYFILP:            /* Printer carriage control */
  1020.     if ((x = cmkey(fcctab,nfcc,"file carriage control","newline",
  1021.                xxstring)) < 0)
  1022.       return(x);
  1023.     if ((y = cmcfm()) < 0) return(y);
  1024.     if (rmsflg) {
  1025.         sprintf(tmpbuf,"%d",x);
  1026.         sstate = setgen('S', "315", tmpbuf, "");
  1027.         return((int) sstate);
  1028.     } else {
  1029.         fcctrl = x;
  1030.         return(success = 1);
  1031.     }    
  1032. #endif /* COMMENT */
  1033.  
  1034.       case XYFILT:            /* Type */
  1035.     if ((x = cmkey(rmsflg ? rfttab  : fttab,
  1036.                rmsflg ? nrfttyp : nfttyp,
  1037.                "type of file transfer","text",xxstring)) < 0)
  1038.       return(x);
  1039.  
  1040. #ifdef VMS
  1041.         /* Allow VMS users to choose record format for binary files */
  1042.         if ((x == XYFT_B) && (rmsflg == 0)) {
  1043.         if ((x = cmkey(fbtab,nfbtyp,"VMS record format","fixed",
  1044.                xxstring)) < 0)
  1045.           return(x);
  1046.     }
  1047. #endif /* VMS */
  1048.     if ((y = cmcfm()) < 0) return(y);
  1049.     binary = x;            /* Do it locally too (edit 190) */
  1050. #ifdef MAC
  1051.     (void) mac_setfildflg(binary);
  1052. #endif /* MAC */
  1053.     if (rmsflg) {
  1054.         char buf[4];        /* Allow for LABELED in VMS & OS/2 */
  1055.         sprintf(buf,"%d",x);
  1056.         sstate = setgen('S', "300", buf, "");
  1057.         return((int) sstate);
  1058.     } else {
  1059.         return(success = 1);
  1060.     }
  1061.  
  1062.       case XYFILX:            /* Collision Action */
  1063.     if ((x = cmkey(colxtab,ncolx,"Filename collision action","backup",
  1064.                xxstring)) < 0)
  1065.       return(x);
  1066.     if ((y = cmcfm()) < 0) return(y);
  1067.     fncact = x;
  1068.     if (rmsflg) {
  1069.         sprintf(tmpbuf,"%d",fncact);
  1070.         sstate = setgen('S', "302", tmpbuf, "");
  1071.         return((int) sstate);
  1072.     } else {
  1073.         if (fncact == XYFX_R) warn = 1; /* SET FILE WARNING implications */
  1074.         if (fncact == XYFX_X) warn = 0; /* ... */
  1075.         return(success = 1);
  1076.     }
  1077.  
  1078.       case XYFILW:            /* Warning/Write-Protect */
  1079.     if ((x = seton(&warn)) < 0) return(x);
  1080.     if (warn)
  1081.       fncact = XYFX_R;
  1082.     else
  1083.       fncact = XYFX_X;
  1084.     return(success = 1);
  1085.  
  1086. #ifdef CK_LABELED
  1087.       case XYFILL:            /* LABELED FILE parameters */
  1088.     if ((x = cmkey(lbltab,nlblp,"Labeled file feature","",
  1089.                xxstring)) < 0)
  1090.       return(x);
  1091.     if ((success = seton(&y)) < 0)
  1092.       return(success);
  1093.     if (y)                /* Set or reset the selected bit */
  1094.       lf_opts |= x;            /* in the options bitmask. */
  1095.     else
  1096.       lf_opts &= ~x;
  1097.     return(success);
  1098. #endif /* CK_LABELED */
  1099.  
  1100.       case XYFILI:            /* INCOMPLETE */
  1101.     return(doprm(XYIFD,rmsflg));
  1102.  
  1103.       default:
  1104.     printf("?unexpected file parameter\n");
  1105.     return(-2);
  1106.     }
  1107. }
  1108.  
  1109. #ifndef NOLOCAL
  1110. int
  1111. settrm() {
  1112.     if ((y = cmkey(trmtab,ntrm,"", "",xxstring)) < 0) return(y);
  1113. #ifdef MAC
  1114.     printf("\n?Sorry, not implemented yet.  Please use the Settings menu.\n");
  1115.     return(-9);
  1116. #else
  1117.     switch (y) {
  1118.       case XYTBYT:            /* SET TERMINAL BYTESIZE */
  1119.     if ((y = cmnum("bytesize for terminal connection","8",10,&x,
  1120.                xxstring)) < 0)
  1121.       return(y);
  1122.     if (x != 7 && x != 8) {
  1123.         printf("\n?The choices are 7 and 8\n");
  1124.         return(success = 0);
  1125.     }
  1126.     if ((y = cmcfm()) < 0) return(y);
  1127.     if (x == 7) cmask = 0177;
  1128.     else if (x == 8) cmask = 0377;
  1129.         return(success = 1);
  1130.  
  1131.       case XYTSO:            /* SET TERMINAL LOCKING-SHIFT */
  1132.     return(seton(&sosi));
  1133.  
  1134.       case XYTNL:            /* SET TERMINAL NEWLINE-MODE */
  1135.     return(seton(&tnlm)); 
  1136.  
  1137. #ifdef OS2
  1138.       case XYTCOL:            /* SET TERMINAL COLOR */
  1139.     if ((x = cmkey(ttycoltab,ncolors,"","terminal",xxstring)) < 0) {
  1140.         return(x);
  1141.         } else {
  1142.         int fg, bg;
  1143.         fg = cmkey(ttyclrtab,nclrs,
  1144.                (x == 5 ? "color for screen border" 
  1145.                       : "foreground color and then background color"),
  1146.  
  1147.                "black",xxstring);
  1148.         if (fg < 0)return(fg);
  1149.         if (x != 5) {
  1150.         if ((bg = cmkey(ttyclrtab,nclrs,
  1151.                 "background color","cyan",xxstring)) < 0)
  1152.           return(bg);
  1153.         }
  1154.         if ((y = cmcfm()) < 0)
  1155.           return(y);
  1156.         switch (x) {
  1157.           case 0:
  1158.         colornormal = fg | bg << 4;
  1159.         break;
  1160.           case 1:
  1161. #ifdef COMMENT
  1162.         colorreverse = fg | bg << 4;
  1163. #else
  1164.         if (pflag &&
  1165. #ifndef NOSPL
  1166.           cmdlvl == 0
  1167. #else
  1168.             tlevel < 0
  1169. #endif /* NOSPL */
  1170.               ) {
  1171.         printf(" Sorry, this command has been retired.\n");
  1172.         printf(" Reverse video is now accomplished simply by\n");
  1173.         printf(" exchanging the fore- and background colors.\n");
  1174.         }
  1175. #endif /* COMMENT */
  1176.         break;
  1177.           case 2:
  1178.         colorunderline = fg | bg << 4;
  1179.         break;
  1180.           case 3:
  1181.         colorstatus = fg | bg << 4;
  1182.         break;
  1183.           case 4:
  1184.         colorhelp = fg | bg << 4;
  1185.         break;
  1186.           case 5:
  1187.         colorborder = fg;
  1188.         break;
  1189.           default:
  1190.         printf("%s - invalid\n",cmdbuf);
  1191.         return(-9);
  1192.         break;
  1193.         }
  1194.         scrninitialised = 0;
  1195.         }
  1196.     return(success = 1);
  1197.  
  1198.       case XYTCUR:            /* SET TERMINAL CURSOR */
  1199.     if ((x = cmkey(ttycurtab,ncursors,"","underline",xxstring)) < 0)
  1200.       return(x);
  1201.     if ((y = cmcfm()) < 0) return(y);
  1202.         tt_cursor = x;
  1203.     return(success = 1);
  1204.  
  1205.       case XYTTYP:            /* SET TERMINAL TYPE */
  1206.     if ((x = cmkey(ttyptab,nttyp,"","vt220",xxstring)) < 0) return(x);
  1207.     if ((y = cmcfm()) < 0) return(y);
  1208.     tt_type = x;
  1209.     if (tt_type == TT_ANSI) {
  1210.         if (parity)
  1211.           printf(
  1212. "WARNING, ANSI terminal emulation works right only if PARITY is NONE.\n\
  1213. HELP SET PARITY for further information.\n"
  1214.              );
  1215.         savcolor = colornormal;    /* Save coloration */
  1216.         colornormal = 0x07;        /* Light gray on black */
  1217.         scrninitialised = 0;    /* To make it take effect */
  1218.         savcmask = cmask;        /* Go to 8 bits */
  1219.         cmask = 0xFF;
  1220.         savtcsl = tcsl;        /* Save terminal charset */
  1221.         savtcsr = tcsr;        
  1222.         savfcs  = fcharset;
  1223.         tcsr = tcsl = FC_CP437;    /* Go to transparent */
  1224.         y = os2getcp();        /* Get current code page */
  1225.         if (y != 437) {        /* If it's not 437 */
  1226.         savcp = y;        /* Save current code page */
  1227.         y = os2setcp(437);    /* Try to switch to CP437 */
  1228.         if (pflag)
  1229.           printf(y ?
  1230.              "Switching to Code Page 437...\n" :
  1231.              "Warning: Code Page 437 not prepared\n"
  1232.              );
  1233.         }
  1234.     } else {            /* Not ANSI, but a real type */
  1235.         if (savcolor) {        /* Restore this stuff if we */
  1236.         colornormal = savcolor;    /* were ANSI before... */
  1237.         savcolor = 0;
  1238.         scrninitialised = 0;
  1239.         }
  1240.         if (savcmask) {        /* Restore terminal bytesize */
  1241.         cmask = savcmask;
  1242.         savcmask = 0;
  1243.         }
  1244.         if (savtcsl > -1) {        /* Restore character sets */
  1245.         tcsl = savtcsl;
  1246.         tcsr = savtcsr;        
  1247.         fcharset = savfcs;
  1248.         savtcsl = -1;
  1249.         }
  1250.         if (savcp > 0) {        /* Restore code page */
  1251.         os2setcp(savcp);
  1252.         savcp = -1;
  1253.         }
  1254.     }
  1255.     return(success = 1);
  1256.  
  1257.       case XYTARR:            /* SET TERMINAL ARROW-KEYS */
  1258.     if ((x = cmkey(akmtab,2,"","",xxstring)) < 0) return(x);
  1259.     if ((y = cmcfm()) < 0) return(y);
  1260.     tt_arrow = x;            /* TTK_NORM / TTK_APPL; see ckuusr.h */
  1261.     return(success = 1);
  1262.  
  1263.       case XYTKPD:            /* SET TERMINAL KEYPAD-MODE */
  1264.     if ((x = cmkey(kpmtab,2,"","",xxstring)) < 0) return(x);
  1265.     if ((y = cmcfm()) < 0) return(y);
  1266.     tt_keypad = x;            /* TTK_NORM / TTK_APPL; see ckuusr.h */
  1267.     return(success = 1);
  1268.  
  1269.       case XYTWRP:            /* SET TERMINAL WRAP */
  1270.     return(seton(&tt_wrap)); 
  1271.  
  1272.       case XYSCRS:
  1273.     if ((y = cmnum("CONNECT scrollback buffer size, lines","240",10,&x,
  1274.                xxstring)) < 0)
  1275.       return(y);
  1276. #ifdef __32BIT__
  1277.     if (x < 1 || x > 2000000L) { /* The max number of lines is the RAM  */
  1278.                                      /* we can actually dedicate to a       */
  1279.                      /* scrollback buffer given the maximum */
  1280.                                      /* process memory space of 512MB       */
  1281.         printf("\n?The size must be between 1 and 2,000,000\n"); 
  1282.         return(success = 0);
  1283.      } 
  1284. #else
  1285.     if (x < 64 || x > 240) {
  1286.         printf("\n?The size must be between 64 and 240\n");
  1287.         return(success = 0);
  1288.     }
  1289. #endif /* __32BIT__ */
  1290.     if ((y = cmcfm()) < 0) return(y);
  1291.     tt_scrsize = x;
  1292.     return(success = 1);
  1293. #endif /* OS2 */
  1294.  
  1295. #ifndef NOCSETS
  1296.       case XYTCS:            /* SET TERMINAL CHARACTER-SET */
  1297.     /* set terminal character-set <remote> <local> */
  1298.     if ((x = cmkey(ttcstab,ntermc,
  1299.                "remote terminal character-set","",xxstring)) < 0) 
  1300.       return(x);
  1301.     if (x == FC_TRANSP) {        /* TRANSPARENT? */
  1302.         if ((x = cmcfm()) < 0) return(x); /* Confirm the command */
  1303.         tcsr = tcsl = FC_USASCII;    /* Make them both the same */
  1304.         return(success = 1);
  1305.     }
  1306.  
  1307. /* Not transparent, so get local set to translate it into */
  1308.  
  1309.     s = "";
  1310. #ifdef OS2
  1311.     y = os2getcp();            /* Default is current code page */
  1312.     switch (y) {
  1313.       case 437: s = "cp437"; break;
  1314.       case 850: s = "cp850"; break;
  1315.       case 852: s = "cp852"; break;
  1316.       case 862: s = "cp862"; break;
  1317.       case 866: s = "cp866"; break;
  1318.     }
  1319. #else
  1320.                     /* Make current file char set */
  1321.     for (y = 0; y <= nfilc; y++)    /* be the default... */
  1322.       if (fcstab[y].kwval == fcharset) {
  1323.           s = fcstab[y].kwd;
  1324.           break;
  1325.       }
  1326. #endif /* OS2 */
  1327.     if ((y = cmkey(fcstab,nfilc,
  1328.                "local character-set",s,xxstring)) < 0)
  1329.       return(y);
  1330.     if ((z = cmcfm()) < 0) return(z); /* Confirm the command */
  1331.     tcsr = x;            /* Remote character set */
  1332.     tcsl = y;            /* Local character set */
  1333.     return(success = 1);
  1334. #endif /* NOCSETS */
  1335.  
  1336.       case XYTEC:            /* SET TERMINAL ECHO */
  1337.     if ((x = cmkey(rltab,nrlt,"which side echos during CONNECT",
  1338.                "remote", xxstring)) < 0) return(x);
  1339.     if ((y = cmcfm()) < 0) return(y);
  1340.     duplex = x;
  1341.     return(success = 1); 
  1342.  
  1343.       case XYTCRD:            /* SET TERMINAL CR-DISPLAY */
  1344.     if ((x = cmkey(crdtab,2,"", "normal", xxstring)) < 0) return(x);
  1345.     if ((y = cmcfm()) < 0) return(y);
  1346.     tt_crd = x;
  1347.     return(success = 1); 
  1348.  
  1349. #ifdef OS2
  1350.       case XYTANS:            /* SET TERMINAL ANSWERBACK */
  1351. /*
  1352.   NOTE: We let them enable and disable the answerback sequence, but we
  1353.   do NOT let them change it, and we definitely do not let the host set it.
  1354.   This is a security feature.
  1355. */
  1356.     return(seton(&tt_answer));
  1357. #endif /* OS2 */
  1358.  
  1359. #ifdef CK_APC
  1360.       case XYTAPC:
  1361.     if ((y = cmkey(apctab,3,"application program command execution","",
  1362.                xxstring)) < 0)
  1363.       return(y);
  1364.     if ((x = cmcfm()) < 0) return(x);
  1365.     if (apcactive && apcstatus != APC_UNCH) return(success = 0);
  1366.     apcstatus = y;    
  1367.     return(success = 1);
  1368. #endif /* CK_APC */
  1369.  
  1370. #ifdef OS2
  1371.       case XYTBEL:
  1372.     if ((y = cmkey(beltab,3,"how terminal emulator rings bells","audible",
  1373.                xxstring)) < 0)
  1374.       return(y);
  1375.     if ((x = cmcfm()) < 0) return(x);
  1376.     tt_bell = y;
  1377.     return(success = 1);
  1378. #endif /* OS2 */
  1379.  
  1380.       case XYTDEB:            /* TERMINAL DEBUG */
  1381.     x = debses;            /* What it was before */
  1382.     y = seton(&debses);        /* Go parse ON or OFF */
  1383. #ifdef OS2
  1384.     if (y > 0)            /* Command succeeded? */
  1385.       if ((x != 0) && (debses == 0)) /* It was on and we turned it off? */
  1386.         os2debugoff();        /* Fix OS/2 coloration */
  1387. #endif /* OS2 */
  1388.     return(y);
  1389.  
  1390. #ifdef OS2
  1391.       case XYTROL:            /* SET TERMINAL ROLL */
  1392.     return(seton(&tt_roll));
  1393.  
  1394.       case XYTCTS:            /* SET TERMINAL TRANSMIT-TIMEOUT */
  1395.     y = cmnum("Maximum seconds to allow CTS off during CONNECT",
  1396.           "5",10,&x,xxstring);
  1397.     return(setnum(&tt_ctstmo,x,y,10000));
  1398.  
  1399.       case XYTCPG: {            /* SET TERMINAL CODE-PAGE */
  1400.     int cp = -1;
  1401.     y = cmnum("PC code page to use during terminal emulation",
  1402.           "850",10,&x,xxstring);
  1403.     if ((x = setnum(&cp,x,y,2000)) < 0) return(x);
  1404.     if (os2setcp(cp) != 1) {
  1405.         printf("Sorry, %d is not a valid code page for this system\n");
  1406.         return(-9);
  1407.     }
  1408.     return(1);
  1409.       }
  1410.  
  1411.       case XYTHCU:            /* SET TERMINAL HIDE-CURSOR */
  1412.     return(seton(&tt_hide));
  1413.  
  1414.       case XYTPAC:            /* SET TERMINAL OUTPUT-PACING */
  1415.     y = cmnum(
  1416.        "Pause between sending each character during CONNECT, milliseconds",
  1417.           "-1",10,&x,xxstring);
  1418.     return(setnum(&tt_pacing,x,y,10000));
  1419.  
  1420. #ifdef OS2MOUSE
  1421.       case XYTMOU:            /* SET TERMINAL MOUSE */
  1422.     return(seton(&tt_mouse));
  1423. #endif /* OS2MOUSE */
  1424.  
  1425. #endif /* OS2 */
  1426.  
  1427.       default:                /* Shouldn't get here. */
  1428.     return(-2);
  1429.     } 
  1430. #endif /* MAC */
  1431. }
  1432. #endif /* NOLOCAL */
  1433.  
  1434. int                    /* SET SEND/RECEIVE */
  1435. setsr(xx, rmsflg) int xx; int rmsflg; {
  1436.     if (xx == XYRECV)
  1437.       strcpy(line,"Parameter for inbound packets");
  1438.     else
  1439.       strcpy(line,"Parameter for outbound packets");
  1440.  
  1441.     if (rmsflg) {
  1442.     if ((y = cmkey(rsrtab,nrsrtab,line,"",xxstring)) < 0) {
  1443.         if (y == -3) {
  1444.         printf("?Remote receive parameter required\n");
  1445.         return(-9);
  1446.         } else return(y);
  1447.     }
  1448.     } else {
  1449.     if ((y = cmkey(srtab,nsrtab,line,"",xxstring)) < 0) return(y);
  1450.     }
  1451.     switch (y) {
  1452.       case XYQCTL:            /* CONTROL-PREFIX */
  1453.     if ((x = cmnum("ASCII value of control prefix","",10,&y,xxstring)) < 0)
  1454.       return(x);
  1455.     if ((x = cmcfm()) < 0) return(x);
  1456.     if ((y > 32 && y < 63) || (y > 95 && y < 127)) {
  1457.         if (xx == XYRECV)
  1458.           ctlq = (CHAR) y;        /* RECEIVE prefix, use with caution! */
  1459.         else
  1460.           myctlq = (CHAR) y;    /* SEND prefix, OK to change */
  1461.         return(success = 1); 
  1462.     } else {
  1463.         printf("?Illegal value for prefix character\n");
  1464.         return(-9);
  1465.     }
  1466.  
  1467.       case XYEOL:
  1468.     y = cmnum("Decimal ASCII code for packet terminator","13",10,&x,
  1469.           xxstring);
  1470.     if ((y = setcc(&z,x,y)) < 0) return(y);
  1471.     if (z > 31) {
  1472.         printf("Sorry, the legal values are 0-31\n");
  1473.         return(-9);
  1474.     }
  1475.     if (xx == XYRECV) eol = z; else {
  1476.         seol = z;
  1477.     }
  1478.     return(success = y);
  1479.  
  1480.       case XYLEN:
  1481.     y = cmnum("Maximum number of characters in a packet","90",10,&x,
  1482.           xxstring);
  1483.     if (xx == XYRECV) {        /* Receive... */
  1484.         if ((y = setnum(&z,x,y,maxrps)) < 0)
  1485.           return(y);
  1486.         if (z < 10) {
  1487.         printf("Sorry, 10 is the minimum\n");
  1488.         return(-9);
  1489.         }
  1490.         if (rmsflg) {
  1491.         tp = tmpbuf;
  1492.         sprintf(tp,"%d",z);
  1493.         sstate = setgen('S', "401", tp, "");
  1494.         return((int) sstate);
  1495.         } else {
  1496.         if (z > MAXRP) z = MAXRP;
  1497.         y = adjpkl(z,wslotr,bigrbsiz);
  1498.         if (y != z) {
  1499.             urpsiz = y;
  1500.             if (
  1501. #ifndef NOSPL
  1502.             cmdlvl == 0
  1503. #else
  1504.             tlevel < 0
  1505. #endif /* NOSPL */
  1506.             )
  1507.               if (msgflg) printf(
  1508. " Adjusting receive packet-length to %d for %d window slots\n",
  1509.              y, wslotr);
  1510.         }
  1511.         urpsiz = y;
  1512.         rpsiz =  (y > 94) ? 94 : y;
  1513.         }
  1514.     } else {            /* Send... */
  1515.         if ((y = setnum(&z,x,y,maxsps)) < 0)
  1516.           return(y);
  1517.         if (z < 10) {
  1518.         printf("Sorry, 10 is the minimum\n");
  1519.         return(-9);
  1520.         }
  1521.         if (z > MAXSP) z = MAXSP;
  1522.         spsiz = z;            /* Set it */
  1523.         y = adjpkl(spsiz,wslotr,bigsbsiz);
  1524.         if (y != spsiz &&
  1525. #ifndef NOSPL
  1526.         cmdlvl == 0
  1527. #else
  1528.         tlevel < 0
  1529. #endif /* NOSPL */
  1530.         )
  1531.           if (msgflg)
  1532.         printf("Adjusting packet size to %d for %d window slots\n",
  1533.              y,wslotr);
  1534.         spsiz = spmax = spsizr = y;    /* Set it and flag that it was set */
  1535.         spsizf = 1;            /* to allow overriding Send-Init. */
  1536.     }
  1537.     if (pflag &&
  1538. #ifndef NOSPL
  1539.         cmdlvl == 0
  1540. #else
  1541.         tlevel < 0
  1542. #endif /* NOSPL */
  1543.         ) {
  1544.         if (z > 94 && msgflg) {
  1545.         printf("Extended-length packets requested.\n");
  1546.         if (bctr < 2 && z > 200) printf("\
  1547. Remember to SET BLOCK 2 or 3 for long packets.\n");
  1548.         }
  1549.         if (speed <= 0L) speed = ttgspd();
  1550. #ifdef COMMENT
  1551. /*
  1552.   Kermit does this now itself.
  1553. */
  1554.         if (speed <= 0L && z > 200 && msgflg) {
  1555.         printf("\
  1556. Make sure your timeout interval is long enough for %d-byte packets.\n",z);
  1557.         }
  1558. #endif /* COMMENT */
  1559.     }
  1560.     return(success = y);
  1561.  
  1562.       case XYMARK:
  1563.     y = cmnum("Code for packet-start character","1",10,&x,xxstring);
  1564. #ifdef UNIX
  1565. /*
  1566.   Printable start-of-packet works for UNIX and VMS only!
  1567. */
  1568.     if ((y = setnum(&z,x,y,126)) < 0) return(y);
  1569. #else
  1570. #ifdef VMS
  1571.     if ((y = setnum(&z,x,y,126)) < 0) return(y);
  1572. #else
  1573. #ifdef OS2
  1574.     if ((y = setnum(&z,x,y,126)) < 0) return(y);
  1575. #else
  1576.     if ((y = setcc(&z,x,y)) < 0) return(y);
  1577. #endif /* OS2 */
  1578. #endif /* VMS */
  1579. #endif /* UNIX */
  1580.     if (xx == XYRECV) stchr = z; else {
  1581.         mystch = z;
  1582.     }
  1583.     return(success = y);
  1584.  
  1585.       case XYNPAD:            /* PADDING */
  1586.     y = cmnum("How many padding characters for inbound packets","0",10,&x,
  1587.           xxstring);
  1588.     if ((y = setnum(&z,x,y,94)) < 0) return(y);
  1589.     if (xx == XYRECV) mypadn = z; else npad = z;
  1590.     return(success = y);
  1591.  
  1592.       case XYPADC:            /* PAD-CHARACTER */
  1593.     y = cmnum("Decimal ASCII code for packet padding character","0",10,&x,
  1594.           xxstring);
  1595.     if ((y = setcc(&z,x,y)) < 0) return(y);
  1596.     if (xx == XYRECV) mypadc = z; else padch = z;
  1597.     return(success = y);
  1598.  
  1599.       case XYTIMO:            /* TIMEOUT */
  1600.     if (xx == XYRECV) {
  1601.         char buf[16];        /* Construct default */
  1602.         sprintf(buf,"%d",URTIME);
  1603.         y = cmnum("Packet timeout interval",buf,10,&x,xxstring);
  1604.         if ((y = setnum(&z,x,y,94)) < 0) return(y);
  1605.  
  1606.         if (rmsflg) {        /* REMOTE SET RECEIVE TIMEOUT */
  1607.         tp = tmpbuf;        /*   Tell Kermit server what */
  1608.         sprintf(tp,"%d",z);    /*   timeout to ask me to use. */
  1609.         sstate = setgen('S', "402", tp, "");
  1610.         return((int) sstate);
  1611.         } else {            /* SET RECEIVE TIMEOUT */
  1612.         pkttim = z;        /*   Value to put in my negotiation */
  1613.         }                /*   packet for other Kermit to use */
  1614.  
  1615.     } else {            /* SET SEND TIMEOUT */
  1616.         y = cmnum("Packet timeout interval","",10,&x,xxstring);
  1617.         if (y == -3) {        /* They cancelled a previous */
  1618.         x = DMYTIM;        /* SET SEND command, so restore */
  1619.         y = 0;            /* the default */
  1620.         timef = 0;        /* and turn off the override flag */
  1621.         } else {            /* They gave a number */
  1622.         timef = 1;        /* so turn on the override flag */
  1623.         }
  1624.         if ((y = setnum(&z,x,y,94)) < 0)
  1625.           return(y);
  1626.         timint = rtimo = z;        /* Override value for me to use */
  1627.     }
  1628.     return(success = 1);
  1629.  
  1630.       case XYFPATH:            /* PATHNAMES */
  1631.     if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
  1632.     if ((x = cmcfm()) < 0) return(x);
  1633.     if (xx == XYRECV)        /* SET RECEIVE PATHNAMES */
  1634.       fnrpath = 1 - y;        /* OFF (with their heads!), ON */
  1635.     else                /* SET SEND PATHNAMES */
  1636.       fnspath = 1 - y;        /* OFF, ON */
  1637.     return(success = 1);        /* Note: 0 = ON, 1 = OFF */
  1638.     /* In other words, ON = leave pathnames ON, OFF = take them off. */
  1639.  
  1640.       case XYPAUS:            /* SET SEND/RECEIVE PAUSE */
  1641.     y = cmnum("Milliseconds to pause between packets","0",10,&x,xxstring);
  1642.     if ((y = setnum(&z,x,y,15000)) < 0)
  1643.       return(y);
  1644.     pktpaus = z;
  1645.     return(success = 1);
  1646.  
  1647.       default:
  1648.     return(-2);
  1649.     }                    /* End of SET SEND/RECEIVE... */
  1650. }
  1651.  
  1652. #ifndef NOXMIT
  1653. int
  1654. setxmit() {
  1655.     if ((y = cmkey(xmitab,nxmit,"","",xxstring)) < 0) return(y);
  1656.     switch (y) {
  1657.       case XMITE:            /* EOF */
  1658.     y = cmtxt("Characters to send at end of file,\n\
  1659.  Use backslash codes for control characters","",&s,xxstring);
  1660.     if (y < 0) return(y);
  1661.     if ((int)strlen(s) > XMBUFL) {
  1662.         printf("?Too many characters, %d maximum\n",XMBUFL);
  1663.         return(-2);
  1664.     }
  1665.     strcpy(xmitbuf,s);
  1666.     return(success = 1);
  1667.  
  1668.       case XMITF:            /* Fill */
  1669.     y = cmnum("Numeric code for blank-line fill character","0",10,&x,
  1670.           xxstring);
  1671.     if ((y = setnum(&z,x,y,127)) < 0) return(y);
  1672.     xmitf = z;
  1673.     return(success = 1);
  1674.       case XMITL:            /* Linefeed */
  1675.         return(seton(&xmitl));
  1676.       case XMITS:            /* Locking-Shift */
  1677.         return(seton(&xmits));
  1678.       case XMITP:            /* Prompt */
  1679.     y = cmnum("Numeric code for host's prompt character, 0 for none",
  1680.           "10",10,&x,xxstring);
  1681.     if ((y = setnum(&z,x,y,127)) < 0) return(y);
  1682.     xmitp = z;
  1683.     return(success = 1);
  1684.       case XMITX:            /* Echo */
  1685.         return(seton(&xmitx));
  1686.       case XMITW:            /* Pause */
  1687.     y = cmnum("Number of milliseconds to pause between binary characters\n\
  1688. or text lines during transmission","0",10,&x,xxstring);
  1689.     if ((y = setnum(&z,x,y,1000)) < 0) return(y);
  1690.     xmitw = z;
  1691.     return(success = 1);
  1692.       default:
  1693.     return(-2);
  1694.     }
  1695. }
  1696. #endif /* NOXMIT */
  1697.  
  1698. /*  D O R M T  --  Do a remote command  */
  1699.  
  1700. VOID rmsg() {
  1701.     if (pflag)
  1702.       printf(
  1703. #ifdef CK_NEED_SIG
  1704.        " Type your escape character, %s, followed by X or E to cancel.\n",
  1705.        dbchr(escape)
  1706. #else
  1707.        " Press the X or E key to cancel.\n"
  1708. #endif /* CK_NEED_SIG */
  1709.       );
  1710. }
  1711.  
  1712. int
  1713. dormt(xx) int xx; {            /* REMOTE commands */
  1714.     int x, y, retcode;
  1715.     char *s, sbuf[50], *s2;
  1716.  
  1717.     if (xx < 0) return(xx);
  1718.  
  1719.     if (xx == XZSET) {            /* REMOTE SET */
  1720.     if ((y = cmkey(rmstab,nrms,"","",xxstring)) < 0) {
  1721.         if (y == -3) {
  1722.         printf("?Parameter name required\n");
  1723.         return(-9);
  1724.         } else return(y);
  1725.     }
  1726.     return(doprm(y,1));
  1727.     }
  1728.  
  1729.     switch (xx) {            /* Others... */
  1730.  
  1731. case XZCWD:                /* CWD */
  1732.     if ((x = cmtxt("Remote directory name","",&s,xxstring)) < 0) return(x);
  1733.     debug(F111,"XZCWD: ",s,x);
  1734.     *sbuf = NUL;
  1735.     s2 = sbuf;
  1736.  
  1737. /* The following is commented out, because there is practically no */
  1738. /* computer in the world that requires a password for directory changing. */
  1739. /* (The DEC-20 was the only one, and they're mostly all gone.) */
  1740. #ifdef DIRPWDPR
  1741.     if (*s != NUL) {            /* If directory name given, */
  1742.                     /* get password on separate line. */
  1743.         if (tlevel > -1) {        /* From take file... */
  1744.  
  1745.         if (fgets(sbuf,50,tfile[tlevel]) == NULL)
  1746.             fatal("take file ends prematurely in 'remote cwd'");
  1747.         debug(F110," pswd from take file",s2,0);
  1748.         for (x = (int)strlen(sbuf);
  1749.               x > 0 && (sbuf[x-1] == NL || sbuf[x-1] == CR);
  1750.          x--)
  1751.         sbuf[x-1] = '\0';
  1752.  
  1753.         } else {            /* From terminal... */
  1754.  
  1755.         printf(" Password: ");         /* get a password */
  1756. #ifdef OS2
  1757.         while (((x = isatty(0) ? coninc(0) :
  1758.              getchar()) != NL) && (x != CR)) {     /* with no echo */
  1759. #else
  1760.         while (((x = getchar()) != NL) && (x != CR)) { /* with no echo */
  1761. #endif /* OS2 */
  1762.             if ((x &= 0177) == '?') {
  1763.                 printf("? Password of remote directory\n Password: ");
  1764.             s2 = sbuf;
  1765.             *sbuf = NUL;
  1766.             }
  1767.             else if (x == ESC)    /* Mini command line editor... */
  1768.                 putchar(BEL);
  1769.         else if (x == BS || x == 0177)
  1770.             s2--;
  1771.         else if (x == 025) {    /* Ctrl-U */
  1772.             s2 = sbuf;
  1773.             *sbuf = NUL;
  1774.         }
  1775.             else
  1776.             *s2++ = x;
  1777.             }
  1778.         *s2 = NUL;
  1779.         putchar('\n');
  1780.         }
  1781.         s2 = sbuf;
  1782.     } else s2 = "";
  1783. #endif /* DIRPWDPR */
  1784.  
  1785.     debug(F110," password",s2,0);
  1786.     sstate = setgen('C',s,s2,"");
  1787.     retcode = 0;
  1788.     break;
  1789.  
  1790. case XZDEL:                /* Delete */
  1791.     if ((x = cmtxt("Name of remote file(s) to delete","",&s,xxstring)) < 0) {
  1792.     if (x == -3) {
  1793.         printf("?Name of remote file(s) required\n");
  1794.         return(-9);
  1795.     } else return(x);
  1796.     }
  1797.     if (local) ttflui();        /* If local, flush tty input buffer */
  1798.     retcode = sstate = rfilop(s,'E');
  1799.     break;
  1800.  
  1801. case XZDIR:                /* Directory */
  1802.     if ((x = cmtxt("Remote directory or file specification","",&s,
  1803.            xxstring)) < 0)
  1804.         return(x);
  1805.     if (local) ttflui();        /* If local, flush tty input buffer */
  1806.     rmsg();
  1807.     retcode = sstate = setgen('D',s,"","");
  1808.     break;
  1809.  
  1810. case XZHLP:                /* Help */
  1811.     if ((x = cmcfm()) < 0) return(x);
  1812.     sstate = setgen('H',"","","");
  1813.     retcode = 0;
  1814.     break; 
  1815.  
  1816. #ifndef NOPUSH
  1817. case XZHOS:                /* Host */
  1818.     if ((x = cmtxt("Command for remote system","",&cmarg,xxstring)) < 0)
  1819.       return(x);
  1820.     if ((int)strlen(cmarg) < 1)  {
  1821.     if (x == -3) {
  1822.         printf("?Remote host command required\n");
  1823.         return(-9);
  1824.     } else return(x);
  1825.     }
  1826.     rmsg();
  1827.     retcode = sstate = 'c';
  1828.     break; 
  1829. #endif /* NOPUSH */
  1830.  
  1831. #ifndef NOFRILLS
  1832. case XZKER:
  1833.     if ((x = cmtxt("Command for remote Kermit","",&cmarg,xxstring)) < 0)
  1834.       return(x);
  1835.     if ((int)strlen(cmarg) < 1)  {
  1836.     if (x == -3) {
  1837.         printf("?Remote Kermit command required\n");
  1838.         return(-9);
  1839.     } else return(x);
  1840.     }
  1841.     retcode = sstate = 'k';
  1842.     rmsg();
  1843.     break; 
  1844.  
  1845. case XZLGI: {                /* Login */
  1846.     char *p1, *p2, *p3;
  1847.     if ((x = cmfld("User ID","",&s,xxstring)) < 0) return(x);
  1848.     if ((p1 = malloc((int)strlen(s) + 1)) == NULL) {
  1849.     printf("Internal error: malloc\n");
  1850.     return(-2);
  1851.     } else strcpy(p1,s);
  1852.     if ((x = cmfld("Password","",&s,xxstring)) < 0) return(x);
  1853.     if ((p2 = malloc((int)strlen(s) + 1)) == NULL) {
  1854.     printf("Internal error: malloc\n");
  1855.     return(-2);
  1856.     } else strcpy(p2,s);
  1857.     if ((x = cmtxt("Account or carriage return","",
  1858.            &s,xxstring)) < 0 && x != -3)
  1859.     return(x);
  1860.     if ((p3 = malloc((int)strlen(s) + 1)) == NULL) {
  1861.     printf("Internal error: malloc\n");
  1862.     return(-2);
  1863.     } else strcpy(p3,s);
  1864.     sstate = setgen('I',p1,p2,p3);
  1865.     if (p3) free(p3);
  1866.     if (p2) free(p2);
  1867.     if (p1) free(p1);
  1868.     retcode = 0;
  1869.     break; 
  1870. }
  1871.  
  1872. case XZLGO:                /* Logout */
  1873.     if ((x = cmcfm()) < 0) return(x);
  1874.     sstate = setgen('I',"","","");
  1875.     retcode = 0;
  1876.     break; 
  1877.  
  1878. case XZPRI:                /* Print */
  1879.     if (!atdiso || !atcapr) {        /* Disposition attribute off? */
  1880.     printf("?Disposition Attribute is Off\n");
  1881.     return(-2);
  1882.     }
  1883.     cmarg = "";
  1884.     cmarg2 = "";
  1885.     if ((x = cmifi("Local file(s) to print on remote printer","",&s,&y,
  1886.            xxstring)) < 0) {
  1887.     if (x == -3) {
  1888.         printf("?Name of local file(s) required\n");
  1889.         return(-9);
  1890.     }
  1891.     return(x);
  1892.     }
  1893.     strcpy(line,s);            /* Make a safe copy of filename */
  1894.     *optbuf = NUL;            /* Wipe out any old options */
  1895.     if ((x = cmtxt("Options for remote print command","",&s,xxstring)) < 0)
  1896.       return(x);
  1897.     strcpy(optbuf,s);            /* Make a safe copy of options */
  1898.     if ((int)strlen(optbuf) > 94) {    /* Make sure this is legal */
  1899.     printf("?Option string too long\n");
  1900.     return(-9);
  1901.     }
  1902.     nfils = -1;                /* Expand file list internally */
  1903.     cmarg = line;            /* Point to file list. */
  1904.     rprintf = 1;            /* REMOTE PRINT modifier for SEND */
  1905.     sstate = 's';            /* Set start state to SEND */
  1906.     if (local) displa = 1;
  1907.     retcode = 0;
  1908.     break;
  1909. #endif /* NOFRILLS */
  1910.     
  1911. case XZSPA:                /* Space */
  1912.     if ((x = cmtxt("Confirm, or remote directory name","",&s,xxstring)) < 0)
  1913.       return(x);
  1914.     retcode = sstate = setgen('U',s,"","");
  1915.     break;
  1916.     
  1917. #ifndef NOFRILLS
  1918. case XZTYP:                /* Type */
  1919.     if ((x = cmtxt("Remote file specification","",&s,xxstring)) < 0)
  1920.       return(x);
  1921.     if ((int)strlen(s) < 1) {
  1922.     printf("?Remote filename required\n");
  1923.         return(-9);    
  1924.     }
  1925.     rmsg();
  1926.     retcode = sstate = rfilop(s,'T');
  1927.     break;
  1928. #endif /* NOFRILLS */
  1929.  
  1930. #ifndef NOFRILLS
  1931. case XZWHO:
  1932.     if ((x = cmtxt("Remote user name, or carriage return","",&s,xxstring)) < 0)
  1933.         return(x);
  1934.     retcode = sstate = setgen('W',s,"","");
  1935.     break;
  1936. #endif /* NOFRILLS */
  1937.  
  1938. case XZPWD:                /* PWD */
  1939.     if ((x = cmcfm()) < 0) return(x);
  1940.     sstate = setgen('A',"","","");
  1941.     retcode = 0;
  1942.     break; 
  1943.     
  1944. #ifndef NOSPL
  1945. case XZQUE: {                /* Query */
  1946.     char buf[2];
  1947.     extern char querybuf[], * qbufp;
  1948.     extern int qbufn;
  1949.     if ((y = cmkey(vartyp,nvartyp,"","",xxstring)) < 0)
  1950.       return(y);
  1951.     if ((x = cmtxt("Remote variable name","",&s,NULL)) < 0) /* No eval */
  1952.       return(x);
  1953.     query = 1;                /* QUERY is active */
  1954.     qbufp = querybuf;            /* Initialize query response buffer */
  1955.     qbufn = 0;
  1956.     querybuf[0] = NUL;
  1957.     buf[0] = (char) (y & 127);
  1958.     buf[1] = NUL;
  1959.     retcode = sstate = setgen('V',"Q",(char *)buf,s);
  1960.     break;
  1961. }
  1962.  
  1963. case XZASG: {                /* Assign */
  1964.     char buf[VNAML];
  1965.     if ((y = cmfld("Remote variable name","",&s,NULL)) < 0) /* No eval */
  1966.       return(y);
  1967.     strcpy(buf,s);
  1968.     if ((x = cmtxt("Assignment for remote variable",
  1969.            "",&s,xxstring)) < 0) /* Evaluate this one */
  1970.       return(x);
  1971. #ifdef COMMENT
  1972. /*
  1973.   Server commands can't be long packets.  In principle there's no reason
  1974.   why they shouldn't be, except that we don't know at this point if the
  1975.   server is capable of accepting long packets because we haven't started
  1976.   the protocol yet.  In practice, allowing a long packet here breaks a lot
  1977.   of assumptions, causes buffer overruns and crashes, etc.  To be fixed
  1978.   later.
  1979. */
  1980.     if ((int)strlen(s) > 85) {        /* Allow for encoding expansion */
  1981.     printf("?Sorry, value is too long - 85 characters max\n");
  1982.     return(-9);
  1983.     }
  1984. #endif /* COMMENT */
  1985.     retcode = sstate = setgen('V',"S",(char *)buf,s);
  1986.     break;
  1987. }
  1988. #endif /* NOSPL */
  1989.  
  1990. default:
  1991.         if ((x = cmcfm()) < 0) return(x);
  1992.         printf("?Not implemented - %s\n",cmdbuf);
  1993.         return(-2);
  1994.     }
  1995.     if (local) ttflui();        /* If local, flush tty input buffer */
  1996.     return(retcode);
  1997. }
  1998.  
  1999.  
  2000. /*  R F I L O P  --  Remote File Operation  */
  2001.  
  2002. CHAR
  2003. #ifdef CK_ANSIC
  2004. rfilop(char * s, char t)
  2005. #else
  2006. rfilop(s,t) char *s, t; 
  2007. #endif /* CK_ANSIC */
  2008. /* rfilop */ {
  2009.     if (*s == NUL) {
  2010.     printf("?File specification required\n");
  2011.     return((CHAR) 0);
  2012.     }
  2013.     debug(F111,"rfilop",s,t);
  2014.     return(setgen(t,s,"",""));
  2015. }
  2016.  
  2017. #ifdef ANYX25
  2018. int
  2019. setx25() {
  2020.     if ((y = cmkey(x25tab,nx25,"X.25 call options","",xxstring)) < 0)
  2021.       return(y);
  2022.     switch (y) {
  2023.       case XYUDAT:
  2024.     if ((z = cmkey(onoff,2,"X.25 call user data","",xxstring))
  2025.         < 0) return(z);
  2026.     if (z == 0) {
  2027.         if ((z = cmcfm()) < 0) return(z);
  2028.         cudata = 0;             /* disable call user data */
  2029.         return (success = 1);
  2030.     }
  2031.     if ((x = cmtxt("X.25 call user data string","",&s,xxstring)) < 0)
  2032.       return(x);
  2033.     if ((int)strlen(s) == 0) {
  2034.         return (-3);
  2035.     } else if ((int)strlen(s) > MAXCUDATA) {
  2036.         printf("?The length must be > 0 and <= %d\n",MAXCUDATA);
  2037.         return(-2);
  2038.     }
  2039.     if ((y = cmcfm()) < 0) return(y);
  2040.     strcpy(udata,s);
  2041.     cudata = 1;            /* X.25 call user data specified */
  2042.     return (success = 1);
  2043.       case XYCLOS:
  2044.     if ((z = cmkey(onoff,2,"X.25 closed user group call","",xxstring))
  2045.         < 0) return(z);
  2046.     if (z == 0) {
  2047.         if ((z = cmcfm()) < 0) return(z);
  2048.         closgr = -1;        /* disable closed user group */
  2049.         return (success = 1);
  2050.     }
  2051.     if ((y = cmnum("0 <= cug index >= 99","",10,&x,xxstring)) < 0)
  2052.       return(y);
  2053.     if (x < 0 || x > 99) {
  2054.         printf("?The choices are 0 <= cug index >= 99\n");
  2055.         return(-2);
  2056.     }
  2057.     if ((y = cmcfm()) < 0) return(y);
  2058.     closgr = x;            /* closed user group selected */
  2059.     return (success = 1);
  2060.  
  2061.       case XYREVC:
  2062.     if((z = cmkey(onoff,2,"X.25 reverse charge call","",xxstring)) < 0)
  2063.       return(z);
  2064.     if ((x = cmcfm()) < 0) return(x);
  2065.     revcall = z;
  2066.     return (success = 1);
  2067.     }
  2068. }
  2069.  
  2070. int
  2071. setpadp() {
  2072.     if ((y = cmkey(padx3tab,npadx3,"PAD X.3 parameter name","",xxstring)) < 0)
  2073.       return(y);
  2074.     x = y;
  2075.     switch (x) {
  2076.       case PAD_BREAK_CHARACTER:
  2077.     if ((y = cmnum("PAD break character value","",10,&z,xxstring)) < 0)
  2078.       return(y);
  2079.     if ((y = cmcfm()) < 0) return(y);
  2080.     break;
  2081.       case PAD_ESCAPE:
  2082.     if ((y = cmnum("PAD escape","",10,&z,xxstring)) < 0) return(y);
  2083.     if (z != 0 && z != 1) {
  2084.         printf("?The choices are 0 or 1\n");
  2085.         return(-2);
  2086.     }
  2087.     if ((y = cmcfm()) < 0) return(y);
  2088.     break;
  2089.       case PAD_ECHO:
  2090.      if ((y = cmnum("PAD echo","",10,&z,xxstring)) < 0) return(y);
  2091.     if (z != 0 && z != 1) {
  2092.         printf("?The choices are 0 or 1\n");
  2093.         return(-2);
  2094.     }
  2095.     if ((y = cmcfm()) < 0) return(y);
  2096.     break;
  2097.       case PAD_DATA_FORWARD_CHAR:
  2098.      if ((y = cmnum("PAD data forward char","",10,&z,xxstring)) < 0)
  2099.       return(y);
  2100.     if (z != 0 && z != 2) {
  2101.         printf("?The choices are 0 or 2\n");
  2102.         return(-2);
  2103.     }
  2104.     if ((y = cmcfm()) < 0) return(y);
  2105.     break;
  2106.       case PAD_DATA_FORWARD_TIMEOUT:
  2107.      if ((y = cmnum("PAD data forward timeout","",10,&z,xxstring)) < 0)
  2108.         return(y);
  2109.     if (z < 0 || z > 255) {
  2110.         printf("?The choices are 0 or 1 <= timeout <= 255\n");
  2111.         return(-2);
  2112.     }
  2113.     if ((y = cmcfm()) < 0) return(y);
  2114.     break;
  2115.       case PAD_FLOW_CONTROL_BY_PAD:
  2116.      if ((y = cmnum("PAD pad flow control","",10,&z,xxstring)) < 0)
  2117.       return(y);
  2118.     if (z != 0 && z != 1) {
  2119.         printf("?The choices are 0 or 1\n");
  2120.         return(-2);
  2121.     }
  2122.     if ((y = cmcfm()) < 0) return(y);
  2123.     break;
  2124.       case PAD_SUPPRESSION_OF_SIGNALS:
  2125.      if ((y = cmnum("PAD service","",10,&z,xxstring)) < 0) return(y);
  2126.     if (z != 0 && z != 1) {
  2127.         printf("?The choices are 0 or 1\n");
  2128.         return(-2);
  2129.     }
  2130.     if ((y = cmcfm()) < 0) return(y);
  2131.     break;
  2132.  
  2133.       case PAD_BREAK_ACTION:
  2134.      if ((y = cmnum("PAD break action","",10,&z,xxstring)) < 0) return(y);
  2135.     if (z != 0 && z != 1 && z != 2 && z != 5 && z != 8 && z != 21) {
  2136.         printf("?The choices are 0, 1, 2, 5, 8 or 21\n");
  2137.         return(-2);
  2138.     }
  2139.     if ((y = cmcfm()) < 0) return(y);
  2140.     break;
  2141.  
  2142.       case PAD_SUPPRESSION_OF_DATA:
  2143.      if ((y = cmnum("PAD data delivery","",10,&z,xxstring)) < 0) return(y);
  2144.     if (z != 0 && z != 1) {
  2145.         printf("?The choices are 0 or 1\n");
  2146.         return(-2);
  2147.     }
  2148.     if ((y = cmcfm()) < 0) return(y);
  2149.     break;
  2150.  
  2151.       case PAD_PADDING_AFTER_CR:
  2152.      if ((y = cmnum("PAD crpad","",10,&z,xxstring)) < 0) return(y);
  2153.     if (z < 0 || z > 7) {
  2154.         printf("?The choices are 0 or 1 <= crpad <= 7\n");
  2155.         return(-2);
  2156.     }
  2157.     if ((y = cmcfm()) < 0) return(y);
  2158.     break;
  2159.  
  2160.       case PAD_LINE_FOLDING:
  2161.      if ((y = cmnum("PAD linefold","",10,&z,xxstring)) < 0) return(y);
  2162.     if (z < 0 || z > 255) {
  2163.         printf("?The choices are 0 or 1 <= linefold <= 255\n");
  2164.         return(-2);
  2165.     }
  2166.     if ((y = cmcfm()) < 0) return(y);
  2167.     break;
  2168.  
  2169.       case PAD_LINE_SPEED:
  2170.      if ((y = cmnum("PAD baudrate","",10,&z,xxstring)) < 0) return(y);
  2171.     if (z < 0 || z > 18) {
  2172.         printf("?The choices are 0 <= baudrate <= 18\n");
  2173.         return(-2);
  2174.     }
  2175.     if ((y = cmcfm()) < 0) return(y);
  2176.     break;
  2177.  
  2178.       case PAD_FLOW_CONTROL_BY_USER:
  2179.      if ((y = cmnum("PAD terminal flow control","",10,&z,xxstring)) < 0)
  2180.         return(y);
  2181.     if (z != 0 && z != 1) {
  2182.         printf("?The choices are 0 or 1\n");
  2183.         return(-2);
  2184.     }
  2185.     if ((y = cmcfm()) < 0) return(y);
  2186.     break;
  2187.  
  2188.       case PAD_LF_AFTER_CR:
  2189.      if ((y = cmnum("PAD crpad","",10,&z,xxstring)) < 0) return(y);
  2190.     if (z < 0 || z == 3 || z > 7) {
  2191.         printf("?The choices are 0, 1, 2, 4, 5, 6 or 7\n");
  2192.         return(-2);
  2193.     }
  2194.     if ((y = cmcfm()) < 0) return(y);
  2195.     break;
  2196.  
  2197.       case PAD_PADDING_AFTER_LF:
  2198.      if ((y = cmnum("PAD lfpad","",10,&z,xxstring)) < 0) return(y);
  2199.     if (z < 0 || z > 7) {
  2200.         printf("?The choices are 0 or 1 <= lfpad <= 7\n");
  2201.         return(-2);
  2202.     }
  2203.     if ((y = cmcfm()) < 0) return(y);
  2204.     break;
  2205.  
  2206.       case PAD_EDITING:
  2207.      if ((y = cmnum("PAD edit control","",10,&z,xxstring)) < 0) return(y);
  2208.     if (z != 0 && z != 1) {
  2209.         printf("?The choices are 0 or 1\n");
  2210.         return(-2);
  2211.     }
  2212.     if ((y = cmcfm()) < 0) return(y);
  2213.     break;
  2214.  
  2215.       case PAD_CHAR_DELETE_CHAR:
  2216.      if ((y = cmnum("PAD char delete char","",10,&z,xxstring)) < 0)
  2217.         return(y);
  2218.     if (z < 0 || z > 127) {
  2219.         printf("?The choices are 0 or 1 <= chardelete <= 127\n");
  2220.         return(-2);
  2221.     }
  2222.     if ((y = cmcfm()) < 0) return(y);
  2223.     break;
  2224.  
  2225.       case PAD_BUFFER_DELETE_CHAR:
  2226.      if ((y = cmnum("PAD buffer delete char","",10,&z,xxstring)) < 0)
  2227.         return(y);
  2228.     if (z < 0 || z > 127) {
  2229.         printf("?The choices are 0 or 1 <= bufferdelte <= 127\n");
  2230.         return(-2);
  2231.     }
  2232.     if ((y = cmcfm()) < 0) return(y);
  2233.     break;
  2234.  
  2235.       case PAD_BUFFER_DISPLAY_CHAR:
  2236.      if ((y = cmnum("PAD display line char","",10,&z,xxstring)) < 0)
  2237.         return(y);
  2238.     if (z < 0 || z > 127) {
  2239.         printf("?The choices are 0 or 1 <= displayline <= 127\n");
  2240.         return(-2);
  2241.     }
  2242.     if ((y = cmcfm()) < 0) return(y);
  2243.     break;
  2244.     }
  2245.     padparms[x] = z;
  2246.     return(success = 1);
  2247. }
  2248. #endif /* ANYX25 */ 
  2249.  
  2250. int
  2251. setat(rmsflg) int rmsflg; {
  2252.     int xx;
  2253.     if ((y = cmkey(attrtab,natr,"File Attribute packets","",xxstring)) < 0)
  2254.       return(y);    
  2255.     if (y == AT_XALL) {            /* ATTRIBUTES ALL ON or ALL OFF */
  2256.     if ((z = seton(&xx)) < 0) return(z);
  2257.     if (rmsflg) {
  2258.         printf("Sorry, command not available\n");
  2259.         return(-9);
  2260.     } else {
  2261.         atenci = xx;        /* Encoding in */
  2262.         atenco = xx;        /* Encoding out */
  2263.         atdati = xx;        /* Date in */
  2264.         atdato = xx;        /* Date out */
  2265.         atdisi = xx;        /* Disposition in/out */
  2266.         atdiso = xx;
  2267.         atleni = xx;        /* Length in/out (both kinds) */
  2268.         atleno = xx;
  2269.         atblki = xx;        /* Blocksize in/out */
  2270.         atblko = xx;
  2271.         attypi = xx;        /* File type in/out */
  2272.         attypo = xx;
  2273.         atsidi = xx;        /* System ID in/out */
  2274.         atsido = xx;
  2275.         atsysi = xx;        /* System-dependent params in/out */
  2276.         atsyso = xx;
  2277. #ifdef STRATUS
  2278.         atfrmi = xx;        /* Format in/out */
  2279.         atfrmo = xx;
  2280.         atcrei = xx;        /* Creator id in/out */
  2281.         atcreo = xx;
  2282.         atacti = xx;        /* Account in/out */
  2283.         atacto = xx;
  2284. #endif /* STRATUS */
  2285.     }
  2286.     return(z);
  2287.     } else if (y == AT_ALLY || y == AT_ALLN) { /* ATTRIBUTES ON or OFF */
  2288.     if ((x = cmcfm()) < 0) return(x);
  2289.     atcapr = (y == AT_ALLY) ? 1 : 0;
  2290.     if (rmsflg) {
  2291.         sstate = setgen('S', "132", atcapr ? "1" : "0", "");
  2292.         return((int) sstate);
  2293.     } else return(success = 1);
  2294.     }
  2295.     /* Otherwise, it's an individual attribute that wants turning off/on */
  2296.  
  2297.     if ((z = cmkey(onoff,2,"","",xxstring)) < 0) return(z);
  2298.     if ((x = cmcfm()) < 0) return(x);
  2299.  
  2300. /* There are better ways to do this... */
  2301. /* The real problem is that we're not separating the in and out cases */
  2302. /* and so we have to arbitrarily pick the "in" case, i.e tell the remote */
  2303. /* server to ignore incoming attributes of the specified type, rather */
  2304. /* than telling it not to send them.  The protocol does not (yet) define */
  2305. /* codes for "in-and-out-at-the-same-time". */
  2306.  
  2307.     switch(y) {
  2308.       case AT_DISP:
  2309.     if (rmsflg) {
  2310.         sstate = setgen('S', "142", z ? "1" : "0", "");
  2311.         return((int) sstate);
  2312.     }
  2313.     atdisi = atdiso = z; break;
  2314.       case AT_ENCO:
  2315.     if (rmsflg) {
  2316.         sstate = setgen('S', "141", z ? "1" : "0", "");
  2317.         return((int) sstate);
  2318.     }
  2319.     atenci = atenco = z; break;
  2320.       case AT_DATE:
  2321.     if (rmsflg) {
  2322.         sstate = setgen('S', "135", z ? "1" : "0", "");
  2323.         return((int) sstate);
  2324.     }
  2325.     atdati = atdato = z; break;
  2326.       case AT_LENB:
  2327.       case AT_LENK:
  2328.     if (rmsflg) {
  2329.         sstate = setgen('S', "133", z ? "1" : "0", "");
  2330.         return((int) sstate);
  2331.     }
  2332.     atleni = atleno = z; break;
  2333.       case AT_BLKS:
  2334.     if (rmsflg) {
  2335.         sstate = setgen('S', "139", z ? "1" : "0", "");
  2336.         return((int) sstate);
  2337.     }
  2338.     atblki = atblko = z; break;
  2339.       case AT_FTYP:
  2340.     if (rmsflg) {
  2341.         sstate = setgen('S', "134", z ? "1" : "0", "");
  2342.         return((int) sstate);
  2343.     }
  2344.     attypi = attypo = z; break;
  2345. #ifdef STRATUS
  2346.       case AT_CREA:
  2347.     if (rmsflg) {
  2348.         sstate = setgen('S', "136", z ? "1" : "0", "");
  2349.         return((int) sstate);
  2350.     }
  2351.     atcrei = atcreo = z; break;
  2352.       case AT_ACCT:
  2353.     if (rmsflg) {
  2354.         sstate = setgen('S', "137", z ? "1" : "0", "");
  2355.         return((int) sstate);
  2356.     }
  2357.     atacti = atacto = z; break;
  2358. #endif /* STRATUS */
  2359.       case AT_SYSI:
  2360.     if (rmsflg) {
  2361.         sstate = setgen('S', "145", z ? "1" : "0", "");
  2362.         return((int) sstate);
  2363.     }
  2364.     atsidi = atsido = z; break;
  2365. #ifdef STRATUS
  2366.       case AT_RECF:
  2367.     if (rmsflg) {
  2368.         sstate = setgen('S', "146", z ? "1" : "0", "");
  2369.         return((int) sstate);
  2370.     }
  2371.         atfrmi = atfrmo = z; break;
  2372. #endif /* STRATUS */
  2373.       case AT_SYSP:
  2374.     if (rmsflg) {
  2375.         sstate = setgen('S', "147", z ? "1" : "0", "");
  2376.         return((int) sstate);
  2377.     }
  2378.     atsysi = atsyso = z; break;
  2379.       default:
  2380.     printf("?Not available\n");
  2381.     return(-2);
  2382.     }
  2383.     return(1);
  2384. }
  2385.  
  2386. #ifndef NOSPL
  2387. int
  2388. setinp() {
  2389.     if ((y = cmkey(inptab,ninp,"","",xxstring)) < 0) return(y);
  2390.     switch (y) {
  2391.       case IN_DEF:            /* SET INPUT DEFAULT-TIMEOUT */
  2392.     z = cmnum("Positive number","",10,&x,xxstring);
  2393.     return(setnum(&indef,x,z,94));
  2394.       case IN_TIM:            /* SET INPUT TIMEOUT-ACTION */
  2395.     if ((z = cmkey(intimt,2,"","",xxstring)) < 0) return(z);
  2396.     if ((x = cmcfm()) < 0) return(x);
  2397.     intime[cmdlvl] = z;
  2398.     return(success = 1);
  2399.       case IN_CAS:            /* SET INPUT CASE */
  2400.     if ((z = cmkey(incast,2,"","",xxstring)) < 0) return(z);
  2401.     if ((x = cmcfm()) < 0) return(x);
  2402.     inpcas[cmdlvl] = z;
  2403.     return(success = 1);
  2404.       case IN_ECH:            /* SET INPUT ECHO */
  2405.     return(seton(&inecho));
  2406.       case IN_SIL:            /* SET INPUT SILENCE */
  2407.     z = cmnum("Seconds of inactivity before INPUT fails","",10,&x,
  2408.           xxstring);
  2409.     return(setnum(&insilence,x,z,-1));
  2410.     }
  2411.     return(0);
  2412. }
  2413. #endif /* NOSPL */
  2414.  
  2415. /*
  2416.   setlin -- parse name of and then open a communication device.
  2417.   Call with:
  2418.     xx == XXLINE for a serial (tty) line, XXHOST for a network host,
  2419.     zz == 0 means if user doesn't give a device name, continue current
  2420.             active connection (if any);
  2421.     zz != 0 means if user doesn't give a device name, then close the
  2422.             current connection and restore the default communication device.
  2423. */
  2424. int
  2425. setlin(xx, zz) int xx, zz; {
  2426.     if (xx == XYHOST) {            /* SET HOST <hostname> */
  2427. #ifndef NETCONN
  2428.         printf("?Network connections not supported\n");
  2429.     return(-9);
  2430. #else
  2431.     if (
  2432.         (nettype != NET_DEC) &&
  2433.         (nettype != NET_SX25) &&
  2434.         (nettype != NET_VX25) &&
  2435. #ifdef NPIPE
  2436.         (nettype != NET_PIPE) &&
  2437. #endif /* NPIPE */
  2438. #ifdef CK_NETBIOS
  2439.         (nettype != NET_BIOS) &&
  2440. #endif /* CK_NETBIOS */
  2441.         (nettype != NET_TCPB)) {
  2442.         printf("?Network type not supported\n");
  2443.         return(-9);
  2444.     }
  2445. #ifdef CK_NETBIOS
  2446.     if ( nettype == NET_BIOS) {
  2447.         if ((x = cmtxt( zz ? 
  2448.     "server name, *,\n or carriage return to close an open connection" :
  2449.     "server name, *,\n or carriage return to resume an open connection",
  2450.                "",&s,xxstring)) < 0)
  2451.           return(x);
  2452.     } else
  2453. #endif /* CK_NETBIOS */
  2454. #ifdef NPIPE
  2455.     if (nettype == NET_PIPE ) {
  2456.         if ((x = cmtxt( zz ? 
  2457.     "server name, *,\n or carriage return to close an open connection" :
  2458.     "server name, *,\n or carriage return to resume an open connection",
  2459.                "",&s,xxstring)) < 0)
  2460.           return(x);
  2461.         if ( *s != '\0' ) {
  2462.         if ( strcmp(s,"*")) {    /* If remote, */
  2463.             strcpy(line,"\\\\"); /* begin with server name */
  2464.             strcat(line,s);
  2465.         } else {
  2466.             line[0]='\0' ;
  2467.         }
  2468.         strcat(line,"\\pipe\\"); /* Make this a pipe name */
  2469.         strcat(line,pipename);   /* Add the name of the pipe */
  2470.         s = line;
  2471.         }
  2472.     } else
  2473. #endif /* NPIPE */
  2474.       if (nettype != NET_TCPB) {    /* Not a TCP/IP connection */
  2475.                     /* Just get a text string */
  2476.         if ((x = cmtxt( zz ? 
  2477.     "Network host name,\n or carriage return to close an open connection" :
  2478.     "Network host name,\n or carriage return to resume an open connection",
  2479.                "",&s,xxstring)) < 0)
  2480.           return(x);
  2481.     } else {            /* TCP/IP connection... */
  2482.  
  2483.         /* Parse for host and service separately. */
  2484.  
  2485.         if ((x = cmfld( zz ?
  2486.    "IP host name or number,\n or carriage return to close an open connection" :
  2487.    "IP host name or number,\n or carriage return to resume an open connection",
  2488.                "",&s,xxstring)) < 0) {
  2489.         if (x != -3)        /* Parse error */
  2490.           return(x);        /* return it */
  2491.         else if (!network) {
  2492.             printf("?Host name or address required\n");
  2493.             return(-9);
  2494.         } else if (!zz)        /* No hostname given */
  2495.           return(1);        /* and none required, */
  2496.         }                /* continue current connection. */
  2497.         if (*s) {            /* If they gave a host name... */
  2498.         strcpy(line,s);        /* make a copy */
  2499.         /* Check for "host:service" */
  2500.         for ( ; (*s != '\0') && (*s != ':'); s++) ;
  2501.  
  2502.         /* If no service given, let them type one now. */
  2503.  
  2504.         if (!*s) {
  2505.             if ((x = cmfld(
  2506.     "TCP service name or number,\n or carriage return for telnet (23)",
  2507.                    "23",&s,xxstring)) < 0 && x != -3)
  2508.               return(x);
  2509.             if (*s) {        /* If they gave a service, */
  2510.             strcat(line,":"); /* concatenate it to the hostname */
  2511.             strcat(line,s);    /* separated by a colon, because */
  2512.             }            /* this is how ttopen() wants it. */
  2513.         }
  2514.         if ((x = cmcfm()) < 0) return(x); /* Confirm the command */
  2515.         s = line;
  2516.         }
  2517.     }
  2518.  
  2519.     /* New connection wanted. */
  2520.  
  2521.     if (!hupok(1))
  2522.       return(success = 0);
  2523.  
  2524.     ttflui();            /* Clear away buffered up junk */
  2525.     ttclos(0);            /* Close old connection, if any */
  2526.     if (oldplex > -1)        /* Restore duplex setting. */
  2527.       duplex = oldplex;
  2528.     if (*s) {            /* They gave a hostname */
  2529.         x = 1;            /* Network connection always local */
  2530.         mdmsav = mdmtyp;        /* Remember old modem type */
  2531.         mdmtyp = -nettype;        /* Special code for network */
  2532.         if (nettype == NET_TCPB) {    /* For TCP/IP telnet connections */
  2533.         oldplex = duplex;    /* Remember previous duplex */
  2534.         duplex = 0;        /* Set full duplex and let */
  2535.                                 /* negotiations change if necessary. */
  2536.         }
  2537.     } else {            /* They just said "set host" */
  2538.         if (network && msgflg)
  2539.           printf(" Closing connection\n");
  2540.         s = dftty;            /* So go back to normal */
  2541.         x = dfloc;            /* default tty, location, */
  2542.         network = 0;        /* No more network connection. */
  2543.         if (oldplex > -1)
  2544.           duplex = oldplex;        /* Restore old duplex setting. */
  2545.         if (mdmtyp < 0) {        /* Switching from net to async? */
  2546.         if (mdmsav > -1)    /* Restore modem type from last */
  2547.           mdmtyp = mdmsav;    /* SET MODEM command, if any. */
  2548.         else
  2549.           mdmtyp = 0;
  2550.         }
  2551.     }
  2552. #endif /* NETCONN */
  2553.     }
  2554.  
  2555. /* Serial tty device, possibly modem, connection... */
  2556.  
  2557.     if (xx == XYLINE) {            /* SET LINE */
  2558. #ifdef OS2                /* or SET PORT */
  2559. /*
  2560.   User can type:
  2561.     COM1..COM8 = Regular COM port
  2562.     1..8       = Synonym for COM1..COM8, is translated to COM1..COM8
  2563.     _n         = (n is a number) = open file handle
  2564.     string     = any text string = name of some other kind of device,
  2565.                  taken literally, as given.
  2566. */
  2567.     if ((x = cmtxt("Communication device name",dftty,&s,xxstring)) < 0)
  2568.       return(x);
  2569.     debug(F110,"OS2 SET PORT s",s,0);
  2570.     y = lookup(os2devtab,s,nos2dev,&x); /* Look up in keyword table */
  2571.     debug(F101,"OS2 SET PORT x","",x);
  2572.     debug(F101,"OS2 SET PORT y","",y);
  2573.     if ((y > -1) && (x >= 0 && x < 8)) { /* User typed a digit 1..8 */
  2574.         s = os2devtab[x+8].kwd;    /* Substitite its real name */
  2575.         debug(F110,"OS2 SET PORT subst s",s,"");
  2576.     } else if (*s == '_') {        /* User used "_" prefix */
  2577.         s++;            /* Remove it */
  2578.         debug(F110,"OS2 SET PORT _subst s",s,0); /* Rest must be numeric */
  2579.         if (!rdigits(s)) {
  2580.         printf("?Invalid format for file handle\n");
  2581.         return(-9);
  2582.         }
  2583.     }
  2584.     debug(F110,"OS2 SET PORT final s",s,"");
  2585. #else
  2586.     if ((x = cmtxt("Communication device name",dftty,&s,xxstring)) < 0)
  2587.       return(x);
  2588. #endif /* OS2 */
  2589.  
  2590.     if (!hupok(1))
  2591.       return(success = 0);
  2592.  
  2593.     if (local) ttflui();        /* Clear away buffered up junk */
  2594.     ttclos(0);            /* Close old line, if any was open */
  2595.     if (*s) {            /* They gave a device name */
  2596.         x = -1;            /* Let ttopen decide about it */
  2597.     } else {            /* They just said "set line" */
  2598.         s = dftty;            /* so go back to normal tty */
  2599.         x = dfloc;            /* and mode. */
  2600.     }
  2601. #ifdef NETCONN
  2602.     if (mdmtyp < 0) {        /* Switching from net to async? */
  2603.         if (mdmsav > -1)        /* Restore modem type from last */
  2604.           mdmtyp = mdmsav;        /* SET MODEM command, if any. */
  2605.         else
  2606.           mdmtyp = 0;
  2607.         mdmsav = -1;
  2608.     }
  2609.     if (oldplex > -1) {        /* Restore previous duplex setting. */
  2610.         duplex = oldplex;
  2611.         oldplex = -1;
  2612.     }
  2613.  
  2614.     if (network) {
  2615. #ifdef TNCODE
  2616. /* This should be unnecessary, since ttclos() did it already? */
  2617. /* But it can't hurt ... */
  2618.         tn_init = 0;        /* TELNET not init'd any more. */
  2619. #endif /* TNCODE */
  2620.         network = 0;        /* No more network. */
  2621.     }
  2622. #endif /* NETCONN */
  2623.     }
  2624. #ifdef COMMENT
  2625. /*
  2626.   The following is removed, not so much because it's a horrible hack, but
  2627.   because it only works if the SET FLOW command was given *before* the SET
  2628.   LINE command, whereas normally these commands can be given in any order.
  2629. */
  2630. #ifdef NEXT
  2631. /*
  2632.   This is a horrible hack, but it's nice for users.  On the NeXT, you select
  2633.   RTS/CTS hardware flow control not by system calls, but by referring to the
  2634.   device with a different name.  If the user has asked for RTS/CTS flow
  2635.   control on a NeXT, but used the non-RTS/CTS device name in the SET LINE
  2636.   command, we make the appropriate substitute here.  I wonder how much bigger
  2637.   this section of code will grow as the years go by... 
  2638. */
  2639.     if ((flow == FLO_RTSC) &&        /* RTS/CTS flow control selected */
  2640.     strcmp(s,dftty)) {        /*  ...on external port? */
  2641.     y = strlen(s);            /* Yes, insert "f" as next-to-last */
  2642.     if (s[y-2] != 'f') {        /* character in device name if not */
  2643.         strcpy(line,s);        /* already there... */
  2644.         line[y] = line[y-1];    /* So /dev/cua => /dev/cufa, etc. */
  2645.         line[y-1] = 'f';
  2646.         line[y+1] = '\0';
  2647.         s = line;
  2648.     }
  2649.     }
  2650. #endif /* NEXT */
  2651. #endif /* COMMENT */
  2652.  
  2653.     if ((y = ttopen(s,&x,mdmtyp,cdtimo)) < 0 ) { /* Open the new line */
  2654.     if (y == -2) {
  2655.         printf("?Timed out, no carrier.\n");
  2656.         printf("Try SET CARRIER OFF and SET LINE again, or else\n");
  2657.         printf("SET MODEM, SET LINE, and then DIAL.\n");
  2658.     } else if (y == -3) {
  2659.         printf("Sorry, access to lock denied: %s\n",s);
  2660.     } else if (y == -4) {
  2661.         printf("Sorry, access to device denied: %s\n",s);
  2662.     } else if (y == -5) {
  2663. #ifdef VMS
  2664.         printf("Sorry, device is in use or otherwise unavailable: %s\n",s);
  2665. #else
  2666.         printf("Sorry, device is in use: %s\n",s);
  2667. #endif /* VMS */
  2668.         } else {            /* Other error. */
  2669. #ifndef VMS
  2670.         if (errno) {
  2671.         int x;            /* Find a safe, long buffer */
  2672.         x = strlen(line) + 2;    /* for the error message. */
  2673.         if (LINBUFSIZ - x > 100) { /* Allow room for 100 chars */
  2674.             tp = line + x;
  2675.             sprintf(tp,"Sorry, can't open connection: %s",s);
  2676.             perror(tp);
  2677.         } else printf("Sorry, can't open connection: %s\n",s);
  2678.         } else
  2679. #endif /* VMS */
  2680.           printf("Sorry, can't open connection: %s\n",s);
  2681.     }    
  2682. /*
  2683.   NOTE:
  2684.   The following will fail if Kermit is running as a daemon with no
  2685.   controlling tty.  Needs research.
  2686. */
  2687.     local = dfloc;            /* Go back to normal */
  2688. #ifndef MAC
  2689.     strcpy(ttname,dftty);        /* Restore default tty name */
  2690. #endif /* MAC */
  2691.     speed = ttgspd();
  2692.     network = 0;            /* No network connection active */
  2693.     return(success = 0);        /* Return failure */
  2694.     }
  2695.     if (x > -1) local = x;        /* Opened ok, set local/remote. */
  2696.     network = (mdmtyp < 0);        /* Remember connection type. */
  2697.     strcpy(ttname,s);            /* Copy name into real place. */
  2698. #ifdef OS2
  2699.     {                    /* Set session title */
  2700.     char * p, name[72];        /* in window list. */
  2701.     strcpy(name,"C-Kermit ");
  2702.     p = name + 9;
  2703.     strncpy(p, ttname, 60);
  2704.     while (*p) {            /* Uppercase it for emphasis. */
  2705.         if (islower(*p))
  2706.           *p = toupper(*p);
  2707.         p++;
  2708.     }
  2709.     os2settitle((char *) name);
  2710.     }
  2711. #endif /* OS2 */
  2712.     speed = ttgspd();            /* Get the current speed. */
  2713.     debug(F111,"set line ",ttname,local);
  2714. #ifdef NETCONN
  2715.     if (network)
  2716. #ifdef CK_SPEED
  2717.       /* Force prefixing of 255 on TCP/IP connections... */
  2718.       if (nettype == NET_TCPB) {
  2719.       ctlp[255] = 1;
  2720.       } else
  2721. #endif /* CK_SPEED */
  2722.     if (nettype == NET_SX25 || nettype == NET_VX25)
  2723.       duplex = 1;            /* Local echo for X.25 */
  2724. #endif /* NETCONN */
  2725.     return(success = 1);
  2726. }
  2727. #endif /* NOICP */
  2728.