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

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