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

  1. #ifndef NOICP
  2.  
  3. /*  C K U U S 7 --  "User Interface" for Unix Kermit, part 7  */
  4.  
  5. /*
  6.   Author: Frank da Cruz (fdc@columbia.edu, FDCCU@CUVMA.BITNET),
  7.   Columbia University Center for Computing Activities.
  8.   First released January 1985.
  9.   Copyright (C) 1985, 1993, Trustees of Columbia University in the City of New
  10.   York.  Permission is granted to any individual or institution to use this
  11.   software as long as it is not sold for profit.  This copyright notice must be
  12.   retained.  This software may not be included in commercial products without
  13.   written permission of Columbia University.
  14. */
  15.  
  16. /*
  17.   This file created from parts of ckuus3.c, which became to big for
  18.   Mark Williams Coherent compiler to handle.
  19. */
  20.  
  21. /*
  22.   Definitions here supersede those from system include files.
  23. */
  24. #include "ckcdeb.h"            /* Debugging & compiler things */
  25. #include "ckcasc.h"            /* ASCII character symbols */
  26. #include "ckcker.h"            /* Kermit application definitions */
  27. #include "ckcxla.h"            /* Character set translation */
  28. #include "ckcnet.h"            /* Network symbols */
  29. #include "ckuusr.h"            /* User interface symbols */
  30.  
  31. static int x, y = 0, z;
  32. static char *s;
  33.  
  34. static int mdmsav = -1;            /* Save modem type around network */
  35. static int oldplex = -1;        /* Duplex holder around network */
  36.  
  37. extern int success, nfilp, fmask, fncnv, frecl, nfttyp, binary, warn, msgflg;
  38. extern int cmask, maxrps, wslotr, bigsbsiz, bigrbsiz, urpsiz, rpsiz, spsiz;
  39. extern int spsizr, spsizf, maxsps, spmax, pflag, bctr, npad, timef, timint;
  40. extern int pkttim, rtimo, local, nfils, displa, atcapr, nettype, escape;
  41. extern int mdmtyp, duplex, dfloc, network, cdtimo, fncact, mypadn;
  42. extern int tnlm, sosi, tlevel, lf_opts, backgrd, flow, fdispla;
  43. extern int
  44.   atenci, atenco, atdati, atdato, atleni, atleno, atblki, atblko,
  45.   attypi, attypo, atsidi, atsido, atsysi, atsyso, atdisi, atdiso; 
  46.  
  47. extern long speed;
  48.  
  49. extern CHAR sstate, eol, seol, stchr, mystch, mypadc, padch;
  50.  
  51. extern char *cmarg, *cmarg2, *dftty;
  52.  
  53. extern char tmpbuf[], *tp, *lp;        /* Temporary buffer & pointers */
  54. #ifndef NOFRILLS
  55. extern char optbuf[];            /* Buffer for MAIL or PRINT options */
  56. extern int rprintf;            /* REMOTE PRINT flag */
  57. #endif /* NOFRILLS */
  58. extern char ttname[];
  59.  
  60. extern struct keytab onoff[], filtab[], fttab[], rltab[];
  61. extern int nrlt;
  62.  
  63. #ifdef DCMDBUF
  64. extern char *atxbuf;            /* Atom buffer */
  65. extern char *cmdbuf;            /* Command buffer */
  66. extern char *line;            /* Character buffer for anything */
  67. extern int *intime;            /* INPUT TIMEOUT */
  68. #ifdef CK_CURSES
  69. /* This needs cleaning up... */
  70. #ifdef UNIX
  71. extern char *trmbuf;            /* Termcap buffer */
  72. #endif /* UNIX */
  73. #ifdef OS2
  74. extern char *trmbuf;            /* Termcap buffer */
  75. #endif /* OS2 */
  76. #ifdef OSK
  77. extern char *trmbuf;            /* Termcap buffer */
  78. #endif /* OSK */
  79. #ifdef AMIGA
  80. extern char *trmbuf;            /* Termcap buffer */
  81. #endif /* AMIGA */
  82. #endif /* CK_CURSES */
  83. #else
  84. extern char atxbuf[];            /* Atom buffer */
  85. extern char cmdbuf[];            /* Command buffer */
  86. extern char line[];            /* Character buffer for anything */
  87. extern int intime[];
  88. #ifdef CK_CURSES
  89. #ifdef UNIX
  90. extern char trmbuf[];            /* Termcap buffer */
  91. #endif /* UNIX */
  92. #endif /* CK_CURSES */
  93. #endif /* DCMDBUF */
  94.  
  95. #ifndef NOCSETS
  96. extern struct keytab fcstab[];        /* For 'set file character-set' */
  97. extern struct keytab ttcstab[];
  98. extern int nfilc, fcharset, ntermc, tcsr, tcsl;
  99. #endif /* NOCSETS */
  100.  
  101. #ifndef NOSPL
  102. extern int cmdlvl;            /* Overall command level */
  103. #ifdef DCMDBUF
  104. extern int *incase;            /* INPUT CASE setting on cmd stack */
  105. #else
  106. extern int incase[];
  107. #endif /* DCMDBUF */
  108. #endif /* NOSPL */
  109.  
  110. #ifdef TNCODE
  111. extern int tn_init;
  112. #endif /* TNCODE */
  113.  
  114. #ifdef SUNX25
  115. extern int revcall, closgr, cudata, nx25, npadx3;
  116. extern char udata[MAXCUDATA];
  117. extern CHAR padparms[MAXPADPARMS+1];
  118. extern struct keytab x25tab[], padx3tab[];
  119. #endif /* SUNX25 */
  120.  
  121. #ifdef CK_CURSES
  122. #ifndef VMS
  123. _PROTOTYP(int tgetent,(char *, char *));
  124. #endif /* VMS */
  125. #endif /* CK_CURSES */
  126.  
  127. #ifndef NODIAL
  128. extern int dialhng, dialtmo, dialksp, dialdpy, dialmnp, dialmhu;
  129. extern int mdmspd;
  130. extern char *dialini, *dialdir, *dialcmd, *dialnpr;
  131. extern FILE * dialfd;
  132.  
  133.  
  134. struct keytab dialtab[] = {
  135.     "dial-command", XYDDIA, 0,
  136.     "directory", XYDDIR, 0,
  137.     "display", XYDDPY, 0,
  138.     "hangup",  XYDHUP, 0,
  139.     "init-string", XYDINI, 0,
  140.     "kermit-spoof", XYDKSP, 0,
  141.     "mnp-enable", XYDMNP, 0,
  142. #ifdef MDMHUP
  143.     "modem-hangup", XYDMHU, 0,
  144. #endif /* MDMHUP */
  145.     "prefix", XYDNPR, 0,
  146.     "speed-matching", XYDSPD, 0,
  147.     "timeout", XYDTMO, 0
  148. };
  149. int ndial = (sizeof(dialtab) / sizeof(struct keytab));
  150. #endif /* NODIAL */
  151.  
  152. #ifndef NOXMIT
  153. /* set transmit */
  154. #define XMITF 0
  155. #define XMITL 1
  156. #define XMITP 2
  157. #define XMITE 3
  158. #define XMITX 4
  159. #define XMITS 5
  160. #define XMITW 6
  161.  
  162. #ifndef NOXMIT
  163. #define XMBUFL 50
  164. extern int xmitf, xmitl, xmitp, xmitx, xmits, xmitw;
  165. char xmitbuf[XMBUFL+1] = { NUL };    /* TRANSMIT eof string */
  166. #endif /* NOXMIT */
  167.  
  168. struct keytab xmitab[] = {
  169.     "echo",     XMITX, 0,
  170.     "eof",      XMITE, 0,
  171.     "fill",     XMITF, 0,
  172.     "linefeed", XMITL, 0,
  173.     "locking-shift", XMITS, 0,
  174.     "pause",    XMITW, 0,
  175.     "prompt",   XMITP, 0
  176. };
  177. int nxmit = (sizeof(xmitab) / sizeof(struct keytab));
  178. #endif /* NOXMIT */
  179.  
  180. /* For SET FILE COLLISION */
  181. /* Some of the following may be possible for some C-Kermit implementations */
  182. /* but not others.  Those that are not possible for your implementation */
  183. /* should be ifdef'd out. */
  184.  
  185. struct keytab colxtab[] = { /* SET FILE COLLISION options */
  186.     "append",    XYFX_A, 0,  /* append to old file */
  187. #ifdef COMMENT
  188.     "ask",       XYFX_Q, 0,  /* ask what to do (not implemented) */
  189. #endif
  190.     "backup",    XYFX_B, 0,  /* rename old file */
  191.     "discard",   XYFX_D, 0,  /* don't accept new file */
  192.     "no-supersede", XYFX_D, CM_INV, /* ditto (MSK compatibility) */
  193.     "overwrite", XYFX_X, 0,  /* overwrite the old file == file warning off */
  194.     "rename",    XYFX_R, 0,  /* rename the incoming file == file warning on */
  195.     "update",    XYFX_U, 0,  /* replace if newer */
  196. };
  197. int ncolx = (sizeof(colxtab) / sizeof(struct keytab));
  198.  
  199. static struct keytab rfiltab[] = {    /* for REMOTE SET FILE */
  200.     "collision",     XYFILX, 0,
  201.     "record-length", XYFILR, 0,
  202.     "type",          XYFILT, 0
  203. };
  204. int nrfilp = (sizeof(rfiltab) / sizeof(struct keytab));
  205.  
  206. struct keytab fntab[] = {           /* File naming */
  207.     "converted", 1, 0,
  208.     "literal",   0, 0
  209. };
  210.  
  211. /* Terminal parameters table */
  212. struct keytab trmtab[] = {
  213. #ifdef OS2
  214.     "answerback",    XYTANS, 0,
  215.     "arrow-keys",    XYTARR, 0,
  216. #endif /* OS2 */
  217.     "bytesize",      XYTBYT, 0,
  218. #ifndef NOCSETS
  219.     "character-set", XYTCS,  0,
  220. #endif /* NOCSETS */
  221. #ifdef OS2
  222.     "color",         XYTCOL, 0,
  223. #endif /* OS2 */
  224.     "cr-display",    XYTCRD, 0,
  225. #ifdef OS2
  226.     "cursor",        XYTCUR, 0,
  227. #endif /* OS2 */
  228.     "echo",          XYTEC,  0,
  229. #ifdef OS2
  230.     "keypad-mode",   XYTKPD, 0,
  231. #endif /* OS2 */
  232.     "locking-shift", XYTSO,  0,
  233.     "newline-mode",  XYTNL,  0
  234. #ifdef OS2
  235. ,   "type",          XYTTYP, 0,
  236.     "wrap",          XYTWRP, 0
  237. #endif /* OS2 */
  238. };
  239. int ntrm = (sizeof(trmtab) / sizeof(struct keytab));
  240.  
  241. struct keytab crdtab[] = {        /* Carriage-return display */
  242.     "crlf",        1, 0,
  243.     "normal",      0, 0
  244. };
  245. extern int tt_crd;            /* Carriage-return display variable */
  246.  
  247. #ifdef OS2
  248. /*
  249.   OS/2 serial communication devices.
  250. */
  251. struct keytab os2devtab[] = {
  252.     "1",    1, CM_INV,            /* Invisible synonyms, like */
  253.     "2",    2, CM_INV,            /* "set port 1" */
  254.     "3",    3, CM_INV,
  255.     "4",    4, CM_INV,
  256.     "5",    5, CM_INV,
  257.     "6",    6, CM_INV,
  258.     "7",    7, CM_INV,
  259.     "8",    8, CM_INV,
  260.     "com1", 1, 0,            /* Real device names */
  261.     "com2", 2, 0,
  262.     "com3", 3, 0,
  263.     "com4", 4, 0,
  264.     "com5", 5, 0,
  265.     "com6", 6, 0,
  266.     "com7", 7, 0,
  267.     "com8", 7, 0
  268. };
  269. int nos2dev = (sizeof(os2devtab) / sizeof(struct keytab));
  270.  
  271. /*
  272.   Terminal parameters that can be set by SET commands.
  273.   Used by the ck?con.c terminal emulator code.  
  274.   For now, only use for OS/2.  Should add these for Macintosh.
  275. */
  276. int tt_arrow = 1;            /* Arrow key mode, 1 = Application */
  277. int tt_keypad = 0;            /* Keypad mode, 0 = Application */
  278. int tt_wrap = 1;            /* Autowrap, 1 = On */
  279. int tt_type = TT_VT102;            /* Terminal type, initially VT102 */
  280. int tt_cursor = 0;            /* Cursor type, 0 = Underline */
  281. int tt_answer = 0;            /* Answerback initially disabled */
  282. #endif /* OS2 */
  283.  
  284. #ifdef OS2
  285. struct keytab akmtab[] = {        /* Arrow key mode */
  286.     "application", 1, 0,
  287.     "cursor",      0, 0
  288. };
  289. struct keytab kpmtab[] = {        /* Keypad mode */
  290.     "application", 0, 0,
  291.     "numeric",     1, 0
  292. };
  293.  
  294. struct keytab ttycoltab[] = {        /* Items to be colored */
  295.     "help",        4, 0,        /* Help screen */
  296.     "normal",      0, 0,        /* Normal screen text */
  297.     "reverse",     1, 0,        /* Reverse video */
  298.     "status",      3, 0,        /* Status line */
  299.     "underlined",  2, 0            /* Underlined text */
  300. };
  301. int ncolors = 5;
  302.  
  303. struct keytab ttyclrtab[] = {        /* Colors */
  304.     "black",       0, 0,
  305.     "blue",        1, 0,
  306.     "brown",       6, 0,
  307.     "cyan",        3, 0,
  308.     "dgray",       8, 0,
  309.     "green",       2, 0,
  310.     "lblue",       9, 0,
  311.     "lcyan",      11, 0,
  312.     "lgray",       7, 0,
  313.     "lgreen",     10, 0,
  314.     "lmagenta",   13, 0,
  315.     "lred",       12, 0,
  316.     "magenta",     5, 0,
  317.     "red",         4, 0,
  318.     "white",      15, 0,
  319.     "yellow",     14, 0
  320. };
  321. int nclrs = 16;
  322.  
  323. struct keytab ttycurtab[] = {
  324.     "full",        2, 0,
  325.     "half",        1, 0,
  326.     "underline",   0, 0
  327. };
  328. int ncursors = 3;
  329. #endif /* OS2 */
  330.  
  331. #ifdef OS2
  332. struct keytab ttyptab[] = {
  333. #ifdef COMMENT
  334. /*
  335.   Not supported yet...
  336.   The idea is to let the console driver handle the escape sequences.
  337. */
  338.     "none",    TT_NONE,  0,
  339. #endif /* COMMENT */
  340. #ifdef OS2PM
  341.     "tek4014", TT_TEK40, 0,
  342. #endif /* OS2PM */
  343.     "vt102",   TT_VT102, 0,
  344.     "vt52",    TT_VT52,  0
  345. };
  346. int nttyp = 2;
  347. #endif /* OS2 */
  348.  
  349. /* #ifdef VMS */
  350. struct keytab fbtab[] = {        /* Binary record types for VMS */
  351.     "fixed",     XYFT_B, 0,        /* Fixed is normal for binary */
  352.     "undefined", XYFT_U, 0        /* Undefined if they ask for it */
  353. };
  354. int nfbtyp = (sizeof(fbtab) / sizeof(struct keytab));
  355. /* #endif */
  356.  
  357. #ifdef VMS
  358. struct keytab lbltab[] = {        /* Labeled File info */
  359.     "acl",         LBL_ACL, 0,
  360.     "backup-date", LBL_BCK, 0,
  361.     "name",        LBL_NAM, 0,
  362.     "owner",       LBL_OWN, 0,
  363.     "path",        LBL_PTH, 0
  364. };
  365. int nlblp = (sizeof(lbltab) / sizeof(struct keytab));
  366. #endif /* VMS */
  367.  
  368. struct keytab fdtab[] = {        /* SET FILE DISPLAY options */
  369. #ifdef MAC                /* Macintosh */
  370.     "fullscreen", XYFD_R, 0,        /* Full-screen but not curses */
  371.     "none",   XYFD_N, 0,
  372.     "off",    XYFD_N, CM_INV,
  373.     "on",     XYFD_R, CM_INV,
  374.     "quiet",  XYFD_N, CM_INV
  375.  
  376. #else                    /* Not Mac */
  377.     "crt", XYFD_S, 0,            /* CRT display */
  378. #ifdef CK_CURSES
  379. #ifdef COMMENT
  380.     "curses",     XYFD_C, CM_INV,    /* Full-screen, curses */
  381. #endif /* COMMENT */
  382.     "fullscreen", XYFD_C, 0,        /* Full-screen, whatever the method */
  383. #endif /* CK_CURSES */
  384.     "none",   XYFD_N, 0,        /* No display */
  385.     "off",    XYFD_N, CM_INV,        /* Ditto */
  386.     "on",     XYFD_R, CM_INV,        /* On = Serial */
  387.     "quiet",  XYFD_N, CM_INV,        /* No display */
  388.     "serial", XYFD_R, 0            /* Serial */
  389. #endif /* MAC */
  390. };
  391. int nfdtab = (sizeof(fdtab) / sizeof(struct keytab));
  392.  
  393. struct keytab rsrtab[] = {        /* For REMOTE SET RECEIVE */
  394.     "packet-length", XYLEN, 0,
  395.     "timeout", XYTIMO, 0
  396. };
  397. int nrsrtab = (sizeof(rsrtab) / sizeof(struct keytab));
  398.  
  399. /* Send/Receive Parameters */
  400.  
  401. struct keytab srtab[] = {
  402.     "end-of-packet", XYEOL, 0,
  403.     "packet-length", XYLEN, 0,
  404.     "pad-character", XYPADC, 0,
  405.     "padding", XYNPAD, 0,
  406.     "start-of-packet", XYMARK, 0,
  407.     "timeout", XYTIMO, 0
  408. };
  409. int nsrtab = (sizeof(srtab) / sizeof(struct keytab));
  410.  
  411. /* REMOTE SET */
  412.  
  413. struct keytab rmstab[] = {
  414.     "attributes",  XYATTR, 0,
  415.     "block-check", XYCHKT, 0,
  416.     "file",        XYFILE, 0,
  417.     "incomplete",  XYIFD,  0,
  418.     "receive",     XYRECV, 0,
  419.     "retry",       XYRETR, 0,
  420.     "server",      XYSERV, 0,
  421.     "transfer",    XYXFER, 0,
  422.     "window",      XYWIND, 0
  423. };
  424. int nrms = (sizeof(rmstab) / sizeof(struct keytab));
  425.  
  426. struct keytab attrtab[] = {
  427.     "all",           AT_XALL, 0,
  428. #ifdef COMMENT
  429.     "blocksize",     AT_BLKS, 0,    /* not used */
  430. #endif /* COMMENT */
  431.     "character-set", AT_ENCO, 0,
  432.     "date",          AT_DATE, 0,
  433.     "disposition",   AT_DISP, 0,
  434.     "encoding",      AT_ENCO, CM_INV,
  435.     "length",        AT_LENK, 0,
  436.     "off",           AT_ALLN, 0,
  437.     "on",            AT_ALLY, 0,
  438. #ifdef COMMENT
  439.     "os-specific",   AT_SYSP, 0,    /* not used by UNIX or VMS */
  440. #endif /* COMMENT */
  441.     "system-id",     AT_SYSI, 0,
  442.     "type",          AT_FTYP, 0,
  443. };
  444. int natr = (sizeof(attrtab) / sizeof(struct keytab)); /* how many attributes */
  445.  
  446. #ifndef NOSPL
  447. extern int indef, inecho, insilence;
  448. struct keytab inptab [] = {        /* SET INPUT parameters */
  449.     "case",            IN_CAS, 0,
  450.     "default-timeout", IN_DEF, CM_INV,
  451.     "echo",            IN_ECH, 0,
  452.     "silence",         IN_SIL, 0,
  453.     "timeout-action",  IN_TIM, 0
  454. };
  455. int ninp = (sizeof(inptab) / sizeof(struct keytab));
  456.  
  457. struct keytab intimt[] = {        /* SET INPUT TIMEOUT parameters */
  458.     "proceed", 0, 0,            /* 0 = proceed */
  459.     "quit",    1, 0            /* 1 = quit */
  460. };
  461.  
  462. struct keytab incast[] = {        /* SET INPUT CASE parameters */
  463.     "ignore",  0, 0,            /* 0 = ignore */
  464.     "observe", 1, 0            /* 1 = observe */
  465. };
  466. #endif /* NOSPL */
  467.  
  468. /* The following routines broken out of doprm() to give compilers a break. */
  469.  
  470. /*  S E T O N  --  Parse on/off (default on), set parameter to result  */
  471.  
  472. int
  473. seton(prm) int *prm; {
  474.     int x, y;
  475.     if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
  476.     if ((x = cmcfm()) < 0) return(x);
  477.     *prm = y;
  478.     return(1);
  479. }
  480.  
  481. /*  S E T N U M  --  Set parameter to result of cmnum() parse.  */
  482. /*
  483.  Call with pointer to integer variable to be set,
  484.    x = number from cnum parse, y = return code from cmnum,
  485.    max = maximum value to accept, -1 if no maximum.
  486.  Returns -9 on failure, after printing a message, or 1 on success.
  487. */
  488. int
  489. setnum(prm,x,y,max) int x, y, *prm, max; {
  490.     extern int cmflgs;
  491.     debug(F101,"setnum","",y);
  492.     if (y == -3) {
  493.     printf("\n?Value required\n");
  494.     return(-9);
  495.     }
  496.     if (y == -2) {
  497.     printf("%s?Not a number: %s\n",cmflgs == 1 ? "" : "\n", atxbuf);
  498.     return(-9);
  499.     }
  500.     if (y < 0) return(y);
  501.     if (max > -1 && x > max) {
  502.     printf("?Sorry, %d is the maximum\n",max);
  503.     return(-9);
  504.     }
  505.     if ((y = cmcfm()) < 0) return(y);
  506.     *prm = x;
  507.     return(1);
  508. }
  509.  
  510. /*  S E T C C  --  Set parameter to an ASCII control character value.  */
  511.  
  512. int
  513. setcc(prm,x,y) int x, y, *prm; {
  514.     if (y == -3) {
  515.     printf("\n?Value required\n");
  516.     return(-3);
  517.     }
  518.     if (y < 0) return(y);
  519.     if ((x > 037) && (x != 0177)) {
  520.     printf("\n?Not in ASCII control range - %d\n",x);
  521.     return(-2);
  522.     }
  523.     if ((y = cmcfm()) < 0) return(y);
  524.     *prm = x;
  525.     return(1);
  526. }
  527.  
  528. #ifndef NODIAL
  529. _PROTOTYP(static int dialstr,(char **, char *));
  530. /*
  531.   Parse a DIAL-related string, stripping enclosing braces, if any.
  532. */
  533. static int
  534. dialstr(p,msg) char **p; char *msg; {
  535.     int x;
  536.     if ((x = cmtxt(msg, "", &s, xxstring)) < 0)
  537.       return(x);
  538.     if (*s == '{') {            /* Strip enclosing braces, if any */
  539.     x = strlen(s);
  540.     if (s[x-1] == '}') {
  541.         s[x-1] = NUL;
  542.         s++;
  543.     }
  544.     }
  545.     if (*p) {                /* Free any previous string. */
  546.     free(*p);
  547.     *p = (char *) 0;
  548.     }    
  549.     if ((x = strlen(s)) > 0) {
  550.     *p = malloc(x + 1);        /* Allocate space for it */
  551.     strcpy(*p,s);            /* and make a safe copy. */
  552.     } else *p = (char *) 0;
  553.     return(success = 1);
  554. }
  555.  
  556. int                    /* Set DIAL command options */
  557. setdial() {
  558.     if ((y = cmkey(dialtab,ndial,"","",xxstring)) < 0) return(y);
  559.     switch (y) {
  560.       case XYDHUP:            /* DIAL HANGUP */
  561.     return(success = seton(&dialhng));
  562.       case XYDINI:            /* DIAL INIT-STRING */
  563.     return(dialstr(&dialini,"Modem dialer initialization string"));
  564.       case XYDNPR:            /* DIAL NUMBER-PREFIX */
  565.     return(dialstr(&dialnpr,"Modem dialer telephone number prefix"));
  566.       case XYDDIA:            /* DIAL DIAL-COMMAND */
  567.     x = cmtxt("Dialing command for modem,\n\
  568.  include \"%s\" to stand for phone number,\n\
  569.  for example, \"set dial dial-command ATDT%s\\13\"",
  570.           "",
  571.           &s,
  572.           xxstring);
  573.     if (x < 0 && x != -3)        /* Handle parse errors */
  574.       return(x);
  575.     y = x = strlen(s);        /* Get length of text */
  576.     if (x > 0 && *s == '{') {    /* Strip enclosing braces, */
  577.         if (s[x-1] == '}') {    /* if any. */
  578.         s[x-1] = NUL;
  579.         s++;
  580.         y -= 2;
  581.         }
  582.     }
  583.     if (y > 0) {            /* If there is any text (left), */
  584.         for (x = 0; x < y; x++) {    /* make sure they included "%s" */
  585.         if (s[x] != '%') continue;
  586.         if (s[x+1] == 's') break;
  587.         }
  588.         if (x == y) {
  589.         printf(
  590. "?Dial-command must contain \"%cs\" for phone number.\n",'%');
  591.         return(-9);
  592.         }
  593.     }
  594.     if (dialcmd) {            /* Free any previous string. */
  595.         free(dialcmd);
  596.         dialcmd = (char *) 0;
  597.     }    
  598.     if (y > 0) {
  599.         dialcmd = malloc(y + 1);    /* Allocate space for it */
  600.         strcpy(dialcmd,s);        /* and make a safe copy. */
  601.     }
  602.     return(success = 1);
  603.       case XYDKSP:            /* DIAL KERMIT-SPOOF */
  604.     return(success = seton(&dialksp));
  605.       case XYDTMO:            /* DIAL TIMEOUT */
  606.     y = cmnum("Seconds to wait for call completion","0",10,&x,xxstring);
  607.     return(success = setnum(&dialtmo,x,y,10000));
  608.       case XYDDPY:            /* DIAL DISPLAY */
  609.     return(success = seton(&dialdpy));
  610.       case XYDSPD:            /* DIAL SPEED-MATCHING */
  611.                     /* used to be speed-changing */
  612.     if ((y = seton(&mdmspd)) < 0) return(y);
  613. #ifdef COMMENT
  614.     mdmspd = 1 - mdmspd;        /* so here we reverse the meaning */
  615. #endif /* COMMENT */
  616.     return(success = 1);
  617.       case XYDMNP:            /* DIAL MNP-ENABLE */
  618.     return(success = seton(&dialmnp));
  619. #ifdef MDMHUP
  620.       case XYDMHU:            /* DIAL MODEM-HANGUP */
  621.     return(success = seton(&dialmhu));
  622. #endif /* MDMHUP */
  623.       case XYDDIR:            /* DIAL DIRECTORY */
  624.     if ((y = cmifi("Name of dialing directory file","",&s,&y,
  625.                xxstring)) < 0) {
  626.         if (y == -3) {
  627.         if (dialdir) free(dialdir);    /* Free any previous storage */
  628.         dialdir = NULL;
  629.         return(success = 1);
  630.         } else return(y);
  631.     }
  632.     if (y) {
  633.         printf("?Wildcards not allowed\n");
  634.         return(-9);
  635.     }
  636.     strcpy(line,s);            /* Make safe copy of dial string */
  637.     if ((y = cmcfm()) < 0) return(y); /* Confirm the command */
  638.     if (dialdir) free(dialdir);    /* Free previous filename storage */
  639.     if (dialfd) {            /* Close previous file, if any */
  640.         fclose(dialfd);
  641.         dialfd = NULL;
  642.     }
  643.     s = line;            /* Point back to dial string */
  644.     if (s == NULL || *s == NUL) {    /* If no name given */
  645.         dialdir = NULL;        /* remove the name string */
  646.         return(success = 1);
  647.     } else if ((dialdir = malloc(strlen(s)+1)) == NULL) {
  648.         return(success = 0);    /* Can't malloc storage for name */
  649.     } else {            /* Have storage for name */
  650.         strcpy(dialdir,s);        /* Copy string into new storage */
  651.         if ((dialfd = fopen(dialdir,"r")) == NULL) { /* Open the file */
  652.         perror(dialdir);    /* Can't, print message saying why */
  653.         success = 0;        /* We didn't succeed */
  654.         return(-9);        /* Fail, message already printed */
  655.         }
  656.         return(success = 1);    /* Everything is OK */
  657.     }
  658.  
  659.       default:
  660.     printf("?Unexpected SET DIAL parameter\n");
  661.     return(-2);
  662.     }
  663. }
  664. #endif /* NODIAL */
  665.  
  666. int
  667. setfil(rmsflg) int rmsflg; {
  668.     if (rmsflg) {
  669.     if ((y = cmkey(rfiltab,nrfilp,"Remote file parameter","",
  670.                xxstring)) < 0) {
  671.         if (y == -3) {
  672.         printf("?Remote file parameter required\n");
  673.         return(-9);
  674.         } else return(y);
  675.     }
  676.     } else {
  677.     if ((y = cmkey(filtab,nfilp,"File parameter","",xxstring)) < 0)
  678.       return(y);
  679.     }
  680.     switch (y) {
  681. #ifdef COMMENT                /* Not needed */
  682.       case XYFILB:            /* Blocksize */
  683.     sprintf(tmpbuf,"%d",DBLKSIZ);
  684.     if ((y = cmnum("file block size",tmpbuf,10,&z,xxstring)) < 0)
  685.       return(y);
  686.     if ((x = cmcfm()) < 0) return(x);
  687.     if (rmsflg) {
  688.         sprintf(tmpbuf,"%d",z);
  689.         sstate = setgen('S', "311", tmpbuf, "");
  690.         return((int) sstate);
  691.     } else {
  692.         fblksiz = z;
  693.         return(success = 1);
  694.     }
  695. #endif /* COMMENT */
  696.  
  697.       case XYFILS:            /* Byte size */
  698.     if ((y = cmnum("file byte size (7 or 8)","8",10,&z,xxstring)) < 0)
  699.       return(y);
  700.     if (z != 7 && z != 8) {
  701.         printf("\n?The choices are 7 and 8\n");
  702.         return(0);
  703.     }
  704.     if ((y = cmcfm()) < 0) return(y);
  705.     if (z == 7) fmask = 0177;
  706.     else if (z == 8) fmask = 0377;
  707.     return(success = 1);
  708.  
  709. #ifndef NOCSETS
  710.       case XYFILC:            /* Character set */
  711.     if ((x = cmkey(fcstab,nfilc,"local file code","ascii", xxstring)) < 0)
  712.       return(x);
  713.     if ((z = cmcfm()) < 0) return(z);
  714.     fcharset = x;
  715.     return(success = 1);
  716. #endif /* NOCSETS */
  717.  
  718.       case XYFILD:            /* Display */
  719.     if ((x = cmkey(fdtab,nfdtab,"file transfer display style","",
  720.                xxstring)) < 0)
  721.       return(x);
  722.     if ((z = cmcfm()) < 0) return(z);
  723. #ifdef CK_CURSES
  724.     if (x == XYFD_C) {
  725. #ifdef VMS
  726.         lp = line;
  727. #else
  728.         lp = trmbuf;
  729. #endif /* VMS */
  730. #ifndef MYCURSES
  731.         s = getenv("TERM");
  732.         if (tgetent(lp,s) < 1) {
  733. #ifdef VMS
  734.         printf("Sorry, terminal type not supported: %s\n",s);
  735. #else
  736.         printf("Sorry, terminal type unknown: %s\n",s);
  737. #endif /* VMS */
  738.         return(success = 0);
  739.         }
  740. #endif /* MYCURSES */
  741.         line[0] = '\0';
  742.     }
  743. #endif /* CK_CURSES */
  744.     fdispla = x;            /* It's OK. */
  745.     return(success = 1);
  746.  
  747.       case XYFILN:            /* Names */
  748.     if ((x = cmkey(fntab,2,"how to handle filenames","converted",
  749.                xxstring)) < 0)
  750.       return(x);
  751.     if ((z = cmcfm()) < 0) return(z);
  752.     fncnv = x;
  753.     return(success = 1);
  754.  
  755.       case XYFILR:            /* Record length */
  756.     sprintf(tmpbuf,"%d",DLRECL);
  757.     if ((y = cmnum("file record length",tmpbuf,10,&z,xxstring)) < 0)
  758.       return(y);
  759.     if ((x = cmcfm()) < 0) return(x);
  760.     if (rmsflg) {
  761.         sprintf(tmpbuf,"%d",z);
  762.         sstate = setgen('S', "312", tmpbuf, "");
  763.         return((int) sstate);
  764.     } else {
  765.         frecl = z;
  766.         return(success = 1);
  767.     }
  768.  
  769. #ifdef COMMENT
  770.       case XYFILO:            /* Organization */
  771.     if ((x = cmkey(forgtab,nforg,"file organization","sequential",
  772.                xxstring)) < 0)
  773.       return(x);
  774.     if ((y = cmcfm()) < 0) return(y);
  775.     if (rmsflg) {
  776.         sprintf(tmpbuf,"%d",x);
  777.         sstate = setgen('S', "314", tmpbuf, "");
  778.         return((int) sstate);
  779.     } else {
  780.         forg = x;
  781.         return(success = 1);
  782.     }    
  783. #endif /* COMMENT */
  784.  
  785. #ifdef COMMENT                /* Not needed */
  786.       case XYFILF:            /* Format */
  787.     if ((x = cmkey(frectab,nfrec,"file record format","stream",
  788.                xxstring)) < 0)
  789.       return(x);
  790.     if ((y = cmcfm()) < 0) return(y);
  791.     if (rmsflg) {
  792.         sprintf(tmpbuf,"%d",x);
  793.         sstate = setgen('S', "313", tmpbuf, "");
  794.         return((int) sstate);
  795.     } else {
  796.         frecfm = x;
  797.         return(success = 1);
  798.     }
  799. #endif /* COMMENT */
  800.  
  801. #ifdef COMMENT
  802.       case XYFILP:            /* Printer carriage control */
  803.     if ((x = cmkey(fcctab,nfcc,"file carriage control","newline",
  804.                xxstring)) < 0)
  805.       return(x);
  806.     if ((y = cmcfm()) < 0) return(y);
  807.     if (rmsflg) {
  808.         sprintf(tmpbuf,"%d",x);
  809.         sstate = setgen('S', "315", tmpbuf, "");
  810.         return((int) sstate);
  811.     } else {
  812.         fcctrl = x;
  813.         return(success = 1);
  814.     }    
  815. #endif /* COMMENT */
  816.  
  817.       case XYFILT:            /* Type */
  818.     if ((x = cmkey(fttab,nfttyp,"type of file","text",xxstring)) < 0)
  819.       return(x);
  820. #ifdef COMMENT
  821.     if ((y = cmnum("file byte size (7 or 8)","8",10,&z,xxstring)) < 0)
  822.       return(y);
  823.     if (z != 7 && z != 8) {
  824.         printf("\n?The choices are 7 and 8\n");
  825.         return(0);
  826.     }
  827. #endif /* COMMENT */
  828.  
  829. #ifdef VMS
  830.         /* Allow VMS users to choose record format for binary files */
  831.         if ((x == XYFT_B) && (rmsflg == 0)) {
  832.         if ((x = cmkey(fbtab,nfbtyp,"VMS record format","fixed",
  833.                xxstring)) < 0)
  834.           return(x);
  835.     }
  836. #endif /* VMS */
  837.     if ((y = cmcfm()) < 0) return(y);
  838.     if (rmsflg) {
  839.         sstate = setgen('S', "300", x ? "1" : "0", "");
  840.         return((int) sstate);
  841.     } else {
  842.         binary = x;
  843. #ifdef COMMENT
  844.         if (z == 7) fmask = 0177;
  845.         else if (z == 8) fmask = 0377;
  846. #endif /* COMMENT */
  847.         return(success = 1);
  848.     }
  849.  
  850.       case XYFILX:            /* Collision Action */
  851.     if ((x = cmkey(colxtab,ncolx,"Filename collision action","backup",
  852.                xxstring)) < 0)
  853.       return(x);
  854.     if ((y = cmcfm()) < 0) return(y);
  855.     fncact = x;
  856.     if (rmsflg) {
  857.         sprintf(tmpbuf,"%d",fncact);
  858.         sstate = setgen('S', "302", tmpbuf, "");
  859.         return((int) sstate);
  860.     } else {
  861.         if (fncact == XYFX_R) warn = 1; /* SET FILE WARNING implications */
  862.         if (fncact == XYFX_X) warn = 0; /* ... */
  863.         return(success = 1);
  864.     }
  865.  
  866.       case XYFILW:            /* Warning/Write-Protect */
  867.     seton(&warn);
  868.     if (warn)
  869.       fncact = XYFX_R;
  870.     else
  871.       fncact = XYFX_X;
  872.     return(success = 1);
  873.  
  874. #ifdef VMS
  875.       case XYFILL:            /* LABELED FILE parameters */
  876.     if ((x = cmkey(lbltab,nlblp,"VMS labeled file feature","",
  877.                xxstring)) < 0)
  878.       return(x);
  879.     if ((success = seton(&y)) < 0)
  880.       return(success);
  881.     if (y)                /* Set or reset the selected bit */
  882.       lf_opts |= x;            /* in the options bitmask. */
  883.     else
  884.       lf_opts &= ~x;
  885.     return(success);
  886. #endif /* VMS */
  887.  
  888.       case XYFILI:            /* INCOMPLETE */
  889.     return(doprm(XYIFD,rmsflg));
  890.  
  891.       default:
  892.     printf("?unexpected file parameter\n");
  893.     return(-2);
  894.     }
  895. }
  896.  
  897. int
  898. settrm() {
  899.     if ((y = cmkey(trmtab,ntrm,"","",xxstring)) < 0) return(y);
  900. #ifdef MAC
  901.     printf("\n?Sorry, not implemented yet.  Please use the Settings menu.\n");
  902.     return(-9);
  903. #else
  904.     switch (y) {
  905.       case XYTBYT:            /* SET TERMINAL BYTESIZE */
  906.     if ((y = cmnum("bytesize for terminal connection","8",10,&x,
  907.                xxstring)) < 0)
  908.       return(y);
  909.     if (x != 7 && x != 8) {
  910.         printf("\n?The choices are 7 and 8\n");
  911.         return(success = 0);
  912.     }
  913.     if ((y = cmcfm()) < 0) return(y);
  914.     if (x == 7) cmask = 0177;
  915.     else if (x == 8) cmask = 0377;
  916.         return(success = 1);
  917.  
  918.       case XYTSO:            /* SET TERMINAL LOCKING-SHIFT */
  919.     return(success = seton(&sosi));
  920.  
  921.       case XYTNL:            /* SET TERMINAL NEWLINE-MODE */
  922.     return(success = seton(&tnlm)); 
  923.  
  924. #ifdef OS2
  925.       case XYTCOL:            /* SET TERMINAL COLOR */
  926.     if ((x = cmkey(ttycoltab,ncolors,"","normal",xxstring)) < 0) {
  927.         return(x);
  928.         } else {
  929.         extern int colornormal, colorreverse, colorunderline,
  930.           colorstatus, colorhelp, scrninitialised;
  931.         int fg, bg;
  932.         if ((fg = cmkey(ttyclrtab,nclrs,
  933.                 "foreground color","black",xxstring)) < 0)
  934.           return(fg);
  935.         if ((bg = cmkey(ttyclrtab,nclrs,
  936.                 "background color","cyan",xxstring)) < 0)
  937.           return(bg);
  938.         if ((y = cmcfm()) < 0)
  939.           return(y);
  940.         switch (x) {
  941.           case 0:
  942.         colornormal = fg | bg << 4;
  943.         break;
  944.           case 1:
  945.         colorreverse = fg | bg << 4;
  946.         break;
  947.           case 2:
  948.         colorunderline = fg | bg << 4;
  949.         break;
  950.           case 3:
  951.         colorstatus = fg | bg << 4;
  952.         break;
  953.           case 4:
  954.         colorhelp = fg | bg << 4;
  955.         break;
  956.           default:
  957.         printf("%s - invalid\n",cmdbuf);
  958.         return(-9);
  959.         break;
  960.         }
  961.         scrninitialised = 0;
  962.         }
  963.     return(success = 1);
  964.  
  965.       case XYTCUR:            /* SET TERMINAL CURSOR */
  966.     if ((x = cmkey(ttycurtab,ncursors,"","underline",xxstring)) < 0)
  967.       return(x);
  968.     if ((y = cmcfm()) < 0) return(y);
  969.         tt_cursor = x;
  970.     return(success = 1);
  971.  
  972.       case XYTTYP:            /* SET TERMINAL TYPE */
  973.     if ((x = cmkey(ttyptab,nttyp,"","vt102",xxstring)) < 0) return(x);
  974.     if ((y = cmcfm()) < 0) return(y);
  975.     tt_type = x;
  976.     return(success = 1);
  977.  
  978.       case XYTARR:            /* SET TERMINAL ARROW-KEYS */
  979.     if ((x = cmkey(akmtab,2,"","",xxstring)) < 0) return(x);
  980.     if ((y = cmcfm()) < 0) return(y);
  981.     tt_arrow = x;            /* 0 = application, 1 = cursor */
  982.     return(success = 1);
  983.  
  984.       case XYTKPD:            /* SET TERMINAL KEYPAD-MODE */
  985.     if ((x = cmkey(kpmtab,2,"","",xxstring)) < 0) return(x);
  986.     if ((y = cmcfm()) < 0) return(y);
  987.     tt_keypad = x;            /* 0 = application, 1 = numeric */
  988.     return(success = 1);
  989.  
  990.       case XYTWRP:            /* SET TERMINAL WRAP */
  991.     seton(&tt_wrap);
  992.     return(success = 1);    
  993. #endif /* OS2 */
  994.  
  995. #ifndef NOCSETS
  996.       case XYTCS:            /* SET TERMINAL CHARACTER-SET */
  997.     /* set terminal character-set <remote> <local> */
  998.     if ((x = cmkey(ttcstab,ntermc,
  999.                "remote terminal character-set","",xxstring)) < 0) 
  1000.       return(x);
  1001.     if (x == FC_TRANSP) {        /* TRANSPARENT? */
  1002.         if ((x = cmcfm()) < 0) return(x); /* Confirm the command */
  1003.         tcsr = tcsl = FC_USASCII;    /* Make them both the same */
  1004.         return(success = 1);
  1005.     }
  1006.  
  1007. /* Not transparent, so get local set to translate it into */
  1008.  
  1009.     s = "";                /* Make current file char set */
  1010.     for (y = 0; y <= nfilc; y++)    /* be the default... */
  1011.       if (fcstab[y].kwval == fcharset) {
  1012.           s = fcstab[y].kwd;
  1013.           break;
  1014.         }
  1015.     if ((y = cmkey(fcstab,nfilc,
  1016.                "local character-set",s,xxstring)) < 0)
  1017.       return(y);
  1018.     if ((z = cmcfm()) < 0) return(z); /* Confirm the command */
  1019.     tcsr = x;            /* Remote character set */
  1020.     tcsl = y;            /* Local character set */
  1021.     return(success = 1);
  1022. #endif /* NOCSETS */
  1023.  
  1024.       case XYTEC:            /* SET TERMINAL ECHO */
  1025.     if ((x = cmkey(rltab,nrlt,"which side echos during CONNECT",
  1026.                "remote", xxstring)) < 0) return(x);
  1027.     if ((y = cmcfm()) < 0) return(y);
  1028.     duplex = x;
  1029.     return(success = 1); 
  1030.  
  1031.       case XYTCRD:            /* SET TERMINAL CR-DISPLAY */
  1032.     if ((x = cmkey(crdtab,2,"", "normal", xxstring)) < 0) return(x);
  1033.     if ((y = cmcfm()) < 0) return(y);
  1034.     tt_crd = x;
  1035.     return(success = 1); 
  1036.  
  1037. #ifdef OS2
  1038.       case XYTANS:            /* SET TERMINAL ANSWERBACK */
  1039. /*
  1040.   NOTE: We let them enable and disable the answerback sequence, but we
  1041.   do NOT let them change it, and we definitely do not let the host set it.
  1042.   This is a security feature.
  1043. */
  1044.     seton(&tt_answer);
  1045.     return(success = 1);    
  1046. #endif /* OS2 */
  1047.  
  1048.       default:                /* Shouldn't get here. */
  1049.     return(-2);
  1050.     }    
  1051. #endif /* MAC */
  1052. }
  1053.  
  1054. int                    /* SET SEND/RECEIVE */
  1055. setsr(xx, rmsflg) int xx; int rmsflg; {
  1056.     if (xx == XYRECV)
  1057.         strcpy(line,"Parameter for inbound packets");
  1058.     else
  1059.         strcpy(line,"Parameter for outbound packets");
  1060.  
  1061.     if (rmsflg) {
  1062.     if ((y = cmkey(rsrtab,nrsrtab,line,"",xxstring)) < 0) {
  1063.         if (y == -3) {
  1064.         printf("?Remote receive parameter required\n");
  1065.         return(-9);
  1066.         } else return(y);
  1067.     }
  1068.     } else {
  1069.     if ((y = cmkey(srtab,nsrtab,line,"",xxstring)) < 0) return(y);
  1070.     }
  1071.     switch (y) {
  1072.  
  1073.       case XYEOL:
  1074.     y = cmnum("Decimal ASCII code for packet terminator","13",10,&x,
  1075.           xxstring);
  1076.     if ((y = setcc(&z,x,y)) < 0) return(y);
  1077.     if (xx == XYRECV) eol = z; else seol = z;
  1078.     return(success = y);
  1079.  
  1080.       case XYLEN:
  1081.     y = cmnum("Maximum number of characters in a packet","90",10,&x,
  1082.           xxstring);
  1083.     if (xx == XYRECV) {        /* Receive... */
  1084.         if ((y = setnum(&z,x,y,maxrps)) < 0)
  1085.           return(y);
  1086.         if (z < 10) {
  1087.         printf("Sorry, 10 is the minimum\n");
  1088.         return(-9);
  1089.         }
  1090.         if (rmsflg) {
  1091.         tp = tmpbuf;
  1092.         sprintf(tp,"%d",z);
  1093.         sstate = setgen('S', "401", tp, "");
  1094.         return((int) sstate);
  1095.         } else {
  1096.         if (z > MAXRP) z = MAXRP;
  1097.         y = adjpkl(z,wslotr,bigrbsiz);
  1098.         if (y != z) {
  1099.             urpsiz = y;
  1100.             if (
  1101. #ifndef NOSPL
  1102.             cmdlvl == 0
  1103. #else
  1104.             tlevel < 0
  1105. #endif /* NOSPL */
  1106.             )
  1107.               if (msgflg) printf(
  1108. " Adjusting receive packet-length to %d for %d window slots\n",
  1109.              y, wslotr);
  1110.         }
  1111.         urpsiz = y;
  1112.         rpsiz =  (y > 94) ? 94 : y;
  1113.         }
  1114.     } else {            /* Send... */
  1115.         if ((y = setnum(&z,x,y,maxsps)) < 0)
  1116.           return(y);
  1117.         if (z < 10) {
  1118.         printf("Sorry, 10 is the minimum\n");
  1119.         return(-9);
  1120.         }
  1121.         if (z > MAXSP) z = MAXSP;
  1122.         spsiz = z;            /* Set it */
  1123.         y = adjpkl(spsiz,wslotr,bigsbsiz);
  1124.         if (y != spsiz &&
  1125. #ifndef NOSPL
  1126.         cmdlvl == 0
  1127. #else
  1128.         tlevel < 0
  1129. #endif /* NOSPL */
  1130.         )
  1131.           if (msgflg)
  1132.         printf("Adjusting packet size to %d for %d window slots\n",
  1133.              y,wslotr);
  1134.         spsiz = spmax = spsizr = y;    /* Set it and flag that it was set */
  1135.         spsizf = 1;            /* to allow overriding Send-Init. */
  1136.     }
  1137.     if (pflag &&
  1138. #ifndef NOSPL
  1139.         cmdlvl == 0
  1140. #else
  1141.         tlevel < 0
  1142. #endif /* NOSPL */
  1143.         ) {
  1144.         if (z > 94 && msgflg) {
  1145.         printf("Extended-length packets requested.\n");
  1146.         if (bctr < 2 && z > 200) printf("\
  1147. Remember to SET BLOCK 2 or 3 for long packets.\n");
  1148.         }
  1149.         if (speed <= 0L) speed = ttgspd();
  1150. #ifdef COMMENT
  1151. /*
  1152.   Kermit does this now itself.
  1153. */
  1154.         if (speed <= 0L && z > 200 && msgflg) {
  1155.         printf("\
  1156. Make sure your timeout interval is long enough for %d-byte packets.\n",z);
  1157.         }
  1158. #endif /* COMMENT */
  1159.     }
  1160.     return(success = y);
  1161.  
  1162.       case XYMARK:
  1163.     y = cmnum("Code for packet-start character","1",10,&x,xxstring);
  1164. #ifdef UNIX
  1165. /*
  1166.   Printable start-of-packet works for UNIX and VMS only!
  1167. */
  1168.     if ((y = setnum(&z,x,y,126)) < 0) return(y);
  1169. #else
  1170. #ifdef VMS
  1171.     if ((y = setnum(&z,x,y,126)) < 0) return(y);
  1172. #else
  1173.     if ((y = setcc(&z,x,y)) < 0) return(y);
  1174. #endif /* VMS */
  1175. #endif /* UNIX */
  1176.     if (xx == XYRECV) stchr = z; else mystch = z;
  1177.     return(success = y);
  1178.  
  1179.  
  1180.       case XYNPAD:            /* PADDING */
  1181.     y = cmnum("How many padding characters for inbound packets","0",10,&x,
  1182.           xxstring);
  1183.     if ((y = setnum(&z,x,y,94)) < 0) return(y);
  1184.     if (xx == XYRECV) mypadn = z; else npad = z;
  1185.     return(success = y);
  1186.  
  1187.       case XYPADC:            /* PAD-CHARACTER */
  1188.     y = cmnum("Decimal ASCII code for packet padding character","0",10,&x,
  1189.           xxstring);
  1190.     if ((y = setcc(&z,x,y)) < 0) return(y);
  1191.     if (xx == XYRECV) mypadc = z; else padch = z;
  1192.     return(success = y);
  1193.  
  1194.       case XYTIMO:            /* TIMEOUT */
  1195.     if (xx == XYRECV) {
  1196.         char buf[16];        /* Construct default */
  1197.         sprintf(buf,"%d",URTIME);
  1198.         y = cmnum("Packet timeout interval",buf,10,&x,xxstring);
  1199.         if ((y = setnum(&z,x,y,94)) < 0) return(y);
  1200.  
  1201.         if (rmsflg) {        /* REMOTE SET RECEIVE TIMEOUT */
  1202.         tp = tmpbuf;        /*   Tell Kermit server what */
  1203.         sprintf(tp,"%d",z);    /*   timeout to ask me to use. */
  1204.         sstate = setgen('S', "402", tp, "");
  1205.         return((int) sstate);
  1206.         } else {            /* SET RECEIVE TIMEOUT */
  1207.         pkttim = z;        /*   Value to put in my negotiation */
  1208.         }                /*   packet for other Kermit to use */
  1209.  
  1210.     } else {            /* SET SEND TIMEOUT */
  1211.         y = cmnum("Packet timeout interval","",10,&x,xxstring);
  1212.         if (y == -3) {        /* They cancelled a previous */
  1213.         x = DMYTIM;        /* SET SEND command, so restore */
  1214.         y = 0;            /* the default */
  1215.         timef = 0;        /* and turn off the override flag */
  1216.         } else {            /* They gave a number */
  1217.         timef = 1;        /* so turn on the override flag */
  1218.         }
  1219.         if ((y = setnum(&z,x,y,94)) < 0)
  1220.           return(y);
  1221.         timint = rtimo = z;        /* Override value for me to use */
  1222.     }
  1223.     return(success = 1);
  1224.  
  1225.       default:
  1226.     return(-2);
  1227.     }                    /* End of SET SEND/RECEIVE... */
  1228. }
  1229.  
  1230. #ifndef NOXMIT
  1231. int
  1232. setxmit() {
  1233.     if ((y = cmkey(xmitab,nxmit,"","",xxstring)) < 0) return(y);
  1234.     switch (y) {
  1235.       case XMITE:            /* EOF */
  1236.     y = cmtxt("Characters to send at end of file,\n\
  1237.  Use backslash codes for control characters","",&s,xxstring);
  1238.     if (y < 0) return(y);
  1239.     if ((int)strlen(s) > XMBUFL) {
  1240.         printf("?Too many characters, %d maximum\n",XMBUFL);
  1241.         return(-2);
  1242.     }
  1243.     strcpy(xmitbuf,s);
  1244.     return(success = 1);
  1245.  
  1246.       case XMITF:            /* Fill */
  1247.     y = cmnum("Numeric code for blank-line fill character","0",10,&x,
  1248.           xxstring);
  1249.     if ((y = setnum(&z,x,y,127)) < 0) return(y);
  1250.     xmitf = z;
  1251.     return(success = 1);
  1252.       case XMITL:            /* Linefeed */
  1253.         return(success = seton(&xmitl));
  1254.       case XMITS:            /* Locking-Shift */
  1255.         return(success = seton(&xmits));
  1256.       case XMITP:            /* Prompt */
  1257.     y = cmnum("Numeric code for host's prompt character, 0 for none",
  1258.           "10",10,&x,xxstring);
  1259.     if ((y = setnum(&z,x,y,127)) < 0) return(y);
  1260.     xmitp = z;
  1261.     return(success = 1);
  1262.       case XMITX:            /* Echo */
  1263.         return(success = seton(&xmitx));
  1264.       case XMITW:            /* Pause */
  1265.     y = cmnum("Number of milliseconds to pause between binary characters\n\
  1266. or text lines during transmission","0",10,&x,xxstring);
  1267.     if ((y = setnum(&z,x,y,1000)) < 0) return(y);
  1268.     xmitw = z;
  1269.     return(success = 1);
  1270.       default:
  1271.     return(-2);
  1272.     }
  1273. }
  1274. #endif /* NOXMIT */
  1275.  
  1276. /*  D O R M T  --  Do a remote command  */
  1277.  
  1278. #ifdef ATTSV
  1279. #ifndef aegis
  1280. #ifndef datageneral
  1281. #define CK_NEED_SIG
  1282. #endif /* datageneral */
  1283. #endif /* aegis */
  1284. #endif /* ATTSV */
  1285.  
  1286. VOID rmsg() {
  1287.     if (pflag)
  1288.       printf(
  1289. #ifdef CK_NEEDSIG
  1290.  
  1291.        " Type your escape character, %s, followed by X or E to cancel.\n",
  1292.        dbchr(escape)
  1293. #else
  1294.        " Press the X or E key to cancel.\n"
  1295. #endif /* CK_NEEDSIG */
  1296.       );
  1297. }
  1298.  
  1299. int
  1300. dormt(xx) int xx; {
  1301.     int x, y, retcode;
  1302.     char *s, sbuf[50], *s2;
  1303.  
  1304.  
  1305.     if (xx < 0) return(xx);
  1306.  
  1307.     if (xx == XZSET) {            /* REMOTE SET */
  1308.     if ((y = cmkey(rmstab,nrms,"","",xxstring)) < 0) {
  1309.         if (y == -3) {
  1310.         printf("?Parameter name required\n");
  1311.         return(-9);
  1312.         } else return(y);
  1313.     }
  1314.     return(doprm(y,1));
  1315.     }
  1316.  
  1317.     switch (xx) {            /* Others... */
  1318.  
  1319. case XZCWD:                /* CWD */
  1320.     if ((x = cmtxt("Remote directory name","",&s,xxstring)) < 0) return(x);
  1321.     debug(F111,"XZCWD: ",s,x);
  1322.     *sbuf = NUL;
  1323.     s2 = sbuf;
  1324.  
  1325. /* The following is commented out, because there is practically no */
  1326. /* computer in the world that requires a password for directory changing. */
  1327. /* (The DEC-20 was the only one, and they're mostly all gone.) */
  1328. #ifdef DIRPWDPR
  1329.     if (*s != NUL) {            /* If directory name given, */
  1330.                     /* get password on separate line. */
  1331.         if (tlevel > -1) {        /* From take file... */
  1332.  
  1333.         if (fgets(sbuf,50,tfile[tlevel]) == NULL)
  1334.             fatal("take file ends prematurely in 'remote cwd'");
  1335.         debug(F110," pswd from take file",s2,0);
  1336.         for (x = (int)strlen(sbuf);
  1337.               x > 0 && (sbuf[x-1] == NL || sbuf[x-1] == CR);
  1338.          x--)
  1339.         sbuf[x-1] = '\0';
  1340.  
  1341.         } else {            /* From terminal... */
  1342.  
  1343.         printf(" Password: ");         /* get a password */
  1344. #ifdef OS2
  1345.         while (((x = isatty(0) ? coninc(0) :
  1346.              getchar()) != NL) && (x != CR)) {     /* with no echo */
  1347. #else
  1348.         while (((x = getchar()) != NL) && (x != CR)) { /* with no echo */
  1349. #endif /* OS2 */
  1350.             if ((x &= 0177) == '?') {
  1351.                 printf("? Password of remote directory\n Password: ");
  1352.             s2 = sbuf;
  1353.             *sbuf = NUL;
  1354.             }
  1355.             else if (x == ESC)    /* Mini command line editor... */
  1356.                 putchar(BEL);
  1357.         else if (x == BS || x == 0177)
  1358.             s2--;
  1359.         else if (x == 025) {    /* Ctrl-U */
  1360.             s2 = sbuf;
  1361.             *sbuf = NUL;
  1362.         }
  1363.             else
  1364.             *s2++ = x;
  1365.             }
  1366.         *s2 = NUL;
  1367.         putchar('\n');
  1368.         }
  1369.         s2 = sbuf;
  1370.     } else s2 = "";
  1371. #endif /* DIRPWDPR */
  1372.  
  1373.     debug(F110," password",s2,0);
  1374.     sstate = setgen('C',s,s2,"");
  1375.     retcode = 0;
  1376.     break;
  1377.  
  1378. case XZDEL:                /* Delete */
  1379.     if ((x = cmtxt("Name of remote file(s) to delete","",&s,xxstring)) < 0) {
  1380.     if (x == -3) {
  1381.         printf("?Name of remote file(s) required\n");
  1382.         return(-9);
  1383.     } else return(x);
  1384.     }
  1385.     if (local) ttflui();        /* If local, flush tty input buffer */
  1386.     retcode = sstate = rfilop(s,'E');
  1387.     break;
  1388.  
  1389. case XZDIR:                /* Directory */
  1390.     if ((x = cmtxt("Remote directory or file specification","",&s,
  1391.            xxstring)) < 0)
  1392.         return(x);
  1393.     if (local) ttflui();        /* If local, flush tty input buffer */
  1394.     rmsg();
  1395.     retcode = sstate = setgen('D',s,"","");
  1396.     break;
  1397.  
  1398. case XZHLP:                /* Help */
  1399.     if ((x = cmcfm()) < 0) return(x);
  1400.     sstate = setgen('H',"","","");
  1401.     retcode = 0;
  1402.     break; 
  1403.  
  1404. #ifndef NOPUSH
  1405. case XZHOS:                /* Host */
  1406.     if ((x = cmtxt("Command for remote system","",&cmarg,xxstring)) < 0)
  1407.       return(x);
  1408.     if ((int)strlen(cmarg) < 1)  {
  1409.     if (x == -3) {
  1410.         printf("?Remote host command required\n");
  1411.         return(-9);
  1412.     } else return(x);
  1413.     }
  1414.     rmsg();
  1415.     retcode = sstate = 'c';
  1416.     break; 
  1417. #endif /* NOPUSH */
  1418.  
  1419. #ifndef NOFRILLS
  1420. case XZKER:
  1421.     if ((x = cmtxt("Command for remote Kermit","",&cmarg,xxstring)) < 0)
  1422.       return(x);
  1423.     if ((int)strlen(cmarg) < 1)  {
  1424.     if (x == -3) {
  1425.         printf("?Remote Kermit command required\n");
  1426.         return(-9);
  1427.     } else return(x);
  1428.     }
  1429.     retcode = sstate = 'k';
  1430.     rmsg();
  1431.     break; 
  1432.  
  1433. case XZLGI: {                /* Login */
  1434.     char *p1, *p2, *p3;
  1435.     if ((x = cmfld("User ID","",&s,xxstring)) < 0) return(x);
  1436.     if ((p1 = malloc((int)strlen(s) + 1)) == NULL) {
  1437.     printf("Internal error: malloc\n");
  1438.     return(-2);
  1439.     } else strcpy(p1,s);
  1440.     if ((x = cmfld("Password","",&s,xxstring)) < 0) return(x);
  1441.     if ((p2 = malloc((int)strlen(s) + 1)) == NULL) {
  1442.     printf("Internal error: malloc\n");
  1443.     return(-2);
  1444.     } else strcpy(p2,s);
  1445.     if ((x = cmtxt("Account or carriage return","",
  1446.            &s,xxstring)) < 0 && x != -3)
  1447.     return(x);
  1448.     if ((p3 = malloc((int)strlen(s) + 1)) == NULL) {
  1449.     printf("Internal error: malloc\n");
  1450.     return(-2);
  1451.     } else strcpy(p3,s);
  1452.     sstate = setgen('I',p1,p2,p3);
  1453.     if (p3) free(p3);
  1454.     if (p2) free(p2);
  1455.     if (p1) free(p1);
  1456.     retcode = 0;
  1457.     break; 
  1458. }
  1459.  
  1460. case XZLGO:                /* Logout */
  1461.     if ((x = cmcfm()) < 0) return(x);
  1462.     sstate = setgen('I',"","","");
  1463.     retcode = 0;
  1464.     break; 
  1465.  
  1466. case XZPRI:                /* Print */
  1467.     if (!atdiso || !atcapr) {        /* Disposition attribute off? */
  1468.     printf("?Disposition Attribute is Off\n");
  1469.     return(-2);
  1470.     }
  1471.     cmarg = "";
  1472.     cmarg2 = "";
  1473.     if ((x = cmifi("Local file(s) to print on remote printer","",&s,&y,
  1474.            xxstring)) < 0) {
  1475.     if (x == -3) {
  1476.         printf("?Name of local file(s) required\n");
  1477.         return(-9);
  1478.     }
  1479.     return(x);
  1480.     }
  1481.     strcpy(line,s);            /* Make a safe copy of filename */
  1482.     *optbuf = NUL;            /* Wipe out any old options */
  1483.     if ((x = cmtxt("Options for remote print command","",&s,xxstring)) < 0)
  1484.       return(x);
  1485.     strcpy(optbuf,s);            /* Make a safe copy of options */
  1486.     if ((int)strlen(optbuf) > 94) {    /* Make sure this is legal */
  1487.     printf("?Option string too long\n");
  1488.     return(-9);
  1489.     }
  1490.     nfils = -1;                /* Expand file list internally */
  1491.     cmarg = line;            /* Point to file list. */
  1492.     rprintf = 1;            /* REMOTE PRINT modifier for SEND */
  1493.     sstate = 's';            /* Set start state to SEND */
  1494.     if (local) displa = 1;
  1495.     retcode = 0;
  1496.     break;
  1497. #endif /* NOFRILLS */
  1498.     
  1499. case XZSPA:                /* Space */
  1500.     if ((x = cmtxt("Confirm, or remote directory name","",&s,xxstring)) < 0)
  1501.       return(x);
  1502.     retcode = sstate = setgen('U',s,"","");
  1503.     break;
  1504.     
  1505. #ifndef NOFRILLS
  1506. case XZTYP:                /* Type */
  1507.     if ((x = cmtxt("Remote file specification","",&s,xxstring)) < 0)
  1508.       return(x);
  1509.     if ((int)strlen(s) < 1) {
  1510.     printf("?Remote filename required\n");
  1511.         return(-9);    
  1512.     }
  1513.     rmsg();
  1514.     retcode = sstate = rfilop(s,'T');
  1515.     break;
  1516. #endif /* NOFRILLS */
  1517.  
  1518. #ifndef NOFRILLS
  1519. case XZWHO:
  1520.     if ((x = cmtxt("Remote user name, or carriage return","",&s,xxstring)) < 0)
  1521.         return(x);
  1522.     retcode = sstate = setgen('W',s,"","");
  1523.     break;
  1524. #endif /* NOFRILLS */
  1525.  
  1526. default:
  1527.         if ((x = cmcfm()) < 0) return(x);
  1528.         printf("?Not implemented - %s\n",cmdbuf);
  1529.         return(-2);
  1530.     }
  1531.     if (local) ttflui();        /* If local, flush tty input buffer */
  1532.     return(retcode);
  1533. }
  1534.  
  1535.  
  1536. /*  R F I L O P  --  Remote File Operation  */
  1537.  
  1538. CHAR
  1539. #ifdef CK_ANSIC
  1540. rfilop(char * s, char t)
  1541. #else
  1542. rfilop(s,t) char *s, t; 
  1543. #endif /* CK_ANSIC */
  1544. /* rfilop */ {
  1545.     if (*s == NUL) {
  1546.     printf("?File specification required\n");
  1547.     return((CHAR) 0);
  1548.     }
  1549.     debug(F111,"rfilop",s,t);
  1550.     return(setgen(t,s,"",""));
  1551. }
  1552.  
  1553. #ifdef SUNX25
  1554. int
  1555. setx25() {
  1556.     if ((y = cmkey(x25tab,nx25,"X.25 call options","",xxstring)) < 0)
  1557.       return(y);
  1558.     switch (y) {
  1559.       case XYUDAT:
  1560.     if ((z = cmkey(onoff,2,"X.25 call user data","",xxstring))
  1561.         < 0) return(z);
  1562.     if (z == 0) {
  1563.         if ((z = cmcfm()) < 0) return(z);
  1564.         cudata = 0;             /* disable call user data */
  1565.         return (success = 1);
  1566.     }
  1567.     if ((x = cmtxt("X.25 call user data string","",&s,xxstring)) < 0)
  1568.       return(x);
  1569.     if ((int)strlen(s) == 0) {
  1570.         return (-3);
  1571.     } else if ((int)strlen(s) > MAXCUDATA) {
  1572.         printf("?The length must be > 0 and <= %d\n",MAXCUDATA);
  1573.         return(-2);
  1574.     }
  1575.     if ((y = cmcfm()) < 0) return(y);
  1576.     strcpy(udata,s);
  1577.     cudata = 1;            /* X.25 call user data specified */
  1578.     return (success = 1);
  1579.       case XYCLOS:
  1580.     if ((z = cmkey(onoff,2,"X.25 closed user group call","",xxstring))
  1581.         < 0) return(z);
  1582.     if (z == 0) {
  1583.         if ((z = cmcfm()) < 0) return(z);
  1584.         closgr = -1;        /* disable closed user group */
  1585.         return (success = 1);
  1586.     }
  1587.     if ((y = cmnum("0 <= cug index >= 99","",10,&x,xxstring)) < 0)
  1588.       return(y);
  1589.     if (x < 0 || x > 99) {
  1590.         printf("?The choices are 0 <= cug index >= 99\n");
  1591.         return(-2);
  1592.     }
  1593.     if ((y = cmcfm()) < 0) return(y);
  1594.     closgr = x;            /* closed user group selected */
  1595.     return (success = 1);
  1596.  
  1597.       case XYREVC:
  1598.     if((z = cmkey(onoff,2,"X.25 reverse charge call","",xxstring)) < 0)
  1599.       return(z);
  1600.     if ((x = cmcfm()) < 0) return(x);
  1601.     revcall = z;
  1602.     return (success = 1);
  1603.     }
  1604. }
  1605.  
  1606. int
  1607. setpadp() {
  1608.     if ((y = cmkey(padx3tab,npadx3,"PAD X.3 parameter name","",xxstring)) < 0)
  1609.       return(y);
  1610.     x = y;
  1611.     switch (x) {
  1612.       case PAD_BREAK_CHARACTER:
  1613.     if ((y = cmnum("PAD break character value","",10,&z,xxstring)) < 0)
  1614.       return(y);
  1615.     if ((y = cmcfm()) < 0) return(y);
  1616.     break;
  1617.       case PAD_ESCAPE:
  1618.     if ((y = cmnum("PAD escape","",10,&z,xxstring)) < 0) return(y);
  1619.     if (z != 0 && z != 1) {
  1620.         printf("?The choices are 0 or 1\n");
  1621.         return(-2);
  1622.     }
  1623.     if ((y = cmcfm()) < 0) return(y);
  1624.     break;
  1625.       case PAD_ECHO:
  1626.      if ((y = cmnum("PAD echo","",10,&z,xxstring)) < 0) return(y);
  1627.     if (z != 0 && z != 1) {
  1628.         printf("?The choices are 0 or 1\n");
  1629.         return(-2);
  1630.     }
  1631.     if ((y = cmcfm()) < 0) return(y);
  1632.     break;
  1633.       case PAD_DATA_FORWARD_CHAR:
  1634.      if ((y = cmnum("PAD data forward char","",10,&z,xxstring)) < 0)
  1635.       return(y);
  1636.     if (z != 0 && z != 2) {
  1637.         printf("?The choices are 0 or 2\n");
  1638.         return(-2);
  1639.     }
  1640.     if ((y = cmcfm()) < 0) return(y);
  1641.     break;
  1642.       case PAD_DATA_FORWARD_TIMEOUT:
  1643.      if ((y = cmnum("PAD data forward timeout","",10,&z,xxstring)) < 0)
  1644.         return(y);
  1645.     if (z < 0 || z > 255) {
  1646.         printf("?The choices are 0 or 1 <= timeout <= 255\n");
  1647.         return(-2);
  1648.     }
  1649.     if ((y = cmcfm()) < 0) return(y);
  1650.     break;
  1651.       case PAD_FLOW_CONTROL_BY_PAD:
  1652.      if ((y = cmnum("PAD pad flow control","",10,&z,xxstring)) < 0)
  1653.       return(y);
  1654.     if (z != 0 && z != 1) {
  1655.         printf("?The choices are 0 or 1\n");
  1656.         return(-2);
  1657.     }
  1658.     if ((y = cmcfm()) < 0) return(y);
  1659.     break;
  1660.       case PAD_SUPPRESSION_OF_SIGNALS:
  1661.      if ((y = cmnum("PAD service","",10,&z,xxstring)) < 0) return(y);
  1662.     if (z != 0 && z != 1) {
  1663.         printf("?The choices are 0 or 1\n");
  1664.         return(-2);
  1665.     }
  1666.     if ((y = cmcfm()) < 0) return(y);
  1667.     break;
  1668.  
  1669.       case PAD_BREAK_ACTION:
  1670.      if ((y = cmnum("PAD break action","",10,&z,xxstring)) < 0) return(y);
  1671.     if (z != 0 && z != 1 && z != 2 && z != 5 && z != 8 && z != 21) {
  1672.         printf("?The choices are 0, 1, 2, 5, 8 or 21\n");
  1673.         return(-2);
  1674.     }
  1675.     if ((y = cmcfm()) < 0) return(y);
  1676.     break;
  1677.  
  1678.       case PAD_SUPPRESSION_OF_DATA:
  1679.      if ((y = cmnum("PAD data delivery","",10,&z,xxstring)) < 0) return(y);
  1680.     if (z != 0 && z != 1) {
  1681.         printf("?The choices are 0 or 1\n");
  1682.         return(-2);
  1683.     }
  1684.     if ((y = cmcfm()) < 0) return(y);
  1685.     break;
  1686.  
  1687.       case PAD_PADDING_AFTER_CR:
  1688.      if ((y = cmnum("PAD crpad","",10,&z,xxstring)) < 0) return(y);
  1689.     if (z < 0 || z > 7) {
  1690.         printf("?The choices are 0 or 1 <= crpad <= 7\n");
  1691.         return(-2);
  1692.     }
  1693.     if ((y = cmcfm()) < 0) return(y);
  1694.     break;
  1695.  
  1696.       case PAD_LINE_FOLDING:
  1697.      if ((y = cmnum("PAD linefold","",10,&z,xxstring)) < 0) return(y);
  1698.     if (z < 0 || z > 255) {
  1699.         printf("?The choices are 0 or 1 <= linefold <= 255\n");
  1700.         return(-2);
  1701.     }
  1702.     if ((y = cmcfm()) < 0) return(y);
  1703.     break;
  1704.  
  1705.       case PAD_LINE_SPEED:
  1706.      if ((y = cmnum("PAD baudrate","",10,&z,xxstring)) < 0) return(y);
  1707.     if (z < 0 || z > 18) {
  1708.         printf("?The choices are 0 <= baudrate <= 18\n");
  1709.         return(-2);
  1710.     }
  1711.     if ((y = cmcfm()) < 0) return(y);
  1712.     break;
  1713.  
  1714.       case PAD_FLOW_CONTROL_BY_USER:
  1715.      if ((y = cmnum("PAD terminal flow control","",10,&z,xxstring)) < 0)
  1716.         return(y);
  1717.     if (z != 0 && z != 1) {
  1718.         printf("?The choices are 0 or 1\n");
  1719.         return(-2);
  1720.     }
  1721.     if ((y = cmcfm()) < 0) return(y);
  1722.     break;
  1723.  
  1724.       case PAD_LF_AFTER_CR:
  1725.      if ((y = cmnum("PAD crpad","",10,&z,xxstring)) < 0) return(y);
  1726.     if (z < 0 || z == 3 || z > 7) {
  1727.         printf("?The choices are 0, 1, 2, 4, 5, 6 or 7\n");
  1728.         return(-2);
  1729.     }
  1730.     if ((y = cmcfm()) < 0) return(y);
  1731.     break;
  1732.  
  1733.       case PAD_PADDING_AFTER_LF:
  1734.      if ((y = cmnum("PAD lfpad","",10,&z,xxstring)) < 0) return(y);
  1735.     if (z < 0 || z > 7) {
  1736.         printf("?The choices are 0 or 1 <= lfpad <= 7\n");
  1737.         return(-2);
  1738.     }
  1739.     if ((y = cmcfm()) < 0) return(y);
  1740.     break;
  1741.  
  1742.       case PAD_EDITING:
  1743.      if ((y = cmnum("PAD edit control","",10,&z,xxstring)) < 0) return(y);
  1744.     if (z != 0 && z != 1) {
  1745.         printf("?The choices are 0 or 1\n");
  1746.         return(-2);
  1747.     }
  1748.     if ((y = cmcfm()) < 0) return(y);
  1749.     break;
  1750.  
  1751.       case PAD_CHAR_DELETE_CHAR:
  1752.      if ((y = cmnum("PAD char delete char","",10,&z,xxstring)) < 0)
  1753.         return(y);
  1754.     if (z < 0 || z > 127) {
  1755.         printf("?The choices are 0 or 1 <= chardelete <= 127\n");
  1756.         return(-2);
  1757.     }
  1758.     if ((y = cmcfm()) < 0) return(y);
  1759.     break;
  1760.  
  1761.       case PAD_BUFFER_DELETE_CHAR:
  1762.      if ((y = cmnum("PAD buffer delete char","",10,&z,xxstring)) < 0)
  1763.         return(y);
  1764.     if (z < 0 || z > 127) {
  1765.         printf("?The choices are 0 or 1 <= bufferdelte <= 127\n");
  1766.         return(-2);
  1767.     }
  1768.     if ((y = cmcfm()) < 0) return(y);
  1769.     break;
  1770.  
  1771.       case PAD_BUFFER_DISPLAY_CHAR:
  1772.      if ((y = cmnum("PAD display line char","",10,&z,xxstring)) < 0)
  1773.         return(y);
  1774.     if (z < 0 || z > 127) {
  1775.         printf("?The choices are 0 or 1 <= displayline <= 127\n");
  1776.         return(-2);
  1777.     }
  1778.     if ((y = cmcfm()) < 0) return(y);
  1779.     break;
  1780.     }
  1781.     padparms[x] = z;
  1782.     return(success = 1);
  1783. }
  1784. #endif /* SUNX25 */ 
  1785.  
  1786. int
  1787. setat(rmsflg) int rmsflg; {
  1788.     int xx;
  1789.     if ((y = cmkey(attrtab,natr,"File Attribute packets","",xxstring)) < 0)
  1790.       return(y);    
  1791.     if (y == AT_XALL) {            /* ATTRIBUTES ALL ON or ALL OFF */
  1792.     if ((z = seton(&xx)) < 0) return(z);
  1793.     if (rmsflg) {
  1794.         printf("Sorry, command not available\n");
  1795.         return(-9);
  1796.     } else {
  1797.         atenci = xx;        /* Encoding in */
  1798.         atenco = xx;        /* Encoding out */
  1799.         atdati = xx;        /* Date in */
  1800.         atdato = xx;        /* Date out */
  1801.         atdisi = xx;        /* Disposition in/out */
  1802.         atdiso = xx;
  1803.         atleni = xx;        /* Length in/out (both kinds) */
  1804.         atleno = xx;
  1805.         atblki = xx;        /* Blocksize in/out */
  1806.         atblko = xx;
  1807.         attypi = xx;        /* File type in/out */
  1808.         attypo = xx;
  1809.         atsidi = xx;        /* System ID in/out */
  1810.         atsido = xx;
  1811.         atsysi = xx;        /* System-dependent params in/out */
  1812.         atsyso = xx;
  1813.     }
  1814.     return(z);
  1815.     } else if (y == AT_ALLY || y == AT_ALLN) { /* ATTRIBUTES ON or OFF */
  1816.     if ((x = cmcfm()) < 0) return(x);
  1817.     atcapr = (y == AT_ALLY) ? 1 : 0;
  1818.     if (rmsflg) {
  1819.         sstate = setgen('S', "132", atcapr ? "1" : "0", "");
  1820.         return((int) sstate);
  1821.     } else return(success = 1);
  1822.     }
  1823.     /* Otherwise, it's an individual attribute that wants turning off/on */
  1824.  
  1825.     if ((z = cmkey(onoff,2,"","",xxstring)) < 0) return(z);
  1826.     if ((x = cmcfm()) < 0) return(x);
  1827.  
  1828. /* There are better ways to do this... */
  1829. /* The real problem is that we're not separating the in and out cases */
  1830. /* and so we have to arbitrarily pick the "in" case, i.e tell the remote */
  1831. /* server to ignore incoming attributes of the specified type, rather */
  1832. /* than telling it not to send them.  The protocol does not (yet) define */
  1833. /* codes for "in-and-out-at-the-same-time". */
  1834.  
  1835.     switch(y) {
  1836.       case AT_DISP:
  1837.     if (rmsflg) {
  1838.         sstate = setgen('S', "142", z ? "1" : "0", "");
  1839.         return((int) sstate);
  1840.     }
  1841.     atdisi = atdiso = z; break;
  1842.       case AT_ENCO:
  1843.     if (rmsflg) {
  1844.         sstate = setgen('S', "141", z ? "1" : "0", "");
  1845.         return((int) sstate);
  1846.     }
  1847.     atenci = atenco = z; break;
  1848.       case AT_DATE:
  1849.     if (rmsflg) {
  1850.         sstate = setgen('S', "135", z ? "1" : "0", "");
  1851.         return((int) sstate);
  1852.     }
  1853.     atdati = atdato = z; break;
  1854.       case AT_LENB:
  1855.       case AT_LENK:
  1856.     if (rmsflg) {
  1857.         sstate = setgen('S', "133", z ? "1" : "0", "");
  1858.         return((int) sstate);
  1859.     }
  1860.     atleni = atleno = z; break;
  1861.       case AT_BLKS:
  1862.     if (rmsflg) {
  1863.         sstate = setgen('S', "139", z ? "1" : "0", "");
  1864.         return((int) sstate);
  1865.     }
  1866.     atblki = atblko = z; break;
  1867.       case AT_FTYP:
  1868.     if (rmsflg) {
  1869.         sstate = setgen('S', "134", z ? "1" : "0", "");
  1870.         return((int) sstate);
  1871.     }
  1872.     attypi = attypo = z; break;
  1873.       case AT_SYSI:
  1874.     if (rmsflg) {
  1875.         sstate = setgen('S', "145", z ? "1" : "0", "");
  1876.         return((int) sstate);
  1877.     }
  1878.     atsidi = atsido = z; break;
  1879.       case AT_SYSP:
  1880.     if (rmsflg) {
  1881.         sstate = setgen('S', "147", z ? "1" : "0", "");
  1882.         return((int) sstate);
  1883.     }
  1884.     atsysi = atsyso = z; break;
  1885.       default:
  1886.     printf("?Not available\n");
  1887.     return(-2);
  1888.     }
  1889.     return(1);
  1890. }
  1891.  
  1892. #ifndef NOSPL
  1893. int
  1894. setinp() {
  1895.     if ((y = cmkey(inptab,ninp,"","",xxstring)) < 0) return(y);
  1896.     switch (y) {
  1897.       case IN_DEF:            /* SET INPUT DEFAULT-TIMEOUT */
  1898.     z = cmnum("Positive number","",10,&x,xxstring);
  1899.     return(success = setnum(&indef,x,z,94));
  1900.       case IN_TIM:            /* SET INPUT TIMEOUT-ACTION */
  1901.     if ((z = cmkey(intimt,2,"","",xxstring)) < 0) return(z);
  1902.     if ((x = cmcfm()) < 0) return(x);
  1903.     intime[cmdlvl] = z;
  1904.     return(success = 1);
  1905.       case IN_CAS:            /* SET INPUT CASE */
  1906.     if ((z = cmkey(incast,2,"","",xxstring)) < 0) return(z);
  1907.     if ((x = cmcfm()) < 0) return(x);
  1908.     incase[cmdlvl] = z;
  1909.     return(success = 1);
  1910.       case IN_ECH:            /* SET INPUT ECHO */
  1911.     return(success = seton(&inecho));
  1912.       case IN_SIL:            /* SET INPUT SILENCE */
  1913.     z = cmnum("Positive number","",10,&x,xxstring);
  1914.     return(success = setnum(&insilence,x,z,-1));
  1915.     }
  1916.     return(0);
  1917. }
  1918. #endif /* NOSPL */
  1919.  
  1920. /*
  1921.   setlin -- parse name of and then open a communication device.
  1922.   Call with:
  1923.     xx == XXLINE for a serial (tty) line, XXHOST for a network host,
  1924.     zz == 0 means if user doesn't give a device name, continue current
  1925.             active connection (if any);
  1926.     zz != 0 means if user doesn't give a device name, then close the
  1927.             current connection and restore the default communication device.
  1928. */
  1929. int
  1930. setlin(xx, zz) int xx, zz; {
  1931.     if (xx == XYHOST) {            /* SET HOST <hostname> */
  1932. #ifndef NETCONN
  1933.         printf("?Network connections not supported\n");
  1934.     return(-9);
  1935. #else
  1936.     if (
  1937.         (nettype != NET_DEC) &&
  1938.         (nettype != NET_SX25) &&
  1939.             (nettype != NET_TCPB)) {
  1940.         printf("?Network type not supported\n");
  1941.         return(-9);
  1942.       }
  1943.     if (nettype != NET_TCPB) {    /* Not a TCP/IP connection */
  1944.                     /* Just get a text string */
  1945.         if ((x = cmtxt( zz ? 
  1946.    "Network host name,\n or carriage return to close an open connection" :
  1947.    "Network host name,\n or carriage return to resume an open connection",
  1948.                "",&s,xxstring)) < 0)
  1949.           return(x);
  1950.  
  1951.     } else {            /* TCP/IP connection... */
  1952.  
  1953.         /* Parse for host and service separately. */
  1954.  
  1955.         if ((x = cmfld( zz ?
  1956.    "IP host name or number,\n or carriage return to close an open connection" :
  1957.    "IP host name or number,\n or carriage return to resume an open connection",
  1958.                "",&s,xxstring)) < 0) {
  1959.         if (x != -3)        /* Parse error */
  1960.           return(x);        /* return it */
  1961.         else if (!zz)        /* No hostname given */
  1962.           return(1);        /* and none required, */
  1963.         }                /* continue current connection. */
  1964.         if (*s) {            /* If they gave a host name... */
  1965.         strcpy(line,s);        /* make a copy */
  1966.         /* Check for "host:service" */
  1967.         for ( ; (*s != '\0') && (*s != ':'); s++) ;
  1968.  
  1969.         /* If no service given, let them type one now. */
  1970.  
  1971.         if (!*s) {
  1972.             if ((x = cmfld(
  1973.     "TCP service name or number,\n or carriage return for telnet (23)",
  1974.                    "23",&s,xxstring)) < 0 && x != -3)
  1975.               return(x);
  1976.             if (*s) {        /* If they gave a service, */
  1977.             strcat(line,":"); /* concatenate it to the hostname */
  1978.             strcat(line,s);    /* separated by a colon, because */
  1979.             }            /* this is how ttopen() wants it. */
  1980.         }
  1981.         if ((x = cmcfm()) < 0) return(x); /* Confirm the command */
  1982.         s = line;
  1983.         }
  1984.     }
  1985.  
  1986.     /* New connection wanted. */
  1987.  
  1988.     ttflui();            /* Clear away buffered up junk */
  1989.     ttclos(0);            /* Close old connection, if any */
  1990.     if (oldplex > -1)        /* Restore duplex setting. */
  1991.       duplex = oldplex;
  1992.     if (*s) {            /* They gave a hostname */
  1993.         x = 1;            /* Network connection always local */
  1994.         mdmsav = mdmtyp;        /* Remember old modem type */
  1995.         mdmtyp = -nettype;        /* Special code for network */
  1996.         if (nettype == NET_TCPB) {    /* For TCP/IP telnet connections */
  1997.         oldplex = duplex;    /* Remember previous duplex */
  1998.         duplex = 0;        /* Set full duplex and let */
  1999.       }                /* negotiations change if necessary. */
  2000.     } else {            /* They just said "set host" */
  2001.         if (network && msgflg)
  2002.           printf(" Closing connection\n");
  2003.         s = dftty;            /* So go back to normal */
  2004.         x = dfloc;            /* default tty, location, */
  2005.         network = 0;        /* No more network connection. */
  2006.         duplex = oldplex;        /* Restore old duplex setting. */
  2007.         if (mdmtyp < 0) {        /* Switching from net to async? */
  2008.         if (mdmsav > -1)    /* Restore modem type from last */
  2009.           mdmtyp = mdmsav;    /* SET MODEM command, if any. */
  2010.         else
  2011.           mdmtyp = 0;
  2012.         }
  2013.     }
  2014. #endif /* NETCONN */
  2015.     }
  2016.  
  2017. /* Serial tty device, possibly modem, connection... */
  2018.  
  2019.     if (xx == XYLINE) {            /* SET LINE */
  2020. #ifdef OS2                /* or SET PORT */
  2021. /*
  2022.   User can type:
  2023.     COM1..COM8 = Regular COM port
  2024.     1..8       = Synonym for COM1..COM8, is translated to COM1..COM8
  2025.     _n         = (n is a number) = open file handle
  2026.     string     = any text string = name of some other kind of device,
  2027.                  taken literally, as given.
  2028. */
  2029.     if ((x = cmtxt("Communication device name",dftty,&s,xxstring)) < 0)
  2030.       return(x);
  2031.     debug(F110,"OS2 SET PORT s",s,0);
  2032.     y = lookup(os2devtab,s,nos2dev,&x); /* Look up in keyword table */
  2033.     debug(F101,"OS2 SET PORT x","",x);
  2034.     debug(F101,"OS2 SET PORT y","",y);
  2035.     if ((y > -1) && (x >= 0 && x < 8)) { /* User typed a digit 1..8 */
  2036.         s = os2devtab[x+8].kwd;    /* Substitite its real name */
  2037.         debug(F110,"OS2 SET PORT subst s",s,"");
  2038.     } else if (*s == '_') {        /* User used "_" prefix */
  2039.         s++;            /* Remove it */
  2040.         debug(F110,"OS2 SET PORT _subst s",s,0); /* Rest must be numeric */
  2041.         if (!rdigits(s)) {
  2042.         printf("?Invalid format for file handle\n");
  2043.         return(-9);
  2044.         }
  2045.     }
  2046.     debug(F110,"OS2 SET PORT final s",s,"");
  2047. #else
  2048.     if ((x = cmtxt("Communication device name",dftty,&s,xxstring)) < 0)
  2049.       return(x);
  2050. #endif /* OS2 */
  2051.  
  2052.     if (local) ttflui();        /* Clear away buffered up junk */
  2053.     ttclos(0);            /* Close old line, if any was open */
  2054.     if (*s) {            /* They gave a device name */
  2055.         x = -1;            /* Let ttopen decide about it */
  2056.     } else {            /* They just said "set line" */
  2057.         s = dftty;            /* so go back to normal tty */
  2058.         x = dfloc;            /* and mode. */
  2059.     }
  2060.     if (mdmtyp < 0) {        /* Switching from net to async? */
  2061.         if (mdmsav > -1)        /* Restore modem type from last */
  2062.           mdmtyp = mdmsav;        /* SET MODEM command, if any. */
  2063.         else
  2064.           mdmtyp = 0;
  2065.         mdmsav = -1;
  2066.     }
  2067.     if (oldplex > -1) {        /* Restore previous duplex setting. */
  2068.         duplex = oldplex;
  2069.         oldplex = -1;
  2070.     }
  2071.     network = 0;            /* No more network. */
  2072.     }
  2073. #ifdef COMMENT
  2074. /*
  2075.   The following is removed, not so much because it's a horrible hack, but
  2076.   because it only works if the SET FLOW command was given *before* the SET
  2077.   LINE command, whereas normally these commands can be given in any order.
  2078. */
  2079. #ifdef NEXT
  2080. /*
  2081.   This is a horrible hack, but it's nice for users.  On the NeXT, you select
  2082.   RTS/CTS hardware flow control not by system calls, but by referring to the
  2083.   device with a different name.  If the user has asked for RTS/CTS flow
  2084.   control on a NeXT, but used the non-RTS/CTS device name in the SET LINE
  2085.   command, we make the appropriate substitute here.  I wonder how much bigger
  2086.   this section of code will grow as the years go by... 
  2087. */
  2088.     if ((flow == FLO_RTSC) &&        /* RTS/CTS flow control selected */
  2089.     strcmp(s,dftty)) {        /*  ...on external port? */
  2090.     y = strlen(s);            /* Yes, insert "f" as next-to-last */
  2091.     if (s[y-2] != 'f') {        /* character in device name if not */
  2092.         strcpy(line,s);        /* already there... */
  2093.         line[y] = line[y-1];    /* So /dev/cua => /dev/cufa, etc. */
  2094.         line[y-1] = 'f';
  2095.         line[y+1] = '\0';
  2096.         s = line;
  2097.     }
  2098.     }
  2099. #endif /* NEXT */
  2100. #endif /* COMMENT */
  2101.  
  2102.     if ((y = ttopen(s,&x,mdmtyp,cdtimo)) < 0 ) { /* Open the new line */
  2103.     if (y == -2) {
  2104.         printf("?Timed out, no carrier.\n");
  2105.         printf("Try SET CARRIER OFF and SET LINE again, or else\n");
  2106.         printf("SET MODEM, SET LINE, and then DIAL.\n");
  2107.     } else if (y == -3) {
  2108.         printf("Sorry, access to lock denied: %s\n",s);
  2109.     } else if (y == -4) {
  2110.         printf("Sorry, access to device denied: %s\n",s);
  2111.     } else if (y == -5) {
  2112. #ifdef VMS
  2113.         printf("Sorry, device is in use or otherwise unavailable: %s\n",s);
  2114. #else
  2115.         printf("Sorry, device is in use: %s\n",s);
  2116. #endif /* VMS */
  2117.         } else {            /* Other error. */
  2118. #ifndef VMS
  2119.         if (errno) {
  2120.         tp = tmpbuf;
  2121.         sprintf(tp,"Sorry, can't open connection: %s",s);
  2122.         perror(tp);
  2123.         } else
  2124. #endif /* VMS */
  2125.           printf("Sorry, can't open connection: %s\n",s);
  2126.     }    
  2127.     local = dfloc;            /* Go back to normal */
  2128. #ifndef MAC
  2129.     strcpy(ttname,dftty);        /* Restore default tty name */
  2130. #endif /* MAC */
  2131.     speed = ttgspd();
  2132.     network = 0;            /* No network connection active */
  2133.     return(success = 0);        /* Return failure */
  2134.     }
  2135.     if (x > -1) local = x;        /* Opened ok, set local/remote. */
  2136.     network = (mdmtyp < 0);        /* Remember connection type. */
  2137. #ifdef TNCODE
  2138.     if (network) tn_init = 0;        /* Say telnet not init'd yet. */
  2139. #endif /* TNCODE */
  2140.     strcpy(ttname,s);            /* Copy name into real place. */
  2141.     speed = ttgspd();            /* Get the current speed. */
  2142.     debug(F111,"set line ",ttname,local);
  2143. #ifdef NETCONN
  2144. #ifdef SUNX25
  2145.     if (nettype == NET_SX25) duplex = 1; /* Duplex half */
  2146. #endif /* SUNX25 */
  2147. #endif /* NETCONN */
  2148.     return(success = 1);
  2149. }
  2150. #endif /* NOICP */
  2151.