home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / cku196.zip / ckuus3.c < prev    next >
C/C++ Source or Header  |  2000-01-02  |  246KB  |  8,870 lines

  1. #include "ckcsym.h"            /* Symbol definitions */
  2. #ifndef NOICP
  3.  
  4. /*  C K U U S 3 --  "User Interface" for C-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, 2000,
  11.     Trustees of Columbia University in the City of New York.
  12.     All rights reserved.  See the C-Kermit COPYING.TXT file or the
  13.     copyright text in the ckcmai.c module for disclaimer and permissions.
  14. */
  15.  
  16. /*  SET command (but much material has been split off into ckuus7.c). */
  17.  
  18. /*
  19.   Kermit-specific includes.
  20.   Definitions here supersede those from system include files.
  21. */
  22. #include "ckcdeb.h"            /* Debugging & compiler things */
  23. #include "ckcasc.h"            /* ASCII character symbols */
  24. #include "ckcker.h"            /* Kermit application definitions */
  25. #include "ckcxla.h"            /* Character set translation */
  26. #include "ckcnet.h"            /* Network symbols */
  27. #ifdef CK_AUTHENTICATION
  28. #include "ckuath.h"
  29. #endif /* CK_AUTHENTICATION */
  30. #ifdef CK_SSL
  31. #include "ck_ssl.h"
  32. #endif /* CK_SSL */
  33. #include "ckuusr.h"            /* User interface symbols */
  34. #ifdef OS2
  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 tt_modechg;
  52. #ifdef NT
  53. #include <windows.h>
  54. #include <tapi.h>
  55. #include "ckntap.h"            /* Microsoft TAPI */
  56. #endif /* NT */
  57. #endif /* OS2 */
  58.  
  59. #ifdef CK_RECALL
  60. extern int cm_retry;
  61. #endif /* CK_RECALL */
  62.  
  63. extern int cmdint;
  64. extern int srvidl;
  65.  
  66. #ifndef NOPUSH
  67. #ifndef NOFRILLS
  68. #ifdef VMS
  69. char editor[CKMAXPATH + 1] = "edit";
  70. #else
  71. char editor[CKMAXPATH + 1] = { NUL, NUL };
  72. #endif /* VMS */
  73. char editopts[128] = { NUL, NUL };
  74. char editfile[CKMAXPATH + 1] = { NUL, NUL };
  75. #ifdef BROWSER
  76. char browser[CKMAXPATH + 1] = { NUL, NUL };
  77. char browsopts[128] = { NUL, NUL };
  78. char browsurl[4096] = { NUL, NUL };
  79. #endif /* BROWSER */
  80. #endif /*  NOFRILLS */
  81. #endif /* NOPUSH */
  82.  
  83. /* Variables */
  84.  
  85. int cmd_quoting = 1;
  86. extern int hints;
  87.  
  88. #ifdef CK_KERBEROS
  89. char * k4pwprompt = NULL;        /* Kerberos 4 password prompt */
  90. char * k4prprompt = NULL;        /* Kerberos 4 principal prompt */
  91. char * k5pwprompt = NULL;        /* Kerberos 5 password prompt */
  92. char * k5prprompt = NULL;        /* Kerberos 5 principal prompt */
  93. #endif /* CK_KERBEROS */
  94. #ifdef CK_SRP
  95. char * srppwprompt = NULL;
  96. #endif /* CK_SRP */
  97.  
  98. extern char * ckprompt, * ikprompt;    /* Default prompt */
  99. extern xx_strp xxstring;
  100.  
  101. extern char * cdmsgfile[], * cdmsgstr;
  102.  
  103. extern int
  104.   local, server, success, dest, sleepcan, inserver, flow, autoflow, binary,
  105.   parity, escape, what, turn, duplex, backgrd, hwparity, stopbits, turnch,
  106.   mdmtyp, network, quiet, nettype, carrier, debses, debtim, cdtimo, nlangs,
  107.   bgset, pflag, msgflg, cmdmsk, suspend, techo, pacing, xitwarn, xitsta,
  108.   outesc, cmd_cols, cmd_rows, ckxech, xaskmore, haveline, didsetlin, isguest;
  109. #ifndef NOSERVER
  110.   extern int en_pri;
  111. #endif /* NOSERVER */
  112.  
  113. #ifdef IKSDCONF
  114. extern int iksdcf;
  115. #endif /* IKSDCONF */
  116. #ifdef TCPSOCKET
  117.   extern int tn_exit;
  118. #endif /* TCPSOCKET */
  119. #ifdef TNCODE
  120.   char * tn_pr_uid = NULL;
  121. #endif /* TNCODE */
  122.   extern int exitonclose;
  123.  
  124. #ifndef NOKVERBS
  125. extern int nkverbs;
  126. extern struct keytab kverbs[];
  127. #endif /* NOKVERBS */
  128.  
  129. extern int ttnproto;            /* Network protocol */
  130.  
  131. extern char *ccntab[];            /* Names of control chars */
  132.  
  133. #ifdef CK_APC
  134. extern int apcactive, apcstatus;
  135. #endif /* CK_APC */
  136.  
  137. #ifndef NOSCRIPT
  138. extern int secho;            /* Whether SCRIPT cmd should echo */
  139. #endif /* NOSCRIPT */
  140.  
  141. #ifdef DCMDBUF
  142. extern char *atmbuf, *atxbuf;
  143. #else
  144. extern char atmbuf[], atxbuf[];
  145. #endif /* DCMDBUF */
  146. extern int cmflgs;
  147.  
  148. extern char psave[];
  149. extern char uidbuf[];
  150. extern int  sl_uid_saved;
  151. int DeleteStartupFile = 0;
  152.  
  153. extern int cmdlvl;            /* Overall command level */
  154.  
  155. #ifndef NOSPL
  156. _PROTOTYP( static int parsdir, (int) );
  157. char pwbuf[PWBUFL+1]  = { NUL, NUL };
  158. int pwflg = 0;
  159. int pwcrypt = 0;
  160. char prmbuf[PWBUFL+1] = { NUL, NUL };
  161. int fndiags = 1;            /* Function diagnostics on/off */
  162. int fnerror = 1;            /* Function error treatment */
  163.  
  164. #ifdef DCMDBUF
  165. extern int *count, *takerr, *merror, *inpcas;
  166. #else
  167. extern int count[], takerr[], merror[], inpcas[];
  168. #endif /* DCMDBUF */
  169. extern int mecho;            /* Macro echo */
  170. extern long ck_alarm;
  171. extern char alrm_date[], alrm_time[];
  172. #else
  173. extern int takerr[];
  174. #endif /* NOSPL */
  175.  
  176. extern int x_ifnum;
  177. extern int bigsbsiz, bigrbsiz;        /* Packet buffers */
  178.  
  179. extern long speed;            /* Terminal speed */
  180.  
  181. extern char ttname[];            /* Communication device name */
  182. extern char myhost[] ;
  183. extern char inidir[];            /* Ini File directory */
  184.  
  185. #ifndef NOSETKEY
  186. extern KEY *keymap;            /* Character map for SET KEY (1:1)  */
  187. extern MACRO *macrotab;            /* Macro map for SET KEY (1:string) */
  188. #ifdef OS2
  189. int wideresult;                /* For SET KEY, wide OS/2 scan codes */
  190. extern int tt_scrsize[];        /* Scrollback buffer Sizes */
  191. #endif /* OS2 */
  192. #endif /* NOSETKEY */
  193.  
  194. /* Printer settings */
  195.  
  196. extern char * printername;        /* NULL if printer not redirected */
  197. extern int printpipe;
  198. extern int noprinter;
  199. #ifdef PRINTSWI
  200. int printtimo = 0;
  201. char * printterm = NULL;
  202. char * printsep = NULL;
  203. int printertype = 0;
  204. #ifdef BPRINT
  205. int printbidi = 0;            /* SET BPRINTER (bidirectional) */
  206. long pportspeed = 0L;            /* Bidirection printer port speed, */
  207. int pportparity = 0;            /*  parity, */
  208. int pportflow = FLO_KEEP;        /*  and flow control */
  209. #endif /* BPRINT */
  210. #ifdef OS2
  211. extern int txt2ps;                      /* Text2PS conversion? */
  212. extern int ps_width, ps_length;         /* Text2PS dimensions */
  213. #endif /* OS2 */
  214. #endif /* PRINTSWI */
  215.  
  216. #ifdef OS2
  217. extern int tcp_avail;            /* Nonzero if TCP/IP is available */
  218. #ifdef DECNET
  219. extern int dnet_avail;            /* Ditto for DECnet */
  220. #endif /* DECNET */
  221. #ifdef SUPERLAT
  222. extern int slat_avail;
  223. #endif /* SUPERLAT */
  224. #endif /* OS2 */
  225.  
  226. static struct keytab logintab[] = {
  227.     "password", LOGI_PSW, CM_INV,
  228.     "prompt",   LOGI_PRM, CM_INV,
  229.     "userid",   LOGI_UID, 0
  230. };
  231.  
  232. #ifndef NOCSETS
  233. /* system-independent character sets, defined in ckcxla.[ch] */
  234. extern struct csinfo tcsinfo[];
  235. extern struct langinfo langs[];
  236.  
  237. /* Other character-set related variables */
  238. extern int tcharset, tslevel, language;
  239. #endif /* NOCSETS */
  240.  
  241. /* File-transfer variable declarations */
  242.  
  243. #ifndef NOXFER
  244. #ifdef CK_AUTODL
  245. extern int cmdadl;
  246. #endif /* CK_AUTODL */
  247.  
  248. #ifndef NOSERVER
  249. extern int ngetpath;
  250. extern char * getpath[];
  251. #endif /* NOSERVER */
  252.  
  253. #ifdef PATTERNS
  254. extern int patterns;
  255. #endif /* PATTERNS */
  256.  
  257. extern struct ck_p ptab[];
  258.  
  259. extern CHAR sstate;            /* Protocol start state */
  260. extern CHAR myctlq;            /* Control-character prefix */
  261. extern CHAR myrptq;            /* Repeat-count prefix */
  262.  
  263. extern int protocol, size, spsiz, spmax, urpsiz, srvtim, srvcdmsg, slostart,
  264.   srvdis, xfermode, ckdelay, keep, maxtry, unkcs, bctr, ebqflg, swcapr,
  265.   wslotr, lscapr, lscapu, spsizr, rptena, rptmin, docrc, xfrcan, xfrchr,
  266.   xfrnum, xfrbel, xfrint, srvping, g_xfermode;
  267.  
  268. #ifdef PIPESEND
  269. extern int usepipes;
  270. #endif /* PIPESEND */
  271.  
  272. #ifdef CKXXCHAR                /* DOUBLE / IGNORE char table */
  273. extern int dblflag, ignflag, dblchar;
  274. extern short dblt[];
  275. #endif /* CKXXCHAR */
  276.  
  277. #ifdef CK_SPEED
  278. extern short ctlp[];            /* Control-prefix table */
  279. extern int prefixing;
  280. static struct keytab pfxtab[] = {
  281.     "all",         PX_ALL, 0,
  282.     "cautious",    PX_CAU, 0,
  283.     "minimal",     PX_WIL, 0,
  284.     "none",        PX_NON, CM_INV
  285. };
  286. #endif /* CK_SPEED */
  287. #endif /* NOXFER */
  288.  
  289. /* Declarations from cmd package */
  290.  
  291. #ifdef DCMDBUF
  292. extern char *cmdbuf;            /* Command buffer */
  293. extern char *line;
  294. extern char *tmpbuf;
  295. #else
  296. extern char cmdbuf[];            /* Command buffer */
  297. extern char line[];            /* Character buffer for anything */
  298. extern char tmpbuf[];
  299. #endif /* DCMDBUF */
  300.  
  301. /* From main ckuser module... */
  302.  
  303. extern char *tp, *lp;            /* Temporary buffer */
  304.  
  305. extern int tlevel;            /* Take Command file level */
  306.  
  307. #ifndef NOLOCAL
  308. #ifdef OS2ORUNIX
  309. extern int sessft;            /* Session-log file type */
  310. #else
  311. #ifdef OSK
  312. extern int sessft;
  313. #endif /* OSK */
  314. #endif /* UNIX */
  315. #endif /* NOLOCAL */
  316.  
  317. char * tempdir = NULL;
  318.  
  319. #ifdef VMS
  320. int vms_msgs = 1;            /* SET MESSAGES */
  321. extern int batch;
  322. #endif /* VMS */
  323.  
  324. /* Keyword tables for SET commands */
  325.  
  326. #ifdef CK_SPEED
  327. struct keytab ctltab[] = {
  328.     "prefixed",   1, 0,            /* Note, the values are important. */
  329.     "unprefixed", 0, 0
  330. };
  331. #endif /* CK_SPEED */
  332.  
  333. static struct keytab oldnew[] = {
  334.     "new", 0, 0,
  335.     "old", 1, 0
  336. };
  337.  
  338. #ifndef NOSPL
  339. static struct keytab functab[] = {
  340.     "diagnostics", FUNC_DI, 0,
  341.     "error",       FUNC_ER, 0
  342. };
  343. static int nfunctab = (sizeof(functab) / sizeof(struct keytab));
  344.  
  345. struct keytab outptab[] = {        /* SET OUTPUT parameters */
  346.     "pacing", 0, 0,            /* only one so far... */
  347.     "special-escapes", 1, 0
  348. };
  349. int noutptab = (sizeof(outptab) / sizeof(struct keytab)); /* How many */
  350. #endif /* NOSPL */
  351.  
  352. struct keytab chktab[] = {        /* Block check types */
  353.     "1", 1, 0,                /* 1 =  6-bit checksum */
  354.     "2", 2, 0,                /* 2 = 12-bit checksum */
  355.     "3", 3, 0,                /* 3 = 16-bit CRC */
  356.     "4", 4, CM_INV,            /* Same as B */
  357.     "blank-free-2", 4, 0        /* B = 12-bit checksum, no blanks */
  358. };
  359.  
  360. struct keytab rpttab[] = {        /* SET REPEAT */
  361.     "counts",    0, 0,            /* On or Off */
  362. #ifdef COMMENT
  363.     "minimum",   1, 0,            /* Threshhold */
  364. #endif /* COMMENT */
  365.     "prefix",    2, 0            /* Repeat-prefix character value */
  366. };
  367.  
  368. #ifndef NOLOCAL
  369. /* For SET [ MODEM ] CARRIER, and also for SET DIAL CONNECT */
  370.  
  371. struct keytab crrtab[] = {
  372.     "automatic", CAR_AUT, 0,        /* 2 */
  373.     "off",       CAR_OFF, 0,        /* 0 */
  374.     "on",        CAR_ON,  0        /* 1 */
  375. };
  376. int ncrr = 3;
  377. #endif /* NOLOCAL */
  378.  
  379. struct keytab ooatab[] = {        /* On/Off/Auto table */
  380.     "automatic", SET_AUTO, 0,        /* 2 */
  381.     "off",       SET_OFF,  0,        /* 0 */
  382.     "on",        SET_ON,   0        /* 1 */
  383. };
  384.  
  385. struct keytab qvtab[] = {        /* Quiet/Verbose table */
  386.     "quiet", 1, 0,
  387.     "verbose", 0, 0
  388. };
  389. int nqvt = 2;
  390.  
  391. /* For SET DEBUG */
  392.  
  393. struct keytab dbgtab[] = {
  394.     "off",        0,  0,
  395.     "on",         1,  0,
  396.     "session",    2,  0,
  397.     "timestamps", 3,  0
  398. };
  399. int ndbg = 4;
  400.  
  401. #ifndef NOLOCAL
  402. /* Transmission speeds */
  403.  
  404. #ifdef TTSPDLIST /* Speed table constructed at runtime . . . */
  405.  
  406. struct keytab * spdtab = NULL;
  407. int nspd = 0;
  408.  
  409. #else
  410. /*
  411.   Note, the values are encoded in cps rather than bps because 19200 and higher
  412.   are too big for some ints.  All but 75bps are multiples of ten.  Result of
  413.   lookup in this table must be multiplied by 10 to get actual speed in bps.
  414.   If this number is 70, it must be changed to 75.  If it is 888, this means
  415.   75/1200 split speed.
  416.  
  417.   The values are generic, rather than specific to UNIX.  We can't use B75,
  418.   B1200, B9600, etc, because non-UNIX versions of C-Kermit will not
  419.   necessarily have these symbols defined.  The BPS_xxx symbols are
  420.   Kermit-specific, and are defined in ckcdeb.h or on the CC command line.
  421.  
  422.   Like all other keytabs, this one must be in "alphabetical" order,
  423.   rather than numeric order.
  424. */
  425. struct keytab spdtab[] = {
  426.     "0",      0,  CM_INV,
  427.     "110",   11,  0,
  428. #ifdef BPS_115K
  429.  "115200",11520,  0,
  430. #endif /* BPS_115K */
  431.   "1200",   120,  0,
  432. #ifdef BPS_134
  433.   "134.5",  134,  0,
  434. #endif /* BPS_134 */
  435. #ifdef BPS_14K
  436.   "14400", 1440,  0,
  437. #endif /* BPS_14K */
  438. #ifdef BPS_150
  439.   "150",     15,  0,
  440. #endif /* BPS_150 */
  441. #ifdef BPS_1800
  442.   "1800",     180,  0,
  443. #endif /* BPS_150 */
  444. #ifdef BPS_19K
  445.   "19200", 1920,  0,
  446. #endif /* BPS_19K */
  447. #ifdef BPS_200
  448.   "200",     20,  0,
  449. #endif /* BPS_200 */
  450. #ifdef BPS_230K
  451.   "230400", 23040, 0,
  452. #endif /* BPS_230K */
  453.   "2400",   240,  0,
  454. #ifdef BPS_28K
  455.   "28800", 2880,  0,
  456. #endif /* BPS_28K */
  457.   "300",     30,  0,
  458. #ifdef BPS_3600
  459.   "3600",   360,  0,
  460. #endif /* BPS_3600 */
  461. #ifdef BPS_38K
  462.   "38400", 3840,  0,
  463. #endif /* BPS_38K */
  464. #ifdef BPS_460K
  465.   "460800", 46080,  0,            /* Need 32 bits for this... */
  466. #endif /* BPS_460K */
  467.   "4800",   480,  0,
  468. #ifdef BPS_50
  469.   "50",       5,  0,
  470. #endif /* BPS_50 */
  471. #ifdef BPS_57K
  472.   "57600", 5760,  0,
  473. #endif /* BPS_57K */
  474.   "600",     60,  0,
  475. #ifdef BPS_7200
  476.   "7200",   720,  0,
  477. #endif /* BPS_7200 */
  478. #ifdef BPS_75
  479.   "75",       7,  0,
  480. #endif /* BPS_75 */
  481. #ifdef BPS_7512
  482.   "75/1200",888,  0,            /* Code "888" for split speed */
  483. #endif /* BPS_7512 */
  484. #ifdef BPS_76K
  485.   "76800", 7680,  0,
  486. #endif /* BPS_76K */
  487. #ifdef BPS_921K
  488.   "921600", 92160,0,            /* Need 32 bits for this... */
  489. #endif /* BPS_921K */
  490.   "9600",   960,  0
  491. };
  492. int nspd = (sizeof(spdtab) / sizeof(struct keytab)); /* How many speeds */
  493. #endif /* TTSPDLIST */
  494.  
  495. #endif /* NOLOCAL */
  496.  
  497. #ifndef NOCSETS
  498. extern struct keytab lngtab[];        /* Languages for SET LANGUAGE */
  499. extern int nlng;
  500. #endif /* NOCSETS */
  501.  
  502. #ifndef NOLOCAL
  503. /* Duplex keyword table */
  504.  
  505. struct keytab dpxtab[] = {
  506.     "full",      0, 0,
  507.     "half",      1, 0
  508. };
  509. #endif /* NOLOCAL */
  510.  
  511. /* Flow Control */
  512.  
  513. struct keytab cxtypesw[] = {
  514. #ifdef DECNET
  515.     "/decnet",         CXT_DECNET,  0,
  516. #endif /* DECNET */
  517.     "/direct-serial",  CXT_DIRECT,  0,
  518. #ifdef DECNET
  519.     "/lat",            CXT_LAT,     0,
  520. #else
  521. #ifdef SUPERLAT
  522.     "/lat",            CXT_LAT,     0,
  523. #endif /* SUPERLAT */
  524. #endif /* DECNET */
  525.     "/modem",          CXT_MODEM,   0,
  526. #ifdef NPIPE
  527.     "/named-pipe",     CXT_NPIPE,   0,
  528. #endif /* NPIPE */
  529. #ifdef NETBIOS
  530.     "/netbios",        CXT_NETBIOS, 0,
  531. #endif /* NETBIOS */
  532.     "/remote",         CXT_REMOTE,  0,
  533. #ifdef SSH
  534.     "/ssh",            CXT_SSH,     0,
  535. #endif /* SSH */
  536. #ifdef TCPSOCKET
  537.     "/tcpip",          CXT_TCPIP,   0,
  538. #endif /* TCPSOCKET */
  539. #ifdef ANYX25
  540.     "/x.25",           CXT_X25,     0,
  541. #endif /* ANYX25 */
  542.     "", 0, 0
  543. };
  544. int ncxtypesw = (sizeof(cxtypesw) / sizeof(struct keytab));
  545.  
  546. struct keytab flotab[] = {        /* SET FLOW-CONTROL keyword table */
  547.     "automatic", FLO_AUTO, CM_INV,    /* Not needed any more */
  548. #ifdef CK_DTRCD
  549.     "dtr/cd",    FLO_DTRC, 0,
  550. #endif /* CK_DTRCD */
  551. #ifdef CK_DTRCTS
  552.     "dtr/cts",   FLO_DTRT, 0,
  553. #endif /* CK_DTRCTS */
  554.     "keep",      FLO_KEEP, 0,
  555.     "none",      FLO_NONE, 0,
  556. #ifdef CK_RTSCTS
  557.     "rts/cts",   FLO_RTSC, 0,
  558. #endif /* CK_RTSCTS */
  559. #ifndef Plan9
  560.     "xon/xoff",  FLO_XONX, 0,
  561. #endif /* Plan9 */
  562.     "", 0, 0
  563. };
  564. int nflo = (sizeof(flotab) / sizeof(struct keytab)) - 1;
  565.  
  566. /*  Handshake characters  */
  567.  
  568. struct keytab hshtab[] = {
  569.     "bell", 007, 0,
  570.     "code", 998, 0,
  571.     "cr",   015, 0,
  572.     "esc",  033, 0,
  573.     "lf",   012, 0,
  574.     "none", 999, 0,            /* (can't use negative numbers) */
  575.     "xoff", 023, 0,
  576.     "xon",  021, 0
  577. };
  578. int nhsh = (sizeof(hshtab) / sizeof(struct keytab));
  579.  
  580. #ifndef NOLOCAL
  581. static struct keytab sfttab[] = {    /* File types for SET SESSION-LOG */
  582.     "ascii",     XYFT_B, CM_INV,
  583.     "binary",    XYFT_B, 0,
  584.     "debug",     XYFT_D, 0,
  585.     "text",      XYFT_T, 0
  586. };
  587. static int nsfttab = (sizeof(sfttab) / sizeof(struct keytab));
  588. #endif /* NOLOCAL */
  589.  
  590. #ifndef NODIAL
  591.  
  592. #ifdef NETCONN                /* Networks directory depends */
  593. int nnetdir = 0;            /* on DIAL code -- fix later... */
  594. char *netdir[MAXDDIR+2];
  595. #endif /* NETCONN */
  596.  
  597. _PROTOTYP( static int setdial, (int) );
  598. _PROTOTYP( static int setdcd, (void) );
  599. _PROTOTYP( static int cklogin, (void) );
  600.  
  601. #ifndef MINIDIAL
  602. #ifdef OLDTBCODE
  603. extern int tbmodel;            /* Telebit model ID */
  604. #endif /* OLDTBCODE */
  605. #endif /* MINIDIAL */
  606.  
  607. extern MDMINF *modemp[];        /* Pointers to modem info structs */
  608. extern struct keytab mdmtab[];        /* Modem types (in module ckudia.c) */
  609. extern int nmdm;            /* Number of them */
  610.  
  611. _PROTOTYP(static int dialstr,(char **, char *));
  612.  
  613. extern int dialhng, dialtmo, dialksp, dialdpy, dialmhu, dialec, dialdc;
  614. extern int dialrtr, dialint, dialudt, dialsrt, dialrstr, mdmwaitd;
  615. extern int mdmspd, dialfc, dialmth, dialesc, dialfld, dialidt, dialpace;
  616. extern int mdmspk, mdmvol, dialtest;
  617.  
  618. int dialcvt = 2;            /* DIAL CONVERT-DIRECTORY */
  619. int dialcnf = 0;            /* DIAL CONFIRMATION */
  620. int dialcon = 2;            /* DIAL CONNECT */
  621. int dialcq  = 0;            /* DIAL CONNECT AUTO quiet/verbose */
  622. extern long dialmax, dialcapas;
  623. int usermdm = 0;
  624. extern int ndialdir;
  625. extern char *dialini,   *dialmstr, *dialmprmt, *dialdir[], *dialcmd,  *dialnpr,
  626.  *dialdcon, *dialdcoff, *dialecon, *dialecoff, *dialhcmd,  *dialx3,
  627.  *dialhwfc, *dialswfc,  *dialnofc, *dialtone,  *dialpulse, *dialname, *diallac;
  628. extern char *diallcc,   *dialixp,  *dialixs,   *dialldp,   *diallds,  *dialtfp,
  629.  *dialpxi,  *dialpxo,   *dialsfx,  *dialaaon,  *dialaaoff;
  630. extern char *diallcp,   *diallcs,  *dialini2,  *dialmac;
  631. extern char *dialspoff, *dialspon, *dialvol1,  *dialvol2,  *dialvol3;
  632.  
  633. char *dialtocc[MAXTPCC] = { NULL, NULL };
  634. int ndialtocc = 0;
  635. char *dialpucc[MAXTPCC] = { NULL, NULL };
  636. int ndialpucc = 0;
  637.  
  638. char *dialtfc[MAXTOLLFREE] = {
  639.     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
  640. };
  641. int ntollfree = 0;
  642.  
  643. char *dialpxx[MAXPBXEXCH] = {
  644.     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
  645. };
  646. int ndialpxx = 0;
  647.  
  648. char *diallcac[MAXLOCALAC] = {
  649.     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  650.     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  651.     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  652.     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
  653. };
  654. int nlocalac = 0;
  655.  
  656. static struct keytab drstrtab[] = {
  657.     "international", 5, 0,
  658.     "local",         2, 0,
  659.     "long-distance", 4, 0,
  660.     "none",          6, 0
  661. };
  662.  
  663. static struct keytab dcnvtab[] = {
  664.     "ask",  2, 0,
  665.     "off",  0, 0,
  666.     "on",   1, 0
  667. };
  668.  
  669. struct keytab setmdm[] = {
  670.     "capabilities",    XYDCAP,  0,
  671.     "carrier-watch",    XYDMCD,  0,
  672.     "command",        XYDSTR,  0,
  673.     "compression",    XYDDC,   CM_INV,
  674.     "data-compression", XYDDC,   0,
  675.     "dial-command",     XYDDIA,  0,
  676.     "error-correction",    XYDEC,   0,
  677.     "escape-character",    XYDESC,  0,
  678.     "flow-control",    XYDFC,   0,
  679.     "hangup-method",    XYDMHU,  0,
  680. #ifndef NOXFER
  681.     "kermit-spoof",    XYDKSP,  0,
  682. #endif /* NOXFER */
  683.     "maximum-speed",    XYDMAX,  0,
  684.     "name",        XYDNAM,  0,
  685.     "speaker",          XYDSPK,  0,
  686.     "speed-matching",    XYDSPD,  0,
  687.     "type",        XYDTYP,  0,
  688.     "volume",           XYDVOL,  0
  689. };
  690. int nsetmdm = (sizeof(setmdm) / sizeof(struct keytab));
  691.  
  692. struct keytab voltab[] = {
  693.     "high",   3,  0,
  694.     "low",    1,  0,
  695.     "medium", 2,  0
  696. };
  697.  
  698. struct keytab mdmcap[] = {
  699.     "at-commands",    CKD_AT,  0,
  700.     "compression",      CKD_DC,  0,
  701.     "dc",               CKD_DC,  CM_INV,
  702.     "ec",               CKD_EC,  CM_INV,
  703.     "error-correction", CKD_EC,  0,
  704.     "hardware-flow",    CKD_HW,  0,
  705.     "hwfc",             CKD_HW,  CM_INV,
  706.     "itu",              CKD_V25, CM_INV,
  707.     "kermit-spoof",    CKD_KS,  0,
  708.     "ks",               CKD_KS,  CM_INV,
  709.     "sb",               CKD_SB,  CM_INV,
  710.     "software-flow",    CKD_SW,  0,
  711.     "speed-buffering",  CKD_SB,  0,
  712.     "swfc",             CKD_SW,  CM_INV,
  713.     "tb",               CKD_TB,  CM_INV,
  714.     "telebit",          CKD_TB,  0,
  715.     "v25bis-commands",    CKD_V25, 0
  716. };
  717. int nmdmcap = (sizeof(mdmcap) / sizeof(struct keytab));
  718.  
  719. struct keytab dialtab[] = {        /* SET DIAL table */
  720.     "area-code",        XYDLAC, 0,    /* Also still includes items     */
  721.     "compression",    XYDDC,  CM_INV,    /* that were moved to SET MODEM, */
  722.     "confirmation",    XYDCNF, 0,    /* but they are CM_INVisible...  */
  723.     "connect",          XYDCON, 0,
  724.     "convert-directory",XYDCVT, 0,
  725.     "country-code",     XYDLCC, 0,
  726.     "dial-command",    XYDDIA, CM_INV,
  727.     "directory",    XYDDIR, 0,
  728.     "display",        XYDDPY, 0,
  729.     "escape-character", XYDESC, CM_INV,
  730.     "error-correction",    XYDEC,  CM_INV,
  731.     "flow-control",    XYDFC,  CM_INV,
  732.     "force-long-distance", XYDFLD, 0,
  733.     "hangup",        XYDHUP, 0,
  734.     "ignore-dialtone",  XYDIDT, 0,
  735.     "interval",        XYDINT, 0,
  736.     "in",        XYDINI, CM_INV|CM_ABR,
  737.     "init-string",    XYDINI, CM_INV,
  738.     "intl-prefix",    XYDIXP, 0,
  739.     "intl-suffix",    XYDIXS, 0,
  740. #ifndef NOXFER
  741.     "kermit-spoof",    XYDKSP, CM_INV,
  742. #endif /* NOXFER */
  743.     "lc-area-codes",    XYDLLAC, 0,
  744.     "lc-prefix",        XYDLCP, 0,
  745.     "lc-suffix",        XYDLCS, 0,
  746.     "ld-prefix",    XYDLDP, 0,
  747.     "ld-suffix",    XYDLDS, 0,
  748.     "local-area-code",  XYDLAC, CM_INV,
  749.     "local-prefix",     XYDLCP, CM_INV,
  750.     "local-suffix",     XYDLCS, CM_INV,
  751.     "m",                XYDMTH, CM_INV|CM_ABR,
  752. #ifndef NOSPL
  753.     "macro",            XYDMAC, 0,    /* 195 */
  754. #endif /* NOSPL */
  755. #ifdef MDMHUP
  756.     "me",               XYDMTH, CM_INV|CM_ABR,
  757. #endif /* MDMHUP */
  758.     "method",        XYDMTH, 0,
  759.     "mnp-enable",    XYDMNP, CM_INV,    /* obsolete but still accepted */
  760. #ifdef MDMHUP
  761.     "modem-hangup",    XYDMHU, CM_INV,
  762. #endif /* MDMHUP */
  763.     "pacing",           XYDPAC,  0,
  764.     "pbx-exchange",     XYDPXX,  0,
  765.     "pbx-inside-prefix",XYDPXI,  0,
  766.     "pbx-outside-prefix",XYDPXO, 0,
  767.     "prefix",        XYDNPR,  0,
  768.     "pulse-countries",  XYDPUCC, 0,
  769.     "restrict",         XYDRSTR, 0,
  770.     "retries",        XYDRTM,  0,
  771.     "sort",             XYDSRT,  0,
  772.     "speed-matching",    XYDSPD,  CM_INV,
  773.     "string",        XYDSTR,  CM_INV,
  774.     "suffix",        XYDSFX,  0,
  775.     "test",             XYDTEST, 0,
  776.     "timeout",        XYDTMO,  0,
  777.     "tf-area-code",     XYDTFC,  CM_INV,
  778.     "tf-prefix",        XYDTFP,  CM_INV,
  779.     "toll-free-area-code",XYDTFC,0,
  780.     "toll-free-prefix", XYDTFP,  0,
  781.     "tone-countries",   XYDTOCC, 0
  782. };
  783. int ndial = (sizeof(dialtab) / sizeof(struct keytab));
  784.  
  785. #ifdef MDMHUP
  786. struct keytab mdmhang[] = {
  787.     "modem-command", 1, 0,
  788.     "rs232-signal",  0, 0,
  789.     "v24-signal",    0, CM_INV
  790. };
  791. #endif /* MDMHUP */
  792.  
  793. static struct keytab mdmcmd[] = {
  794.     "autoanswer",       XYDS_AN, 0,    /* autoanswer */
  795.     "compression",    XYDS_DC, 0,    /* data compression */
  796.     "dial-mode-prompt", XYDS_MP, 0,    /* dial mode prompt */
  797.     "dial-mode-string", XYDS_MS, 0,    /* dial mode string */
  798.     "error-correction",    XYDS_EC, 0,    /* error correction */
  799.     "hangup-command",    XYDS_HU, 0,    /* hangup command */
  800.     "hardware-flow",    XYDS_HW, 0,    /* hwfc */
  801.     "ignore-dialtone",    XYDS_ID, 0,    /* ignore dialtone */
  802.     "init-string",    XYDS_IN, 0,    /* init string */
  803.     "no-flow-control",    XYDS_NF, 0,    /* no flow control */
  804.     "predial-init",     XYDS_I2, 0,     /* last-minute setup commands */
  805.     "pulse",            XYDS_DP, 0,    /* pulse */
  806.     "software-flow",    XYDS_SW, 0,    /* swfc */
  807.     "speaker",          XYDS_SP, 0,     /* Speaker */
  808.     "tone",             XYDS_DT, 0,    /* tone */
  809.     "volume",           XYDS_VO, 0      /* Volume */
  810. };
  811. static int nmdmcmd = (sizeof(mdmcmd) / sizeof(struct keytab));
  812.  
  813. struct keytab dial_fc[] = {
  814.     "auto",     FLO_AUTO, 0,
  815.     "none",     FLO_NONE, 0,
  816.     "rts/cts",  FLO_RTSC, 0,
  817.     "xon/xoff", FLO_XONX, 0
  818. };
  819.  
  820. struct keytab dial_m[] = {        /* DIAL METHOD */
  821.     "auto",    XYDM_A, 0,
  822.     "default", XYDM_D, 0,
  823.     "pulse",   XYDM_P, 0,
  824.     "tone",    XYDM_T, 0
  825. };
  826. int ndial_m = (sizeof(dial_m)/sizeof(struct keytab));
  827.  
  828. #ifdef CK_TAPI
  829. struct keytab tapitab[] = {        /* Top-Level Microsoft TAPI */
  830.     "configure-line",     XYTAPI_CFG,  0,
  831.     "dialing-properties", XYTAPI_DIAL, 0
  832. };
  833. int ntapitab = (sizeof(tapitab)/sizeof(struct keytab));
  834.  
  835. struct keytab settapitab[] = {        /* SET Microsoft TAPI */
  836.     "inactivity-timeout", XYTAPI_INA,  0,
  837.     "line",               XYTAPI_LIN,  0,
  838.     "location",           XYTAPI_LOC,  0,
  839.     "manual-dialing",     XYTAPI_MAN,  0,
  840.     "modem-dialing",      XYTAPI_PASS, 0,
  841.     "modem-lights",       XYTAPI_LGHT, 0,
  842.     "phone-number-conversions",      XYTAPI_CON,  0,
  843.     "port",               XYTAPI_LIN,  CM_INV,
  844.     "post-dial-terminal", XYTAPI_PST,  0,
  845.     "pre-dial-terminal",  XYTAPI_PRE,  0,
  846.     "use-windows-configuration", XYTAPI_USE, 0,
  847.     "wait-for-credit-card-tone", XYTAPI_BNG, 0
  848. };
  849. int nsettapitab = (sizeof(settapitab)/sizeof(struct keytab));
  850.  
  851. struct keytab * tapiloctab = NULL;    /* Microsoft TAPI Locations */
  852. int ntapiloc = 0;
  853. extern struct keytab * tapilinetab;    /* Microsoft TAPI Line Devices */
  854. extern int ntapiline;
  855. extern int tttapi;            /* TAPI in use */
  856. extern int tapipass;            /* TAPI Passthrough mode */
  857. extern int tapiconv;            /* TAPI Conversion mode */
  858. extern int tapilights;
  859. extern int tapipreterm;
  860. extern int tapipostterm;
  861. extern int tapimanual;
  862. extern int tapiinactivity;
  863. extern int tapibong;
  864. extern int tapiusecfg;
  865. #endif /* CK_TAPI */
  866. #endif /* NODIAL */
  867.  
  868. #ifndef NOPUSH
  869. extern int nopush;
  870. #ifdef UNIX
  871. struct keytab wildtab[] = {        /* SET WILDCARD-EXPANSION */
  872.     "kermit",  0, 0,
  873.     "shell",   1, 0
  874. };
  875. struct keytab wdottab[] = {        /* cont'd */
  876.     "/match-dot-files",    1, 0,
  877.     "/no-match-dot-files", 0, 0
  878. };
  879. extern int wildxpand;
  880. #endif /* UNIX */
  881. #endif /* NOPUSH */
  882.  
  883. #ifdef NETCONN
  884. extern struct keytab netcmd[], netkey[];
  885. extern int nnets, nnetkey;
  886. #ifdef TCPSOCKET
  887. extern struct keytab tcpopt[];
  888. extern int ntcpopt;
  889. #ifndef NOTCPOPTS
  890. #ifdef SO_LINGER
  891. _PROTOTYP( int linger, (int,int) );
  892. #endif /* SO_LINGER */
  893. #ifdef TCP_NODELAY
  894. _PROTOTYP( int no_delay, (int) );
  895. #endif /* TCP_NODELAY */
  896. #endif /* NOTCPOPTS */
  897. #endif /* TCPSOCKET */
  898. #ifdef NPIPE
  899. char pipename[PIPENAML+1] = { NUL, NUL };
  900. #endif /* NPIPE */
  901. #ifdef CK_NETBIOS
  902. extern unsigned char NetBiosName[];
  903. #endif /* CK_NETBIOS */
  904. #endif /* NETCONN */
  905.  
  906. #ifdef ANYX25
  907. struct keytab x25tab[] = {
  908.     "call-user-data",    XYUDAT, 0,
  909.     "closed-user-group", XYCLOS, 0,
  910.     "reverse-charge",    XYREVC, 0
  911. };
  912. int nx25 = (sizeof(x25tab) / sizeof(struct keytab));
  913.  
  914. #ifndef IBMX25
  915. struct keytab padx3tab[] = {
  916.     "break-action",         PAD_BREAK_ACTION,           0,
  917.     "break-character",      PAD_BREAK_CHARACTER,        0,
  918.     "character-delete",     PAD_CHAR_DELETE_CHAR,       0,
  919.     "cr-padding",           PAD_PADDING_AFTER_CR,       0,
  920.     "discard-output",       PAD_SUPPRESSION_OF_DATA,    0,
  921.     "echo",                 PAD_ECHO,                   0,
  922.     "editing",              PAD_EDITING,                0,
  923.     "escape",               PAD_ESCAPE,                 0,
  924.     "forward",              PAD_DATA_FORWARD_CHAR,      0,
  925.     "lf-padding",           PAD_PADDING_AFTER_LF,       0,
  926.     "lf-insert",            PAD_LF_AFTER_CR,            0,
  927.     "line-delete",          PAD_BUFFER_DELETE_CHAR,     0,
  928.     "line-display",         PAD_BUFFER_DISPLAY_CHAR,    0,
  929.     "line-fold",            PAD_LINE_FOLDING,           0,
  930.     "pad-flow-control",     PAD_FLOW_CONTROL_BY_PAD,    0,
  931.     "service-signals",      PAD_SUPPRESSION_OF_SIGNALS, 0,
  932.     "timeout",              PAD_DATA_FORWARD_TIMEOUT,   0,
  933. /* Speed is read-only */
  934.     "transmission-rate",    PAD_LINE_SPEED,             0,
  935.     "user-flow-control",    PAD_FLOW_CONTROL_BY_USER,   0
  936. };
  937. int npadx3 = (sizeof(padx3tab) / sizeof(struct keytab));
  938. #endif /* IBMX25 */
  939. #endif /* ANYX25 */
  940.  
  941. #ifdef TLOG
  942. static struct keytab vbtab[] = {
  943.     "brief",   0, 0,
  944. #ifdef OS2ORUNIX
  945.     "ftp",     2, 0,
  946. #endif /* OS2ORUNIX */
  947.     "verbose", 1, 0
  948. };
  949. int nvb = (sizeof(vbtab) / sizeof(struct keytab));
  950. #endif /* TLOG */
  951.  
  952. #ifdef CKSYSLOG
  953. static struct keytab syslogtab[] = {
  954.     "all",         SYSLG_CX, 0,
  955.     "commands",    SYSLG_CM, 0,
  956.     "connection",  SYSLG_AC, 0,
  957.     "debug",       SYSLG_DB, 0,
  958.     "dial",        SYSLG_DI, 0,
  959.     "file-access", SYSLG_FA, 0,
  960.     "file-create", SYSLG_FC, 0,
  961.     "login",       SYSLG_LI, 0,
  962.     "none",        SYSLG_NO, 0,
  963.     "protocol",    SYSLG_PR, 0
  964. };
  965. int nsyslog = (sizeof(syslogtab) / sizeof(struct keytab));
  966. #endif /* CKSYSLOG */
  967.  
  968. /* Parity keyword table */
  969.  
  970. struct keytab partbl[] = {
  971.     "even",    'e', 0,
  972. #ifdef HWPARITY
  973.     "hardware",'H', 0,
  974. #endif /* HWPARITY */
  975.     "mark",    'm', 0,
  976.     "none",     0 , 0,
  977.     "odd",     'o', 0,
  978.     "space",   's', 0
  979. };
  980. int npar = (sizeof(partbl) / sizeof(struct keytab));
  981.  
  982. #ifdef HWPARITY
  983. struct keytab hwpartbl[] = {
  984. /* Add mark and space if needed and possible */
  985.     "even",    'e', 0,
  986. #ifdef OS2
  987.     "mark",    'm', 0,
  988. #endif /* OS2 */
  989.     "odd",     'o', 0,
  990. #ifdef OS2
  991.     "space",   's', 0,
  992. #endif /* OS2 */
  993.     "", 0, 0
  994. };
  995. int nhwpar = (sizeof(hwpartbl) / sizeof(struct keytab)) - 1;
  996. #endif /* HWPARITY */
  997.  
  998. /* On/Off table */
  999.  
  1000. struct keytab onoff[] = {
  1001.     "off",       0, 0,
  1002.     "on",        1, 0
  1003. };
  1004.  
  1005. struct keytab cdtab[] = {
  1006.     "message",   XYCD_M, 0,
  1007.     "path",      XYCD_P, 0
  1008. };
  1009. int ncdtab = (sizeof(cdtab) / sizeof(struct keytab));
  1010.  
  1011. struct keytab cdmsg[] = {
  1012.     "file",      2, 0,
  1013.     "off",       0, 0,
  1014.     "on",        1, 0
  1015. };
  1016. int ncdmsg = (sizeof(cdmsg) / sizeof(struct keytab));
  1017.  
  1018. static
  1019. struct keytab xittab[] = {        /* SET EXIT */
  1020.     "on-disconnect", 2, 0,        /* ...ON-DISCONNECT */
  1021.     "status",        0, 0,        /* ...STATUS */
  1022.     "warning",       1, 0        /* ...WARNING */
  1023. };
  1024. int nexit = (sizeof(xittab) / sizeof(struct keytab));
  1025.  
  1026. struct keytab xitwtab[] = {        /* SET EXIT WARNING */
  1027.     "always", 2, 0,                     /* even when not connected */
  1028.     "off",    0, 0,            /* no warning     */
  1029.     "on",     1, 0            /* when connected */
  1030. };
  1031. int nexitw = (sizeof(xitwtab) / sizeof(struct keytab));
  1032.  
  1033. struct keytab rltab[] = {
  1034.     "local",     1, 0,            /* ECHO values */
  1035.     "off",       0, CM_INV,
  1036.     "on",        1, CM_INV,
  1037.     "remote",    0, 0
  1038. };
  1039. int nrlt = (sizeof(rltab) / sizeof(struct keytab));
  1040.  
  1041. /* Incomplete File Disposition table */
  1042.  
  1043. struct keytab ifdtab[] = {
  1044.     "discard", SET_OFF, 0,
  1045.     "keep",    SET_ON,  0
  1046. };
  1047.  
  1048. struct keytab ifdatab[] = {
  1049.     "auto",    SET_AUTO, 0,
  1050.     "discard", SET_OFF,  0,
  1051.     "keep",    SET_ON,   0
  1052. };
  1053.  
  1054. char * ifdnam[] = { "discard", "keep", "auto" };
  1055.  
  1056. /* SET TAKE parameters table */
  1057. static
  1058. struct keytab taktab[] = {
  1059.     "echo",  0, 0,
  1060.     "error", 1, 0,
  1061.     "off",   2, CM_INV,            /* For compatibility */
  1062.     "on",    3, CM_INV            /* with MS-DOS Kermit... */
  1063. };
  1064.  
  1065. #ifndef NOSPL
  1066. #ifdef COMMENT
  1067. /* not used */
  1068. static
  1069. struct keytab suftab[] = {        /* (what to do with) STARTUP-FILE */
  1070.     "delete", 1, 0,
  1071.     "keep",   0, 0
  1072. };
  1073. #endif /* COMMENT */
  1074.  
  1075. /* SET MACRO parameters table */
  1076. static
  1077. struct keytab smactab[] = {
  1078.     "echo",  0, 0,
  1079.     "error", 1, 0
  1080. };
  1081. #endif /* NOSPL */
  1082.  
  1083. #ifndef NOSCRIPT
  1084. static
  1085. struct keytab scrtab[] = {
  1086.     "echo",  0, 0
  1087. };
  1088. #endif /* NOSCRIPT */
  1089.  
  1090. /* SET COMMAND table */
  1091. static struct keytab scmdtab[] = {
  1092. #ifdef CK_AUTODL
  1093.     "autodownload", SCMD_ADL, 0,
  1094. #endif /* CK_AUTODL */
  1095.     "bytesize",  SCMD_BSZ, 0,
  1096.     "cbreak",    876, CM_INV,
  1097. #ifdef OS2
  1098.     "color",     SCMD_COL, 0,
  1099.     "cursor-position", SCMD_CUR, 0,
  1100. #endif /* OS2 */
  1101.     "height",    SCMD_HIG, 0,
  1102.     "interruption", SCMD_INT, 0,
  1103.     "more-prompting",  SCMD_MOR, 0,
  1104.     "quoting",   SCMD_QUO, 0
  1105. #ifdef CK_RECALL
  1106. ,   "recall-buffer-size", SCMD_RCL, 0
  1107. #endif /* CK_RECALL */
  1108. #ifdef CK_RECALL
  1109. ,   "retry", SCMD_RTR, 0
  1110. #endif /* CK_RECALL */
  1111. #ifdef OS2
  1112. #ifdef ONETERMUPD
  1113. ,  "scrollback",  SCMD_SCR, 0
  1114. #endif /* ONETERMUPD */
  1115. #endif /* OS2 */
  1116. ,   "width",     SCMD_WID, 0
  1117. };
  1118. static int nbytt = (sizeof(scmdtab) / sizeof(struct keytab));
  1119.  
  1120. #ifndef NOSERVER
  1121. /* Server parameters table */
  1122. static struct keytab srvtab[] = {
  1123.     "cd-message",   XYSERC, 0,
  1124.     "display",      XYSERD, 0,
  1125.     "get-path",     XYSERP, 0,
  1126.     "idle-timeout", XYSERI, 0,
  1127.     "keepalive",    XYSERK, 0,
  1128.     "login",        XYSERL, 0,
  1129.     "timeout",      XYSERT, 0
  1130. };
  1131. static int nsrvt = (sizeof(srvtab) / sizeof(struct keytab));
  1132. #endif /* NOSERVER */
  1133.  
  1134. static struct keytab sleeptab[] = {    /* SET SLEEP table */
  1135.     "cancellation",  0,   0
  1136. };
  1137.  
  1138. static struct keytab tstab[] = {    /* SET TRANSFER/XFER table */
  1139.     "bell",            XYX_BEL, 0,
  1140. #ifdef XFRCAN
  1141.     "cancellation",    XYX_CAN, 0,
  1142. #endif /* XFRCAN */
  1143. #ifndef NOCSETS
  1144.     "character-set",   XYX_CSE, 0,
  1145. #endif /* NOCSETS */
  1146. #ifndef NOSPL
  1147.     "crc-calculation", XYX_CRC, 0,
  1148. #endif /* NOSPL */
  1149.     "display",         XYX_DIS, 0,
  1150.     "interruption",    XYX_INT, 0,
  1151.     "locking-shift",   XYX_LSH, 0,
  1152.     "mode",            XYX_MOD, 0,
  1153. #ifdef PIPESEND
  1154.     "pipes",           XYX_PIP, 0,
  1155. #endif /* PIPESEND */
  1156. #ifdef CK_XYZ
  1157.     "protocol",        XYX_PRO, 0,
  1158. #endif /* CK_XYZ */
  1159.     "slow-start",      XYX_SLO, 0,
  1160.     "", 0, 0
  1161. };
  1162. static int nts = (sizeof(tstab) / sizeof(struct keytab)) - 1;
  1163.  
  1164. static struct keytab rtstab[] = {    /* REMOTE SET TRANSFER/XFER table */
  1165. #ifndef NOCSETS
  1166.     "character-set",   XYX_CSE, 0,
  1167. #endif /* NOCSETS */
  1168.     "mode",            XYX_MOD, 0
  1169. };
  1170. static int nrts = (sizeof(rtstab) / sizeof(struct keytab));
  1171.  
  1172. struct keytab xfrmtab[] = {        /* TRANSFER MODE table */
  1173.     "automatic", XMODE_A, 0,
  1174.     "manual",    XMODE_M, 0
  1175. };
  1176.  
  1177. #ifndef NOCSETS
  1178. /* SET TRANSFER CHARACTER-SET table */
  1179.  
  1180. extern struct keytab tcstab[];
  1181. extern int ntcs;
  1182. #endif /* NOCSETS */
  1183.  
  1184. /* SET TRANSFER LOCKING-SHIFT table */
  1185. struct keytab lstab[] = {
  1186.     "forced", 2,   0,
  1187.     "off",    0,   0,
  1188.     "on",     1,   0
  1189. };
  1190. int nls = (sizeof(lstab) / sizeof(struct keytab));
  1191.  
  1192. /* SET TELNET tables */
  1193. #ifdef TNCODE
  1194. extern int tn_nlm, tn_b_nlm, tn_b_meu, tn_b_ume, tn_b_xfer, tn_sb_bug;
  1195. extern int tn_no_encrypt_xfer;
  1196. extern int tn_wait_flg, tn_duplex;
  1197. extern int sl_tn_saved;
  1198. extern int tn_infinite;
  1199. extern int tn_rem_echo;
  1200. extern int tn_deb;
  1201. extern int tn_auth_how;
  1202. extern int tn_auth_enc;
  1203. #ifdef CK_AUTHENTICATION
  1204. static struct keytab setauth[] = {
  1205. #ifdef CK_KERBEROS
  1206.     "k4",        AUTH_KRB4, CM_INV,
  1207.     "k5",        AUTH_KRB5, CM_INV,
  1208.     "kerberos4", AUTH_KRB4, 0,
  1209.     "kerberos5", AUTH_KRB5, 0,
  1210.     "kerberos_iv",AUTH_KRB4, CM_INV,
  1211.     "kerberos_v", AUTH_KRB5, CM_INV,
  1212.     "krb4",      AUTH_KRB4, CM_INV,
  1213.     "krb5",      AUTH_KRB5, CM_INV,
  1214. #endif /* CK_KERBEROS */
  1215. #ifdef CK_SRP
  1216.     "srp",       AUTH_SRP,  0,
  1217. #endif /* CK_SRP */
  1218. #ifdef CK_SSL
  1219.     "ssl",      AUTH_SSL,   0,
  1220.     "tls",      AUTH_TLS,   0,
  1221. #endif /* CK_SSL */
  1222.     "",         0,      0
  1223. };
  1224. static int nsetauth = sizeof(setauth)/sizeof(struct keytab) - 1;
  1225. #ifdef CK_KERBEROS
  1226. extern char * krb5_d_principal;        /* Default principal */
  1227. extern char * krb5_d_instance;
  1228. extern char * krb5_d_realm;        /* Default realm */
  1229. extern char * krb5_d_cc;        /* Default credentials cache */
  1230. extern char * krb5_d_srv;               /* Default service name */
  1231. extern int    krb5_d_lifetime;          /* Default lifetime */
  1232. extern int    krb5_d_forwardable;
  1233. extern int    krb5_d_proxiable;
  1234. extern int    krb5_d_renewable;
  1235. extern int    krb5_autoget;
  1236. extern int    krb5_autodel;
  1237. extern int    krb5_d_getk4;
  1238. extern int    krb5_checkaddrs;        /* Check TGT Addrs */
  1239.  
  1240. extern struct krb4_init_data krb4_init;
  1241. extern char * krb4_d_principal;        /* Default principal */
  1242. extern char * krb4_d_realm;        /* Default realm */
  1243. extern char * krb4_d_srv;               /* Default service name */
  1244. extern int    krb4_d_lifetime;          /* Default lifetime */
  1245. extern int    krb4_d_preauth;
  1246. extern char * krb4_d_instance;
  1247. extern int    krb4_autoget;
  1248. extern int    krb4_autodel;
  1249. extern int    krb4_checkaddrs;        /* Check TGT Addrs */
  1250. #ifdef KRB4
  1251. extern int    k4debug;
  1252. #endif /* KRB4 */
  1253. static struct keytab krbver[] = {
  1254.     "4",                 4, 0,
  1255.     "5",                 5, 0,
  1256.     "iv",                4, CM_INV,
  1257.     "v",                 5, CM_INV
  1258. };
  1259. static int nkrbver = sizeof(krbver)/sizeof(struct keytab);
  1260.  
  1261. static struct keytab kdestab[] = {
  1262.     "never",            KRB_DEL_NO, 0,
  1263.     "no",               KRB_DEL_NO, CM_INV,
  1264.     "on-close",         KRB_DEL_CL, 0,
  1265.     "on-exit",          KRB_DEL_EX, 0
  1266. };
  1267. static int nkdestab = sizeof(kdestab)/sizeof(struct keytab);
  1268.  
  1269. static struct keytab k4tab[] = {
  1270.     "autodel",           XYKRBDEL, CM_INV,
  1271.     "autodestroy",       XYKRBDEL, 0,
  1272.     "autoget",           XYKRBGET, 0,
  1273.     "check-address",     XYKRBADR, 0,
  1274.     "debug",             XYKRBDBG, CM_INV,
  1275.     "instance",          XYKRBINS, 0,
  1276.     "lifetime",          XYKRBLIF, 0,
  1277.     "preauth",           XYKRBPRE, 0,
  1278.     "principal",         XYKRBPR,  0,
  1279.     "prompt",            XYKRBPRM, 0,
  1280.     "realm",             XYKRBRL,  0,
  1281.     "service-name",      XYKRBSRV, 0
  1282. };
  1283. static int nk4tab = sizeof(k4tab)/sizeof(struct keytab);
  1284.  
  1285. static struct keytab k5tab[] = {
  1286.     "autodel",           XYKRBDEL, CM_INV,
  1287.     "autodestroy",       XYKRBDEL, 0,
  1288.     "autoget",           XYKRBGET, 0,
  1289.     "cc",                XYKRBCC,  CM_INV,
  1290.     "check-address",     XYKRBADR, 0,
  1291.     "credentials-cache", XYKRBCC,  0,
  1292.     "forwardable",       XYKRBFWD, 0,
  1293.     "get-k4-tgt",        XYKRBK5K4,0,
  1294.     "instance",          XYKRBINS, 0,
  1295.     "lifetime",          XYKRBLIF, 0,
  1296.     "principal",         XYKRBPR,  0,
  1297.     "prompt",            XYKRBPRM, 0,
  1298.     "proxiable",         XYKRBPRX, 0,
  1299.     "realm",             XYKRBRL,  0,
  1300.     "renewable",         XYKRBRNW, 0,
  1301.     "service-name",      XYKRBSRV, 0
  1302. };
  1303. static int nk5tab = sizeof(k5tab)/sizeof(struct keytab);
  1304.  
  1305. #define KRB_PW_PRM 1
  1306. #define KRB_PR_PRM 2
  1307.  
  1308. static struct keytab krbprmtab[] = {
  1309.     "password",  KRB_PW_PRM, 0,
  1310.     "principal", KRB_PR_PRM, 0
  1311. };
  1312.  
  1313. #endif /* CK_KERBEROS */
  1314. #ifdef CK_SRP
  1315. static struct keytab srptab[] = {
  1316.     "prompt",            XYSRPPRM, 0
  1317. };
  1318. static int nsrptab = sizeof(srptab)/sizeof(struct keytab);
  1319. #define SRP_PW_PRM 1
  1320.  
  1321. static struct keytab srpprmtab[] = {
  1322.     "password",  SRP_PW_PRM, 0
  1323. };
  1324. #endif /* CK_SRP */
  1325. #ifdef CK_SSL
  1326. static struct keytab ssltab[] = {
  1327.     "certs-ok",          XYSSLCOK,  CM_INV,
  1328.     "cipher-list",       XYSSLCL,   0,
  1329.     "crl-dir",           XYSSLCRLD, 0,
  1330.     "crl-file",          XYSSLCRL,  0,
  1331.     "debug",             XYSSLDBG,  0,
  1332.     "dh-key-file",       XYSSLDKFL, CM_INV,
  1333.     "dh-param-file",     XYSSLDPFL, 0,
  1334.     "dsa-cert-file",     XYSSLDCFL, 0,
  1335.     "dsa-key-file",      XYSSLDKFL, 0,
  1336.     "dummy",             XYSSLDUM,  CM_INV,
  1337.     "only",              XYSSLON,   CM_INV,
  1338.     "rsa-cert-file",     XYSSLRCFL, 0,
  1339.     "rsa-key-file",      XYSSLRKFL, 0,
  1340.     "verbose",           XYSSLVRB,  0,
  1341.     "verify",            XYSSLVRF,  0,
  1342.     "verify-dir",        XYSSLVRFD, 0,
  1343.     "verify-file",       XYSSLVRFF, 0
  1344. };
  1345. static int nssltab = sizeof(ssltab)/sizeof(struct keytab);
  1346. static struct keytab sslvertab[] = {
  1347.     "fail-if-no-peer-cert", SSL_VERIFY_PEER |
  1348.                             SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0,
  1349.     "no",               SSL_VERIFY_NONE, 0,
  1350.     "none",             SSL_VERIFY_NONE, CM_INV,
  1351.     "off",              SSL_VERIFY_NONE, CM_INV,
  1352.     "on",               SSL_VERIFY_PEER, CM_INV,
  1353.     "peer-cert",        SSL_VERIFY_PEER, 0
  1354. };
  1355. static int nsslvertab = sizeof(sslvertab)/sizeof(struct keytab);
  1356. #endif /* CK_SSL */
  1357. #endif /* CK_AUTHENTICATION */
  1358. #ifdef CK_ENCRYPTION
  1359. int cx_type = CX_AUTO;
  1360. extern int sl_cx_type;
  1361. #endif /* CK_ENCRYPTION */
  1362. extern char *tcp_address;
  1363.  
  1364. static struct keytab tnnegtab[] = {    /* TELNET NEGOTIATION table */
  1365.     "accepted",  TN_NG_AC, 0,
  1366.     "refused",   TN_NG_RF, 0,
  1367.     "req",       TN_NG_RQ, CM_INV|CM_ABR,
  1368.     "requ",      TN_NG_RQ, CM_INV|CM_ABR,
  1369.     "reque",     TN_NG_RQ, CM_INV|CM_ABR,
  1370.     "reques",    TN_NG_RQ, CM_INV|CM_ABR,
  1371.     "request",   TN_NG_RQ, CM_INV|CM_ABR,
  1372.     "requeste",  TN_NG_RQ, CM_INV|CM_ABR,
  1373.     "requested", TN_NG_RQ, 0,
  1374.     "required",  TN_NG_MU, 0
  1375. };
  1376. static int ntnnegtab = sizeof(tnnegtab)/sizeof(struct keytab);
  1377.  
  1378. #ifdef CK_ENCRYPTION
  1379. static struct keytab typkwd[] = {
  1380.     "/type", 0, CM_ARG
  1381. };
  1382.  
  1383. static struct keytab tnenctab[] = {    /* TELNET ENCRYPTION table */
  1384.     "accepted",   TN_NG_AC,    CM_INV,
  1385.     "refused",    TN_NG_RF,    CM_INV,
  1386.     "req",        TN_NG_RQ,    CM_INV|CM_ABR,
  1387.     "requ",       TN_NG_RQ,    CM_INV|CM_ABR,
  1388.     "reque",      TN_NG_RQ,    CM_INV|CM_ABR,
  1389.     "reques",     TN_NG_RQ,    CM_INV|CM_ABR,
  1390.     "request",    TN_NG_RQ,    CM_INV|CM_ABR,
  1391.     "requeste",   TN_NG_RQ,    CM_INV|CM_ABR,
  1392.     "requested",  TN_NG_RQ,    CM_INV,
  1393.     "required",   TN_NG_MU,    CM_INV,
  1394.     "start",      TN_EN_START, CM_INV,
  1395.     "stop",       TN_EN_STOP,  CM_INV,
  1396.     "type",       TN_EN_TYP,   0
  1397. };
  1398. static int ntnenc = sizeof(tnenctab)/sizeof(struct keytab) ;
  1399.  
  1400. #endif /* CK_ENCRYPTION */
  1401.  
  1402. static struct keytab tnbugtab[] = {    /* TELNET BUG table */
  1403.     "binary-me-means-u-too", 0, 0,
  1404.     "binary-u-means-me-too", 1, 0,
  1405.     "infinite-loop-check",   2, 0,
  1406.     "sb-implies-will-do",    3, 0
  1407. };
  1408.  
  1409. #ifdef CK_ENVIRONMENT
  1410. static struct keytab tnenvtab[] = {    /* TELNET ENVIRONMENT table */
  1411.     "acct",    TN_ENV_ACCT,    0,
  1412.     "display",    TN_ENV_DISP,    0,
  1413.     "job",    TN_ENV_JOB,    0,
  1414.     "off",      TN_ENV_OFF,     CM_INV,
  1415.     "on",       TN_ENV_ON,      CM_INV,
  1416.     "printer",    TN_ENV_PRNT,    0,
  1417.     "systemtype",TN_ENV_SYS,    0,
  1418.     "user",     TN_ENV_USR,     0,
  1419. #ifdef COMMENT
  1420.     "uservar",    TN_ENV_UVAR,    CM_INV
  1421. #endif /* COMMENT */
  1422.     "", 0, 0
  1423. };
  1424. static int ntnenv = sizeof(tnenvtab)/sizeof(struct keytab) - 1;
  1425. #endif /* CK_ENVIRONMENT */
  1426.  
  1427. #ifdef CK_AUTHENTICATION
  1428. static struct keytab tnauthtab[] = {    /* TELNET AUTHENTICATION table */
  1429.     "accepted",   TN_NG_AC,  CM_INV,
  1430.     "encrypt-flag", TN_AU_ENC, 0,
  1431.     "forwarding", TN_AU_FWD,   0,
  1432.     "how-flag",   TN_AU_HOW,   0,
  1433.     "refused",    TN_NG_RF,  CM_INV,
  1434.     "req",        TN_NG_RQ,  CM_INV|CM_ABR,
  1435.     "requ",       TN_NG_RQ,  CM_INV|CM_ABR,
  1436.     "reque",      TN_NG_RQ,  CM_INV|CM_ABR,
  1437.     "reques",     TN_NG_RQ,  CM_INV|CM_ABR,
  1438.     "request",    TN_NG_RQ,  CM_INV|CM_ABR,
  1439.     "requeste",   TN_NG_RQ,  CM_INV|CM_ABR,
  1440.     "requested",  TN_NG_RQ,  CM_INV,
  1441.     "required",   TN_NG_MU,  CM_INV,
  1442.     "type",       TN_AU_TYP, 0
  1443. };
  1444. static int ntnauth = sizeof(tnauthtab)/sizeof(struct keytab) ;
  1445.  
  1446. struct keytab autyptab[] = {    /* TELNET AUTHENTICATION TYPE table */
  1447.     "automatic",  AUTH_AUTO, 0,
  1448. #ifdef CK_KERBEROS
  1449.     "k4",         AUTH_KRB4, CM_INV,
  1450.     "k5",         AUTH_KRB5, CM_INV,
  1451.     "kerberos4",  AUTH_KRB4, 0,
  1452.     "kerberos5",  AUTH_KRB5, 0,
  1453.     "kerberos_iv",AUTH_KRB4, CM_INV,
  1454.     "kerberos_v", AUTH_KRB5, CM_INV,
  1455.     "krb4",       AUTH_KRB4, CM_INV,
  1456.     "krb5",       AUTH_KRB5, CM_INV,
  1457. #endif /* CK_KERBEROS */
  1458.     "none",       AUTH_NONE, 0,
  1459. #ifdef NT
  1460.     "ntlm",       AUTH_NTLM, 0,
  1461. #endif /* NT */
  1462. #ifdef CK_SRP
  1463.     "srp",        AUTH_SRP,  0,
  1464. #endif /* CK_SRP */
  1465. #ifdef CK_SSL
  1466.     "ssl",        AUTH_SSL,  0,
  1467. #endif /* CK_SSL */
  1468.     "", 0, 0
  1469. };
  1470. int nautyp = sizeof(autyptab)/sizeof(struct keytab) - 1;
  1471.  
  1472. struct keytab auhowtab[] = {    /* TELNET AUTHENTICATION HOW table */
  1473.     "any",     TN_AUTH_HOW_ANY,     0,
  1474.     "mutual",  TN_AUTH_HOW_MUTUAL,  0,
  1475.     "one-way", TN_AUTH_HOW_ONE_WAY, 0,
  1476.     "", 0, 0
  1477. };
  1478. int nauhow = sizeof(auhowtab)/sizeof(struct keytab) - 1;
  1479.  
  1480. struct keytab auenctab[] = {    /* TELNET AUTHENTICATION ENCRYPT table */
  1481.     "any",     TN_AUTH_ENC_ANY,     0,
  1482.     "none",    TN_AUTH_ENC_NONE,    0,
  1483.     "telopt",  TN_AUTH_ENC_TELOPT,  0,
  1484.     "", 0, 0
  1485. };
  1486. int nauenc = sizeof(auenctab)/sizeof(struct keytab) - 1;
  1487. #endif /* CK_AUTHENTICATION */
  1488.  
  1489. #define TN_NL_BIN 3
  1490. #define TN_NL_NVT 4
  1491. static struct keytab tn_nlmtab[] = {    /* TELNET NEWLINE-MODE table */
  1492.     "binary-mode", TN_NL_BIN, 0,    /* Binary mode */
  1493.     "nvt",    TN_NL_NVT, 0,        /* NVT mode */
  1494.     "off",    TNL_CRNUL, CM_INV,    /* CR-NUL (TELNET spec) */
  1495.     "on",     TNL_CRLF,  CM_INV,    /* CR-LF (TELNET spec) */
  1496.     "raw",    TNL_CR,    CM_INV        /* CR only (out of spec) */
  1497. };
  1498. static int ntn_nlm = (sizeof(tn_nlmtab) / sizeof(struct keytab));
  1499.  
  1500. static struct keytab tnlmtab[] = {    /* TELNET NEWLINE-MODE table */
  1501.     "cr",     TNL_CR,    CM_INV,    /* CR only (out of spec) */
  1502.     "cr-lf",  TNL_CRLF,  CM_INV,    /* CR-LF (TELNET spec) */
  1503.     "cr-nul", TNL_CRNUL, CM_INV,    /* CR-NUL (TELNET spec) */
  1504.     "lf",     TNL_LF,    CM_INV,    /* LF instead of CR-LF */
  1505.     "off",    TNL_CRNUL, 0,        /* CR-NUL (TELNET spec) */
  1506.     "on",     TNL_CRLF,  0,        /* CR-LF (TELNET spec) */
  1507.     "raw",    TNL_CR,    0        /* CR only (out of spec) */
  1508. };
  1509. static int ntnlm = (sizeof(tnlmtab) / sizeof(struct keytab));
  1510.  
  1511. struct keytab tntab[] = {
  1512. #ifdef CK_AUTHENTICATION
  1513.     "authentication",       CK_TN_AU,  0,
  1514. #endif /* CK_AUTHENTICATION */
  1515.     "b",                    CK_TN_BM,  CM_INV|CM_ABR,
  1516.     "bi",                   CK_TN_BM,  CM_INV|CM_ABR,
  1517.     "bin",                  CK_TN_BM,  CM_INV|CM_ABR,
  1518.     "bina",                 CK_TN_BM,  CM_INV|CM_ABR,
  1519.     "binar",                CK_TN_BM,  CM_INV|CM_ABR,
  1520.     "binary",               CK_TN_BM,  CM_INV|CM_ABR,
  1521.     "binary-",              CK_TN_BM,  CM_INV|CM_ABR,
  1522.     "binary-mode",          CK_TN_BM,  CM_INV,
  1523.     "binary-transfer-mode", CK_TN_XF,  0,
  1524.     "binary-xfer-mode",     CK_TN_XF,  CM_INV,
  1525.     "bug",                  CK_TN_BUG, 0,
  1526.     "debug",                CK_TN_DB,  0,
  1527.     "echo",                 CK_TN_EC,  0,
  1528. #ifdef CK_ENCRYPTION
  1529.     "encryption",      CK_TN_ENC,  0,
  1530. #endif /* CK_ENCRYPTION */
  1531. #ifdef CK_ENVIRONMENT
  1532.     "environment",     CK_TN_ENV,  0,
  1533. #endif /* CK_ENVIRONMENT */
  1534. #ifdef IKS_OPTION
  1535.     "kermit",          CK_TN_IKS,  CM_INV,
  1536. #endif /* IKS_OPTION */
  1537. #ifdef CK_SNDLOC
  1538.     "location",        CK_TN_LOC,  0,
  1539. #endif /* CK_SNDLOC */
  1540. #ifdef CK_NAWS
  1541.     "naws",            CK_TN_NAWS, CM_INV,
  1542. #endif /* CK_NAWS */
  1543.     "newline-mode",    CK_TN_NL,   0,
  1544.     "no-encrypt-during-xfer", CK_TN_NE, CM_INV,
  1545.     "prompt-for-userid",CK_TN_PUID,0,
  1546.     "remote-echo",     CK_TN_RE,   0,
  1547. #ifdef CK_SSL
  1548.     "start-tls",       CK_TN_TLS,  CM_INV,
  1549. #endif /* CK_SSL */
  1550.     "terminal-type",   CK_TN_TT,   0,
  1551.     "wait-for-negotiations", CK_TN_WAIT, 0,
  1552. #ifdef CK_ENVIRONMENT
  1553.     "xdisplay-location",CK_TN_XD, CM_INV,
  1554. #endif /* CK_ENVIRONMENT */
  1555.     "", 0, 0
  1556. };
  1557. int ntn = (sizeof(tntab) / sizeof(struct keytab)) - 1;
  1558.  
  1559. struct keytab tnopttab[] = {
  1560. #ifdef CK_AUTHENTICATION
  1561.     "authentication",  CK_TN_AU,   0,
  1562. #else
  1563.     "authentication",  CK_TN_AU,   CM_INV,
  1564. #endif /* CK_AUTHENTICATION */
  1565.     "binary-mode",     CK_TN_BM,   0,
  1566.     "com-port-control",CK_TN_CPC,  CM_INV,
  1567.     "echo",            CK_TN_EC,   0,
  1568. #ifdef CK_ENCRYPTION
  1569.     "encryption",      CK_TN_ENC,  0,
  1570. #else
  1571.     "encryption",      CK_TN_ENC,  CM_INV,
  1572. #endif /* CK_ENCRYPTION */
  1573. #ifdef CK_FORWARD_X
  1574.     "forward_x",       CK_TN_FX,   0,
  1575. #else /* CK_FORWARD_X */
  1576.     "forward_x",       CK_TN_FX,   CM_INV,
  1577. #endif /* CK_FORWARD_X */
  1578.     "ibm-sak",         CK_TN_SAK,  CM_INV,
  1579. #ifdef IKS_OPTION
  1580.     "kermit",          CK_TN_IKS,  0,
  1581. #else
  1582.     "kermit",          CK_TN_IKS,  CM_INV,
  1583. #endif /* IKS_OPTION */
  1584.     "lflow",           CK_TN_FLW,  CM_INV,
  1585. #ifdef CK_NAWS
  1586.     "naws",            CK_TN_NAWS, 0,
  1587. #else
  1588.     "naws",            CK_TN_NAWS, CM_INV,
  1589. #endif /* CK_NAWS */
  1590. #ifdef CK_ENVIRONMENT
  1591.     "new-environment", CK_TN_ENV,  0,
  1592. #else
  1593.     "new-environment", CK_TN_ENV,  CM_INV,
  1594. #endif /* CK_ENVIRONMENT */
  1595.     "pragma-heartbeat",CK_TN_PHR,  CM_INV,
  1596.     "pragma-logon",    CK_TN_PLG,  CM_INV,
  1597.     "pragma-sspi",     CK_TN_PSP,  CM_INV,
  1598.     "sak",             CK_TN_SAK,  CM_INV,
  1599. #ifdef CK_SNDLOC
  1600.     "send-location",   CK_TN_LOC,  0,
  1601. #else
  1602.     "send-location",   CK_TN_LOC,  CM_INV,
  1603. #endif /* CK_SNDLOC */
  1604.     "sga",             CK_TN_SGA, CM_INV|CM_ABR,
  1605. #ifdef CK_SSL
  1606.     "start-tls",       CK_TN_TLS,  0,
  1607. #else
  1608.     "start-tls",       CK_TN_TLS,  CM_INV,
  1609. #endif /* CK_SSL */
  1610.     "suppress-go-aheads", CK_TN_SGA, 0,
  1611.     "terminal-type",   CK_TN_TT,   0,
  1612.     "ttype",           CK_TN_TT,   CM_INV|CM_ABR,
  1613. #ifdef CK_ENVIRONMENT
  1614.     "xdisplay-location", CK_TN_XD, 0,
  1615. #else
  1616.     "xdisplay-location", CK_TN_XD, CM_INV,
  1617. #endif /* CK_ENVIRONMENT */
  1618.     "", 0, 0
  1619. };
  1620. int ntnopt = (sizeof(tnopttab) / sizeof(struct keytab)) - 1;
  1621.  
  1622. struct keytab tnoptsw[] = {
  1623.     "/client",  CK_TN_CLIENT,   0,
  1624.     "/server",  CK_TN_SERVER,   0
  1625. };
  1626. int ntnoptsw = (sizeof(tnoptsw) / sizeof(struct keytab));
  1627. #endif /* TNCODE */
  1628.  
  1629. struct keytab ftrtab[] = {        /* Feature table */
  1630. #ifndef NOCSETS                /* 0 = we have it, 1 = we don't */
  1631. "character-sets",    0, 0,
  1632. #else
  1633. "character-sets",    1, 0,
  1634. #endif /* NOCSETS */
  1635. #ifndef NOCYRIL
  1636. "cyrillic",        0, 0,
  1637. #else
  1638. "cyrillic",        1, 0,
  1639. #endif /* NOCYRIL */
  1640.  
  1641. #ifndef NOLOGDIAL
  1642. "cx-log",               0, 0,
  1643. #else
  1644. "cx-log",               1, 0,
  1645. #endif /* NOLOGDIAL */
  1646.  
  1647. #ifndef NODEBUG
  1648. "debug",        0, 0,
  1649. #else
  1650. "debug",        1, 0,
  1651. #endif /* NODEBUG */
  1652.  
  1653. #ifndef NODIAL
  1654. "dial",            0, 0,
  1655. #else
  1656. "dial",            1, 0,
  1657. #endif /* NODIAL */
  1658.  
  1659. #ifdef DYNAMIC
  1660. "dynamic-memory",       0, 0,
  1661. #else
  1662. "dynamic-memory",       1, 0,
  1663. #endif /* DYNAMIC */
  1664.  
  1665. #ifndef NOXFER
  1666. "file-transfer",        0, 0,
  1667. #else
  1668. "file-transfer",        1, 0,
  1669. #endif /* NOXFER */
  1670.  
  1671. #ifdef XXFWD
  1672. "forward",              0, 0,
  1673. #else
  1674. "forward",              1, 0,
  1675. #endif /* XXFWD */
  1676.  
  1677. #ifdef CK_CURSES
  1678. "fullscreen-display",    0, 0,
  1679. #else
  1680. "fullscreen-display",    1, 0,
  1681. #endif /* CK_CURSES */
  1682. #ifdef GREEK
  1683. "greek",                0, 0,
  1684. #else
  1685. "greek",                1, 0,
  1686. #endif /* GREEK */
  1687. #ifdef HEBREW
  1688. "hebrew",               0, 0,
  1689. #else
  1690. "hebrew",               1, 0,
  1691. #endif /* HEBREW */
  1692. #ifndef NOHELP
  1693. "help",            0, 0,
  1694. #else
  1695. "help",            1, 0,
  1696. #endif /* NOHELP */
  1697.  
  1698. #ifndef NOIKSD
  1699. "iksd",                 0, 0,
  1700. #else
  1701. "iksd",                 1, 0,
  1702. #endif /* NOIKSD */
  1703.  
  1704. #ifndef NOSPL
  1705. "if-command",        0, 0,
  1706. #else
  1707. "if-command",        1, 0,
  1708. #endif /* NOSPL */
  1709. #ifndef NOJC
  1710. #ifdef UNIX
  1711. "job-control",        0, 0,
  1712. #else
  1713. "job-control",        1, 0,
  1714. #endif /* UNIX */
  1715. #else
  1716. "job-control",        1, 0,
  1717. #endif /* NOJC */
  1718. #ifdef KANJI
  1719. "kanji",        0, 0,
  1720. #else
  1721. "kanji",        1, 0,
  1722. #endif /* KANJI */
  1723.  
  1724. #ifndef NOXFER
  1725. "kermit",               0, 0,
  1726. #else
  1727. "kermit",               1, 0,
  1728. #endif /* NOXFER */
  1729.  
  1730. #ifdef CK_KERBEROS
  1731. "kerberos",        0, 0,
  1732. #else
  1733. "kerberos",        1, 0,
  1734. #endif /* CK_KERBEROS */
  1735.  
  1736. #ifndef NOCSETS
  1737. "latin1",        0, 0,
  1738. #else
  1739. "latin1",        1, 0,
  1740. #endif /* NOCSETS */
  1741. #ifdef LATIN2
  1742. "latin2",        0, 0,
  1743. #else
  1744. "latin2",        1, 0,
  1745. #endif /* LATIN2 */
  1746.  
  1747. #ifndef NOLOCAL
  1748. "making-connections",   0, 0,
  1749. #else
  1750. "making-connections",   1, 0,
  1751. #endif /* NOLOCAL */
  1752.  
  1753. #ifdef NETCONN
  1754. "network",        0, 0,
  1755. #else
  1756. "network",        1, 0,
  1757. #endif /* NETCONN */
  1758.  
  1759. #ifdef NT
  1760. #ifdef CK_AUTHENTICATION
  1761. "ntlm",                 1, 0,
  1762. #else /* CK_AUTHENTICATION */
  1763. "ntlm",                 0, 0,
  1764. #endif /* CK_AUTHENTICATION */
  1765. #else /* NT */
  1766. "ntlm",                 0, 0,
  1767. #endif /* NT */
  1768.  
  1769. #ifdef PIPESEND
  1770. "pipes",                0, 0,
  1771. #else
  1772. #ifdef NETCMD
  1773. "pipes",                0, 0,
  1774. #endif /* NETCMD */
  1775. #endif /* PIPESEND */
  1776. #ifndef PIPESEND
  1777. #ifndef NETCMD
  1778. "pipes",                1, 0,
  1779. #endif /* PIPESEND */
  1780. #endif /* NETCMD */
  1781.  
  1782. #ifdef NETPTY
  1783. "pty",                  0, 0,
  1784. #else
  1785. "pty",                  1, 0,
  1786. #endif /* NETPTY */
  1787.  
  1788. #ifndef NOPUSH
  1789. "push",            0, 0,
  1790. #else
  1791. "push",            1, 0,
  1792. #endif /* PUSH */
  1793.  
  1794. #ifdef CK_REDIR
  1795. "redirect",             0, 0,
  1796. #else
  1797. "redirect",             1, 0,
  1798. #endif /* CK_REDIR */
  1799.  
  1800. #ifdef CK_RTSCTS
  1801. "rts/cts",        0, 0,
  1802. #else
  1803. "rts/cts",        1, 0,
  1804. #endif /* RTS/CTS */
  1805.  
  1806. #ifndef NOSCRIPT
  1807. "script-command",    0, 0,
  1808. #else
  1809. "script-command",    1, 0,
  1810. #endif /* NOSCRIPT */
  1811. #ifndef NOSERVER
  1812. "server-mode",        0, 0,
  1813. #else
  1814. "server-mode",        1, 0,
  1815. #endif /* NOSERVER */
  1816. #ifndef NOSHOW
  1817. "show-command",        0, 0,
  1818. #else
  1819. "show-command",        1, 0,
  1820. #endif /* NOSHOW */
  1821.  
  1822. #ifdef CK_SRP
  1823. "srp",                0, 0,
  1824. #else
  1825. "srp",                1, 0,
  1826. #endif /* CK_SRP */
  1827.  
  1828. #ifdef CK_SSL
  1829. "ssl/tls",        0, 0,
  1830. #else
  1831. "ssl/tls",        1, 0,
  1832. #endif /* CK_SSL */
  1833.  
  1834. #ifndef NOXMIT
  1835. "transmit",        0, 0,
  1836. #else
  1837. "transmit",        1, 0,
  1838. #endif /* NOXMIT */
  1839.  
  1840. #ifdef UNICODE
  1841. "unicode",              0, 0,
  1842. #else
  1843. "unicode",              1, 0,
  1844. #endif /* UNICODE */
  1845.  
  1846. #ifdef CK_XYZ
  1847. "xyzmodem",        0, 0,
  1848. #else
  1849. "xyzmodem",        1, 0,
  1850. #endif /* NOXMIT */
  1851.  
  1852. "", 0, 0
  1853. };
  1854. int nftr = (sizeof(ftrtab) / sizeof(struct keytab)) - 1;
  1855.  
  1856. struct keytab desttab[] = {        /* SET DESTINATION */
  1857. #ifdef CALIBRATE
  1858.     "calibrate", DEST_N, CM_INV,
  1859. #endif /* CALIBRATE */
  1860.     "disk",    DEST_D, 0,
  1861. #ifdef CALIBRATE
  1862.     "nowhere", DEST_N, 0,
  1863. #endif /* CALIBRATE */
  1864.     "printer", DEST_P, 0,
  1865.     "screen",  DEST_S, 0
  1866. };
  1867. int ndests =  (sizeof(desttab) / sizeof(struct keytab));
  1868.  
  1869. #ifndef NOSPL        /* Used only with script programming items... */
  1870.  
  1871. #ifndef NOSERVER            /* This is just to avoid some */
  1872. #define CK_PARSDIR            /* "statement not reached" */
  1873. #else                    /* complaints... */
  1874. #ifndef NODIAL
  1875. #define CK_PARSDIR
  1876. #endif /* NODIAL */
  1877. #endif /* NOSERVER */
  1878.  
  1879. /*
  1880.   cx == 0 means dial directory
  1881.   cx == 1 means network directory
  1882.   cx == 2 means a directory path list
  1883. */
  1884. static int
  1885. parsdir(cx) int cx; {
  1886.     int i, x, y, dd;            /* Workers */
  1887.     int nxdir;
  1888.     char *s;
  1889.     char ** xdir;
  1890.     char *pp[MAXGETPATH];        /* Temporary name pointers */
  1891. #ifdef ZFNQFP
  1892.     struct zfnfp * fnp;
  1893. #ifdef OS2
  1894.     char * env;
  1895.     char dirpath[4096];
  1896. #else /* OS2 */
  1897.     char dirpath[1024];            /* For fully qualified filenames */
  1898. #endif /* OS2 */
  1899. #endif /* ZFNQFP */
  1900.  
  1901.     int max = 0;            /* Maximum number of things to parse */
  1902.     char c;
  1903.  
  1904. #ifndef NODIAL
  1905.     if (cx == 0) {            /* Dialing */
  1906.     nxdir = ndialdir;
  1907.     xdir = dialdir;
  1908.     max = MAXDDIR;
  1909.     } else
  1910. #ifdef NETCONN
  1911.     if (cx == 1) {            /* Network */
  1912.     nxdir = nnetdir;
  1913.     xdir = netdir;
  1914.     max = MAXDDIR;
  1915.     } else
  1916. #endif /* NETCONN */
  1917. #endif /* NODIAL */
  1918. #ifndef NOSERVER
  1919.     if (cx == 2) {            /* GET path */
  1920.     nxdir = ngetpath;
  1921.     xdir = getpath;
  1922.     max = MAXGETPATH;
  1923.     } else                /* Called with invalid function code */
  1924. #endif /* NOSERVER */
  1925.       return(-2);
  1926.  
  1927. #ifdef CK_PARSDIR
  1928.     dd = 0;                /* Temporary name counter */
  1929.     while (1) {
  1930.     if (cx != 2) {            /* Dialing or Network Directory */
  1931. #ifdef OS2
  1932.         int len;
  1933. #ifdef NT
  1934.         env = getenv("K95PHONES");
  1935. #else /* NT */
  1936.         env = getenv("K2PHONES");
  1937. #endif /* NT */
  1938.         if (!env)
  1939.           env = getenv("K95PHONES");
  1940.             if (!env)
  1941.           env = "";
  1942.  
  1943.             dirpath[0] = '\0';
  1944.             len = strlen(env) + 2*strlen(startupdir) + 2*strlen(inidir)
  1945.                 + 2*strlen(zhome()) + 2*strlen(exedir) + 4*strlen("PHONES/")
  1946.                 + 12;
  1947.             if (len < 4096)
  1948.           sprintf(dirpath,"%s%s%s;%s%s;%s;%s%s;%s;%s%s",
  1949.             /* Semicolon-separated path list */
  1950.             env,
  1951.             (env[0] && env[strlen(env)-1] == ';') ? "" : ";",
  1952.             startupdir,
  1953.             startupdir, "PHONES/",
  1954.             inidir,
  1955.             inidir, "PHONES/",
  1956.                     zhome(),
  1957.                     zhome(), "PHONES/",
  1958.             exedir,
  1959.             exedir, "PHONES/"
  1960.             );
  1961. #else
  1962. #ifdef UNIX
  1963.         y = 1024;
  1964.         s = dirpath;
  1965.         zzstring("\\v(home)",&s,&y);
  1966. #endif /* UNIX */
  1967. #endif /* OS2 */
  1968.         y = cmifip(
  1969.           "Names of one or more directory files, separated by spaces",
  1970.                "",&s,&x,0,
  1971. #ifdef OS2ORUNIX
  1972.                dirpath,
  1973. #else
  1974.                NULL,
  1975. #endif /* OS2ORUNIX */
  1976.                xxstring
  1977.                );
  1978.     } else {            /* List of directory names */
  1979.         x = 0;
  1980.         y = cmdir("Directory name","",&s,xxstring);
  1981.     }
  1982.     if (y < 0) {
  1983.         if (y == -3) {        /* EOL or user typed <CR> */
  1984.         if ((y = cmcfm()) < 0) return(y);
  1985.         for (i = 0; i < max; i++) { /* Clear these */
  1986.             if (i < nxdir && xdir[i]) {
  1987.             free(xdir[i]);
  1988.             }
  1989.             xdir[i] = (i < dd) ? pp[i] : NULL;
  1990.         }
  1991. #ifndef NODIAL
  1992.         if (cx == 0)
  1993.           ndialdir = dd;
  1994. #ifdef NETCONN
  1995.         if (cx == 1)
  1996.           nnetdir = dd;
  1997. #endif /* NETCONN */
  1998. #endif /* NODIAL */
  1999. #ifndef NOSERVER
  2000.         if (cx == 2)
  2001.           ngetpath = dd;
  2002. #endif /* NOSERVER */
  2003.         return(success = 1);
  2004.  
  2005.         } else {            /* Parse error */
  2006.         for (i = 0; i < dd; i++) {  /* Free temp storage */
  2007.             if (pp[i]) free(pp[i]); /* but don't change */
  2008.             pp[i] = NULL;           /* anything else */
  2009.         }
  2010.         return(y);
  2011.         }
  2012.     }
  2013.     if (x) {
  2014.         printf("?Wildcards not allowed\n");
  2015.         return(-9);
  2016.     }
  2017. #ifdef CK_TMPDIR
  2018.     if (cx == 2 && !isdir(s)) {
  2019.         printf("?Not a directory - %s\n", s);
  2020.         return(-9);
  2021.     }
  2022. #endif /* CK_TMPDIR */
  2023.  
  2024. #ifdef ZFNQFP
  2025.     /* Get fully qualified pathname */
  2026.     if (fnp = zfnqfp(s,TMPBUFSIZ - 1,tmpbuf)) {
  2027.         if (fnp->fpath)
  2028.           if ((int) strlen(fnp->fpath) > 0)
  2029.         s = fnp->fpath;
  2030.     }
  2031. #endif /* ZFNQFP */
  2032.     c = NUL;
  2033.     x = strlen(s);
  2034.     if (x > 0)            /* Get last char */
  2035.       c = s[x-1];
  2036.     debug(F000,"parsdir s",s,c);
  2037.     if ((pp[dd] = malloc(strlen(s)+2)) == NULL) {
  2038.         printf("?Internal error - malloc\n");
  2039.         for (i = 0; i < dd; i++) {  /* Free temp storage */
  2040.         if (pp[i]) free(pp[i]);
  2041.         pp[i] = NULL;
  2042.         }
  2043.         return(-9);
  2044.     } else {            /* Have storage for name */
  2045.         strcpy(pp[dd],s);        /* Copy string into new storage */
  2046.         debug(F111,"parsdir pp[dd] 1",pp[dd],dd);
  2047. #ifndef NOXFER
  2048.         if (cx == 2) {        /* If we are parsing directories */
  2049.         char dirsep[2];
  2050.         extern int myindex;    /* Append directory separator if */
  2051.         extern struct sysdata sysidlist[]; /* it is missing...   */
  2052.         debug(F101,"parsdir myindex","",myindex);
  2053.         if (myindex > -1)
  2054.           if (sysidlist[myindex].sid_unixlike)
  2055.             if (c != sysidlist[myindex].sid_dirsep) {
  2056.             dirsep[0] = sysidlist[myindex].sid_dirsep;
  2057.             dirsep[1] = NUL;
  2058.             strcat(pp[dd], (char *) dirsep);
  2059.             }
  2060.         }
  2061. #endif /* NOXFER */
  2062.         debug(F111,"parsdir pp[dd] 2",pp[dd],dd);
  2063.         if (++dd > max) {
  2064.         printf("?Too many directories - %d max\n", max);
  2065.         for (i = 0; i < dd; i++) {  /* Free temp storage */
  2066.             if (pp[i]) free(pp[i]);
  2067.             pp[i] = NULL;
  2068.         }
  2069.         }
  2070.     }
  2071.     }
  2072. #endif /* CK_PARSDIR */
  2073. }
  2074. #endif /* NOSPL */
  2075.  
  2076. #ifndef NOSERVER
  2077. static int
  2078. cklogin() {
  2079.     int x;
  2080.     char * s;
  2081.     char username[LOGINLEN+1];
  2082.     char password[LOGINLEN+1];
  2083.     char account[LOGINLEN+1];
  2084.     extern char * x_user, * x_passwd, * x_acct;
  2085.     extern int x_login, x_logged;
  2086.  
  2087.     username[0] = NUL;
  2088.     password[0] = NUL;
  2089.     account[0]  = NUL;
  2090.  
  2091.     x = cmfld("username", "", &s, xxstring);
  2092.     if (x != -3) {
  2093.     if (x < 0)
  2094.       return(x);
  2095.     if ((int)strlen(s) > LOGINLEN) {
  2096.         printf("\"%s\" - too long, %d max\n", s, LOGINLEN);
  2097.         return(-9);
  2098.     }
  2099.     strcpy(username,s);
  2100.     x = cmfld("password", "", &s, xxstring);
  2101.     if (x != -3) {
  2102.         if (x < 0)
  2103.           return(x);
  2104.         if ((int)strlen(s) > LOGINLEN) {
  2105.         printf("\"%s\" - too long, %d max\n", s, LOGINLEN);
  2106.         return(-9);
  2107.         }
  2108.         strcpy(password,s);
  2109.         x = cmfld("account", "", &s, xxstring);
  2110.         if (x != -3) {
  2111.         if (x < 0)
  2112.           return(x);
  2113.         if ((int)strlen(s) > LOGINLEN) {
  2114.             printf("\"%s\" - too long, %d max\n", s, LOGINLEN);
  2115.             return(-9);
  2116.         }
  2117.         strcpy(account,s);
  2118.         if ((x = cmcfm()) < 0)
  2119.           return(x);
  2120.         }
  2121.     }
  2122.     }
  2123.     makestr(&x_user,username);
  2124.     makestr(&x_passwd,password);
  2125.     makestr(&x_acct,account);
  2126.     x_login = (x_user) ? 1 : 0;
  2127.     x_logged = 0;
  2128.     return(1);
  2129. }
  2130. #endif /* NOSERVER */
  2131.  
  2132. #ifndef NOLOCAL
  2133. static int
  2134. setdcd() {
  2135.     int x, y, z = 0;
  2136.     if ((y = cmkey(crrtab,ncrr,"","auto",xxstring)) < 0) return(y);
  2137.     if (y == CAR_ON) {
  2138.     x = cmnum("Carrier wait timeout, seconds","0",10,&z,xxstring);
  2139.     if (x < 0) return(x);
  2140.     }
  2141.     if ((x = cmcfm()) < 0) return(x);
  2142.     carrier = ttscarr(y);
  2143.     cdtimo = z;
  2144.     return(1);
  2145. }
  2146. #endif /* NOLOCAL */
  2147.  
  2148. extern struct keytab yesno[];
  2149. extern int nyesno;
  2150.  
  2151. static struct keytab qyesno[] = {    /* Yes/No/Quit keyword table */
  2152.     "no",    0, 0,
  2153.     "ok",    1, 0,
  2154.     "quit",  2, 0,
  2155.     "yes",   1, 0
  2156. };
  2157. static int nqyesno = (sizeof(qyesno) / sizeof(struct keytab));
  2158.  
  2159. /* Ask question, get yes/no answer */
  2160.  
  2161. int
  2162. getyesno(msg, quit) char * msg; int quit; {
  2163. #ifdef CK_RECALL
  2164.     int sv_recall;            /* For turning off command recall */
  2165.     extern int on_recall;        /* around Password prompting */
  2166. #endif /* CK_RECALL */
  2167.     int y, z;
  2168.  
  2169. #ifdef OS2
  2170.     extern int vmode;
  2171.     int vmode_sav = vmode;
  2172.  
  2173. #ifdef COMMENT
  2174.     if (win95_popup
  2175. #ifdef IKSD
  2176.     && !inserver
  2177. #endif /* IKSD */
  2178.     )
  2179.       return(popup_readyesno(vmode,prmpt,quit));
  2180. #endif /* COMMENT */
  2181.     if (vmode == VTERM) {
  2182.         vmode = VCMD;
  2183.         VscrnIsDirty(VTERM);
  2184.         VscrnIsDirty(VCMD);
  2185.     }
  2186. #endif /* OS2 */
  2187. #ifdef VMS
  2188. /*
  2189.   In VMS, whenever a TAKE file or macro is active, we restore the
  2190.   original console modes so Ctrl-C/Ctrl-Y can work.  But here we
  2191.   go interactive again, so we have to temporarily put them back.
  2192. */
  2193.     if (!cmdsrc())
  2194.       concb((char)escape);
  2195. #endif /* VMS */
  2196.  
  2197. #ifdef CK_RECALL
  2198.     sv_recall = on_recall;        /* Save and turn off command recall */
  2199.     on_recall = 0;
  2200. #endif /* CK_RECALL */
  2201.     cmsavp(psave,PROMPTL);        /* Save old prompt */
  2202.     cmsetp(msg);            /* Make new prompt */
  2203.     z = 0;                /* Initialize answer to No. */
  2204.     cmini(ckxech);            /* Initialize parser. */
  2205.     do {
  2206.     prompt(NULL);            /* Issue prompt. */
  2207.     if (quit)
  2208.       y = cmkey(qyesno,nqyesno,"","",NULL); /* Get Yes or No */
  2209.     else
  2210.       y = cmkey(yesno,nyesno,"","",NULL); /* Get Yes or No */
  2211.     if (y < 0) {
  2212.         if (y == -4) {        /* EOF */
  2213.         z = y;
  2214.         break;
  2215.         } else if (y == -3)        /* No answer? */
  2216.           printf(" Please respond Yes or No%s\n", quit ? " or Quit" : "");
  2217.         cmini(ckxech);
  2218.     } else {
  2219.         z = y;            /* Save answer */
  2220.         y = cmcfm();        /* Get confirmation */
  2221.     }
  2222.     } while (y < 0);            /* Continue till done */
  2223.     cmsetp(psave);            /* Restore real prompt */
  2224. #ifdef CK_RECALL
  2225.     on_recall = sv_recall;        /* Restore command recall */
  2226. #endif /* CK_RECALL */
  2227. #ifdef VMS
  2228.     if (cmdlvl > 0)            /* In VMS and not at top level, */
  2229.       conres();                /*  restore console again. */
  2230. #endif /* VMS */
  2231. #ifdef OS2
  2232.     if (vmode != vmode_sav) {
  2233.         vmode = VTERM;
  2234.         VscrnIsDirty(VCMD);
  2235.         VscrnIsDirty(VTERM);
  2236.     }
  2237. #endif /* OS2 */
  2238.     return(z);
  2239. }
  2240.  
  2241. int                    /* CHECK command */
  2242. dochk() {
  2243.     int x, y;
  2244.     if ((y = cmkey(ftrtab,nftr,"","",xxstring)) < 0)
  2245.       return(y);
  2246.     strcpy(line,atmbuf);
  2247.     if ((y = cmcfm()) < 0)
  2248.       return(y);
  2249. #ifndef NOPUSH
  2250.     if (!ckstrcmp(line,"push",(int)strlen(line),0)) {
  2251.     if (msgflg)            /* If at top level... */
  2252.       printf(" push%s available\n", nopush ? " not" : "");
  2253.     else if (nopush && !backgrd)
  2254.       printf(" CHECK: push not available\n");
  2255.     return(success = 1 - nopush);
  2256.     }
  2257. #endif /* NOPUSH */
  2258. #ifdef PIPESEND
  2259.     if (!ckstrcmp(line,"pipes",(int)strlen(line),0)) {
  2260.     if (msgflg)            /* If at top level... */
  2261.       printf(" pipes%s available\n",
  2262.          (nopush || protocol != PROTO_K) ? " not" : "");
  2263.     else if ((nopush || protocol != PROTO_K) && !backgrd)
  2264.       printf(" CHECK: pipes not available\n");
  2265.     return(success = 1 - nopush);
  2266.     }
  2267. #endif /* PIPESEND */
  2268.     y = lookup(ftrtab,line,nftr,&x);    /* Look it up */
  2269.     debug(F111,"dochk",ftrtab[x].kwd,y);
  2270.     if (msgflg)                /* If at top level... */
  2271.       printf(" %s%s available\n", ftrtab[x].kwd, y ? " not" : "");
  2272.     else if (y && !backgrd)
  2273.       printf(" CHECK: %s not available\n", ftrtab[x].kwd);
  2274.     return(success = 1 - y);
  2275. }
  2276.  
  2277. #ifndef NOLOCAL
  2278. #ifdef CKLOGDIAL
  2279.  
  2280. /* Connection log and elapsed-time reporting */
  2281.  
  2282. extern char cxlogbuf[];            /* Log record buffer */
  2283. extern char diafil[];            /* Log file name */
  2284. extern int dialog, cx_active;        /* Flags */
  2285. static int cx_prev = 0L;        /* Elapsed time of previous session */
  2286.  
  2287. VOID
  2288. dologend() {                /* Write record to connection log */
  2289.     long d1, d2, t1, t2;
  2290.     char buf[32], * p;
  2291.  
  2292.     debug(F101,"dologend dialog","",dialog);
  2293.     debug(F101,"dologend cxlogbuf[0]","",cxlogbuf[0]);
  2294. #ifdef CKSYSLOG
  2295.     debug(F101,"dologend ckxlogging","",ckxlogging);
  2296. #endif /* CKSYSLOG */
  2297.  
  2298.     if (!cx_active || !cxlogbuf[0])    /* No active record */
  2299.       return;
  2300.  
  2301.     cx_active = 0;            /* Record is not active */
  2302.     debug(F110,"dologend cxlogbuf 1",cxlogbuf,0);
  2303.  
  2304.     d1 = mjd((char *)cxlogbuf);        /* Get start date of this session */
  2305.     ckstrncpy(buf,ckdate(),31);        /* Get current date */
  2306.     d2 = mjd(buf);            /* Convert them to mjds */
  2307.     p = cxlogbuf;            /* Get start time */
  2308.     p[11] = NUL;
  2309.     p[14] = NUL;            /* Convert to seconds */
  2310.     t1 = atol(p+9) * 3600L + atol(p+12) * 60L + atol(p+15);
  2311.     p[11] = ':';
  2312.     p[14] = ':';
  2313.     p = buf;                /* Get end time */
  2314.     p[11] = NUL;
  2315.     p[14] = NUL;
  2316.     t2 = atol(p+9) * 3600L + atol(p+12) * 60L + atol(p+15);
  2317.     t2 = ((d2 - d1) * 86400L) + (t2 - t1); /* Compute elapsed time */
  2318.     debug(F101,"dologend t2","",t2);
  2319.     if (t2 > -1L) {
  2320.     cx_prev = t2;
  2321.     p = hhmmss(t2);
  2322.     debug(F110,"dologend hhmmss",p,0);
  2323.     strncat(cxlogbuf,"E=",CXLOGBUFL); /* Append to log record */
  2324.     strncat(cxlogbuf,p,CXLOGBUFL);
  2325.     debug(F110,"dologend cxlogbuf 2",cxlogbuf,0);
  2326.     } else
  2327.       cx_prev = 0L;
  2328.     debug(F101,"dologend cx_prev","",cx_prev);
  2329.     if (dialog) {            /* If logging */
  2330.     int x;
  2331.     x = diaopn(diafil,1,1);        /* Open log in append mode */
  2332.     debug(F101,"dologend diaopn","",x);
  2333.     x = zsoutl(ZDIFIL,cxlogbuf);    /* Write the record */
  2334.     debug(F101,"dologend zsoutl","",x);
  2335.     x = zclose(ZDIFIL);        /* Close the log */
  2336.     debug(F101,"dologend zclose","",x);
  2337.     }
  2338. #ifdef CKSYSLOG
  2339.     debug(F101,"dologend ckxlogging","",ckxlogging);
  2340.     if (ckxlogging) {
  2341.     int x;
  2342.     x = ckindex("T=DIAL",cxlogbuf,0,0,1);
  2343.     debug(F111,"dologend ckxsyslog",cxlogbuf,ckxsyslog);
  2344.     debug(F111,"dologend ckindex","T=DIAL",x);
  2345.         if (x > 0) {
  2346.         if (ckxsyslog >= SYSLG_DI) {
  2347.         debug(F110,"dologend syslog",cxlogbuf+18,0);
  2348.         cksyslog(SYSLG_DI,1,"CONNECTION",(char *)(cxlogbuf+18),"");
  2349.         } else if (ckxsyslog >= SYSLG_AC) {
  2350.         debug(F110,"dologend syslog",cxlogbuf+18,0);
  2351.         cksyslog(SYSLG_AC,1,"CONNECTION",(char *)(cxlogbuf+18),"");
  2352.         }
  2353.         }
  2354.     }
  2355. #endif /* CKSYSLOG */
  2356. }
  2357.  
  2358. /*  D O L O G S H O W  --  Show session/connection info  */
  2359.  
  2360. /* Call with fc == 1 to show, fc == 0 to only calculate. */
  2361. /* Returns session elapsed time in seconds. */
  2362. /* If no session active, returns elapsed time of previous session, if any, */
  2363. /* otherwise 0 */
  2364.  
  2365. long
  2366. dologshow(fc) int fc; {            /* SHOW (current) CONNECTION */
  2367.     long d1, d2, t1, t2 = 0;
  2368.     char c, buf1[32], buf2[32], * info[32], * p, * s;
  2369.     char xbuf[CXLOGBUFL+1];
  2370.     int i, x = 0, z;
  2371.  
  2372.     if (!cxlogbuf[0]) {
  2373.     if (fc) {
  2374.         if (didsetlin)
  2375.           printf(" No record.\n");
  2376.         else
  2377.           printf(" No connection.\n");
  2378.     }
  2379.     return(cx_prev);
  2380.     }
  2381.     debug(F101,"dologshow local","",local);
  2382.     debug(F101,"dologshow cx_active","",cx_active);
  2383.  
  2384.     if (local)
  2385.       z = ttchk();            /* See if we have an open connection */
  2386.     else
  2387.       z = cx_active ? 1 : -2;
  2388.     if (z < 0L) {
  2389.     if (!fc)
  2390.       return(cx_prev);
  2391.     else
  2392.       t2 = cx_prev;
  2393.     }
  2394.     debug(F101,"dologshow ttchk","",z);
  2395.     debug(F101,"dologshow cx_prev","",cx_prev);
  2396.  
  2397.     ckstrncpy(buf1,cxlogbuf,17);    /* Copy of just the timestamp */
  2398.     buf1[17] = NUL;            /* Terminate it */
  2399.     ckstrncpy(xbuf,cxlogbuf+18,CXLOGBUFL); /* Copy that can be poked */
  2400.     xwords(xbuf,31,info,1);        /* Break up into fields */
  2401.     d1 = mjd(buf1);            /* Convert start time to MJD */
  2402.     ckstrncpy(buf2,ckdate(),31);    /* Current date */
  2403.     d2 = mjd(buf2);            /* Convert to MJD */
  2404.     p = buf1;                /* Point to start time */
  2405.     p[11] = NUL;
  2406.     p[14] = NUL;            /* Convert to seconds */
  2407.     t1 = atol(p+9) * 3600L + atol(p+12) * 60L + atol(p+15);
  2408.     p[11] = ':';
  2409.     p[14] = ':';
  2410.     p = buf2;                /* Ditto for current time */
  2411.     p[11] = NUL;
  2412.     p[14] = NUL;
  2413.     if (z > -1L) {
  2414.     t2 = atol(p+9) * 3600L + atol(p+12) * 60L + atol(p+15);
  2415.     t2 = ((d2 - d1) * 86400L) + (t2 - t1); /* Elapsed time so far */
  2416.     }
  2417.     if (fc) {
  2418.     p = NULL;
  2419.     if (t2 > -1L)            /* Convert seconds to hh:mm:ss */
  2420.       p = hhmmss(t2);
  2421.     if (z > -1)
  2422.       s = "Active";
  2423.     else if (z == -2)
  2424.       s = "Closed";
  2425.     else
  2426.       s = "Unknown";
  2427.     printf("\n");            /* Show results */
  2428.     printf(" Status:       %s\n",s);
  2429.     printf(" Opened:       %s\n",buf1);
  2430.     printf(" User:         %s\n",info[1] ? info[1] : "");
  2431.     printf(" PID:          %s\n",info[2] ? info[2] : "");
  2432.     for (i = 3; info[i]; i++) {
  2433.         c = info[i][0];
  2434.         s = (info[i]) ? info[i]+2 : "";
  2435.         switch (c) {
  2436.           case 'T': printf(" Type:         %s\n", s); break;
  2437.           case 'N': printf(" To:           %s\n", s); break;
  2438.           case 'H': printf(" From:         %s\n", s); break;
  2439.           case 'D': printf(" Device:       %s\n", s); break;
  2440.           case 'O': printf(" Origin:       %s\n", s); break;
  2441.           case 'E': break;
  2442.           default:  printf(" %s\n",info[i] ? info[i] : "");
  2443.         }
  2444.     }
  2445.     if (z < 0L)
  2446.       printf(" Elapsed time: %s\n", hhmmss(t2));
  2447.     else
  2448.       printf(" Elapsed time: %s\n", p ? p : "(unknown)");
  2449.     x = 0;
  2450. #ifdef NETCONN
  2451. #ifdef CK_ENCRYPTION
  2452.     if (ck_tn_encrypting() && ck_tn_decrypting()) x++;
  2453. #endif /* CK_ENCRYPTION */
  2454. #ifdef CK_SSL
  2455.     if (tls_active_flag || ssl_active_flag) x++;
  2456. #endif /* CK_SSL */
  2457. #ifdef RLOGCODE
  2458. #ifdef CK_KERBEROS
  2459. #ifdef CK_ENCRYPTION
  2460.     if (ttnproto == NP_EK4LOGIN || ttnproto == NP_EK5LOGIN) x++;
  2461. #endif /* CK_ENCRYPTION */
  2462. #endif /* CK_KERBEROS */
  2463. #endif /* RLOGCODE */
  2464. #endif /* NETCONN */
  2465.     printf(" Encrypted:    %s\n", x ? "Yes" : "No");
  2466.     printf(" Log:          %s\n", dialog ? diafil : "(none)");
  2467.     printf("\n");
  2468.     }
  2469.     return(t2 > -1L ? t2 : 0L);
  2470. }
  2471.  
  2472. VOID
  2473. dologline() {
  2474.     char * p;
  2475.     int n, m = 0;
  2476.  
  2477.     dologend();                /* Previous session not closed out? */
  2478.     cx_active = 1;            /* Record is active */
  2479.     cx_prev = 0L;
  2480.     p = ckdate();            /* Get timestamp */
  2481.     n = ckstrncpy(cxlogbuf,p,CXLOGBUFL-1); /* Start record off with it */
  2482.     m = strlen(uidbuf) + strlen(myhost) + strlen(ttname) + 32;
  2483.     if (n+m < CXLOGBUFL-1) {        /* Add serial device info */
  2484.     p = cxlogbuf+n;
  2485.     sprintf(p," %s %s T=SERIAL H=%s D=%s ",
  2486.         uidbuf,
  2487.         ckgetpid(),
  2488.         myhost,
  2489.         ttname
  2490.         );
  2491.     } else
  2492.       strcpy(cxlogbuf,"LOGLINE BUFFER OVERFLOW");
  2493.     debug(F110,"dologline",cxlogbuf,0);
  2494. }
  2495.  
  2496. #ifdef NETCONN
  2497. VOID
  2498. dolognet() {
  2499.     char * p, * s = "NET";
  2500.     int n, m;
  2501.  
  2502.     dologend();                /* Previous session not closed out? */
  2503.     cx_prev = 0L;
  2504.     cx_active = 1;            /* Record is active */
  2505.     p = ckdate();
  2506.     n = ckstrncpy(cxlogbuf,p,CXLOGBUFL);
  2507. #ifdef TCPSOCKET
  2508.     if (nettype == NET_TCPB || nettype == NET_TCPA)
  2509.       s = "TCP";
  2510. #endif /* TCPSOCKET */
  2511. #ifdef ANYX25
  2512.     if (nettype == NET_SX25 || nettype == NET_VX25 || nettype == NET_IX25)
  2513.       s = "X25";
  2514. #endif /* ANYX25 */
  2515. #ifdef DECNET
  2516.     if (nettype == NET_DEC)
  2517.       s = "DECNET";
  2518. #endif /* DECNET */
  2519. #ifdef SUPERLAT
  2520.     if (nettype == NET_SLAT)
  2521.       s = "SUPERLAT";
  2522. #endif /* SUPERLAT */
  2523. #ifdef CK_NETBIOS
  2524.     if (nettype == NET_BIOS)
  2525.       s = "NETBIOS";
  2526. #endif /* CK_NETBIOS */
  2527.  
  2528.     m = strlen(uidbuf) + strlen(myhost) + strlen(ttname) + strlen(s) + 32;
  2529.     if (n+m < CXLOGBUFL-1) {
  2530.     p = cxlogbuf+n;
  2531.     sprintf(p," %s %s T=%s N=%s H=%s ",
  2532.         uidbuf,
  2533.         ckgetpid(),
  2534.         s,
  2535.         ttname,
  2536.         myhost
  2537.         );
  2538.     } else
  2539.       strcpy(cxlogbuf,"LOGNET BUFFER OVERFLOW");
  2540.     debug(F110,"dolognet cxlogbuf",cxlogbuf,0);
  2541. }
  2542. #endif /* NETCONN */
  2543. #endif /* CKLOGDIAL */
  2544.  
  2545. #ifndef NODIAL
  2546. /*
  2547.   Parse a DIAL-related string, stripping enclosing braces, if any.
  2548. */
  2549. static int
  2550. dialstr(p,msg) char **p; char *msg; {
  2551.     int x;
  2552.     char *s;
  2553.  
  2554.     if ((x = cmtxt(msg, "", &s, xxstring)) < 0)
  2555.       return(x);
  2556.     s = brstrip(s);            /* Strip braces around. */
  2557.     makestr(p,s);
  2558.     debug(F110,"dialstr",s,0);
  2559.     return(success = 1);
  2560. }
  2561.  
  2562. VOID
  2563. initmdm(x) int x; {
  2564.     MDMINF * p;
  2565.     int m;
  2566.  
  2567.     mdmtyp = x;                /* Set global modem type */
  2568.     debug(F101,"initmdm mdmtyp","",mdmtyp);
  2569.     debug(F101,"initmdm usermdm","",usermdm);
  2570.     if (x < 1) return;
  2571.  
  2572.     m = usermdm ? usermdm : mdmtyp;
  2573.  
  2574.     p = modemp[m];            /* Point to modem info struct, and */
  2575.     debug(F101,"initmdm p","",p);
  2576.     if (p) {
  2577.     dialec = p->capas & CKD_EC;    /* set DIAL ERROR-CORRECTION, */
  2578.     dialdc = p->capas & CKD_DC;    /* DIAL DATA-COMPRESSION, and */
  2579.     mdmspd = p->capas & CKD_SB ? 0 : 1; /* DIAL SPEED-MATCHING from it. */
  2580.     dialfc = FLO_AUTO;            /* Modem's local flow control.. */
  2581.     dialmax   = p->max_speed;
  2582.     dialcapas = p->capas;
  2583.     dialesc   = p->esc_char;
  2584.     } else if (mdmtyp > 0) {
  2585.     printf("WARNING: modem info for \"%s\" not filled in yet\n",
  2586.            gmdmtyp()
  2587.            );
  2588.     }
  2589.  
  2590. /* Reset or set the SET DIAL STRING items ... */
  2591.  
  2592.     if (usermdm && p) {    /* USER-DEFINED: copy info from specified template */
  2593.  
  2594.     makestr(&dialini,p->wake_str);
  2595.     makestr(&dialmstr,p->dmode_str);
  2596.     makestr(&dialmprmt,p->dmode_prompt);
  2597.     makestr(&dialcmd,p->dial_str);
  2598.     makestr(&dialdcon,p->dc_on_str);
  2599.     makestr(&dialdcoff,p->dc_off_str);
  2600.     makestr(&dialecon,p->ec_on_str);
  2601.     makestr(&dialecoff,p->ec_off_str);
  2602.     makestr(&dialhcmd,p->hup_str);
  2603.     makestr(&dialhwfc,p->hwfc_str);
  2604.     makestr(&dialswfc,p->swfc_str);
  2605.     makestr(&dialnofc,p->nofc_str);
  2606.     makestr(&dialtone,p->tone);
  2607.     makestr(&dialpulse,p->pulse);
  2608.     makestr(&dialname,"This space available (use SET MODEM NAME)");
  2609.  
  2610.     } else {            /* Not user-defined, so wipe out overrides */
  2611.  
  2612.     if (dialini)   free(dialini);   dialini =   NULL; /* Init-string */
  2613.     if (dialmstr)  free(dialmstr);  dialmstr =  NULL; /* Dial-mode-str */
  2614.     if (dialmprmt) free(dialmprmt); dialmprmt = NULL; /* Dial-mode-pro */
  2615.     if (dialcmd)   free(dialcmd);   dialcmd =   NULL; /* Dial-command  */
  2616.     if (dialdcon)  free(dialdcon);  dialdcon =  NULL; /* DC ON command */
  2617.     if (dialdcoff) free(dialdcoff); dialdcoff = NULL; /* DC OFF command */
  2618.     if (dialecon)  free(dialecon);  dialecon =  NULL; /* EC ON command */
  2619.     if (dialecoff) free(dialecoff); dialecoff = NULL; /* EC OFF command */
  2620.     if (dialhcmd)  free(dialhcmd);  dialhcmd =  NULL; /* Hangup command */
  2621.     if (dialhwfc)  free(dialhwfc);  dialhwfc =  NULL; /* Flow control... */
  2622.     if (dialswfc)  free(dialswfc);  dialswfc =  NULL;
  2623.     if (dialnofc)  free(dialnofc);  dialnofc =  NULL;
  2624.     if (dialtone)  free(dialtone);  dialtone =  NULL; /* Dialing method */
  2625.     if (dialpulse) free(dialpulse); dialpulse = NULL;
  2626.     if (dialname)  free(dialname);  dialname =  NULL; /* Modem name */
  2627.     }
  2628.     if (autoflow)            /* Maybe change flow control */
  2629.       setflow();
  2630.  
  2631. #ifndef MINIDIAL
  2632. #ifdef OLDTBCODE
  2633.     tbmodel = 0;           /* If it's a Telebit, we don't know the model yet */
  2634. #endif /* OLDTBCODE */
  2635. #endif /* MINIDIAL */
  2636. }
  2637.  
  2638. int
  2639. setmodem() {                /* SET MODEM */
  2640.  
  2641.     int x, y, z;
  2642.     long zz;
  2643.     struct FDB k1, k2;
  2644.  
  2645.     cmfdbi(&k1,_CMKEY,
  2646.        "Modem parameter","","",nsetmdm, 0, xxstring, setmdm, &k2);
  2647.     cmfdbi(&k2,_CMKEY,"","","",nmdm,0,xxstring,mdmtab,NULL);
  2648.     x = cmfdb(&k1);
  2649.     if (x < 0) {            /* Error */
  2650.     if (x == -2 || x == -9)
  2651.       printf("?No keywords match: \"%s\"\n",atmbuf);
  2652.     return(x);
  2653.     }
  2654.     y = cmresult.nresult;        /* Keyword value */
  2655.     if (cmresult.fdbaddr == &k2) {    /* Modem-type keyword table */
  2656.     if ((x = cmcfm()) < 0)
  2657.       return(x);
  2658.     usermdm = 0;
  2659.     initmdm(cmresult.nresult);    /* Set the modem type. */
  2660.     return(success = 1);        /* Done */
  2661.     }
  2662.     switch (cmresult.nresult) {        /* SET MODEM keyword table. */
  2663. #ifdef MDMHUP
  2664.       case XYDMHU:            /* DIAL MODEM-HANGUP */
  2665.     if ((y = cmkey(mdmhang,3,"how to hang up modem",
  2666.                "modem-command", xxstring)) < 0)
  2667.       return(y);
  2668.     if ((x = cmcfm()) < 0)
  2669.       return(x);
  2670.     dialmhu = y;
  2671.     return(success = 1);
  2672. #endif /* MDMHUP */
  2673.  
  2674.       case XYDCAP:
  2675.     zz = 0L;
  2676.     y = 0;
  2677.     while (y != -3) {
  2678.         if ((y = cmkey(mdmcap,nmdmcap,
  2679.                "capability of modem", "", xxstring)) < 0) {
  2680.         if (y == -3)
  2681.           break;
  2682.         else
  2683.           return(y);
  2684.         }
  2685.         zz |= y;
  2686.     }
  2687.     if ((x = cmcfm()) < 0)
  2688.       return(x);
  2689.     dialcapas = zz;
  2690.     debug(F101,"setmodem autoflow","",autoflow);
  2691.     debug(F101,"setmodem flow 1","",flow);
  2692.     if (autoflow)            /* Maybe change flow control */
  2693.       setflow();
  2694.     debug(F101,"setmodem flow 2","",flow);
  2695.     mdmspd = zz & CKD_SB ? 0 : 1;    /* Set MODEM SPEED-MATCHING from it. */
  2696.     return(success = 1);
  2697.  
  2698.       case XYDMAX:
  2699.     if ((x = cmkey(spdtab,nspd,line,"",xxstring)) < 0) {
  2700.         if (x == -3) printf("?value required\n");
  2701.         return(x);
  2702.     }
  2703.     if ((y = cmcfm()) < 0) return(y);
  2704.     dialmax = (long) x * 10L;
  2705.     if (dialmax == 70) dialmax = 75;
  2706.     return(success = 1);
  2707.  
  2708.       case XYDSTR:            /* These moved from SET DIAL */
  2709.       case XYDDC:
  2710.       case XYDEC:
  2711.       case XYDESC:
  2712.       case XYDFC:
  2713.       case XYDKSP:
  2714.       case XYDSPD:
  2715.       case XYDDIA:
  2716.     return(setdial(x));
  2717.  
  2718.       case XYDTYP:
  2719.     if ((y = cmkey(mdmtab,nmdm,"modem type","none", xxstring)) < 0)
  2720.       return(y);
  2721.     if (y == dialudt) {        /* User-defined modem type */
  2722.         if ((x = cmkey(mdmtab,nmdm,"based on existing modem type",
  2723.                "unknown", xxstring)) < 0)
  2724.           return(x);
  2725.     }
  2726.     if ((z = cmcfm()) < 0)
  2727.       return(z);
  2728.     usermdm = 0;
  2729.     usermdm = (y == dialudt) ? x : 0;
  2730.     initmdm(y);
  2731.     return(success = 1);
  2732.  
  2733.       case XYDNAM:
  2734.     return(dialstr(&dialname,"Descriptive name for modem"));
  2735.  
  2736.       case XYDMCD:            /* SET MODEM CARRIER-WATCH */
  2737.     return(setdcd());
  2738.  
  2739.       case XYDSPK:            /* SET MODEM SPEAKER */
  2740.     return(seton(&mdmspk));
  2741.  
  2742.       case XYDVOL:            /* SET MODEM VOLUME */
  2743.     if ((x = cmkey(voltab,3,"","medium",xxstring)) < 0)
  2744.       return(x);
  2745.     if ((y = cmcfm()) < 0)
  2746.       return(y);
  2747.     mdmvol = x;
  2748.     return(success = 1);
  2749.  
  2750.       default:
  2751.     printf("Unexpected SET MODEM parameter\n");
  2752.     return(-9);
  2753.     }
  2754. }
  2755.  
  2756. static int                /* Set DIAL command options */
  2757. setdial(y) int y; {
  2758.     int x = 0, z = 0;
  2759.     char *s = NULL;
  2760.  
  2761.     if (y < 0)
  2762.       if ((y = cmkey(dialtab,ndial,"","",xxstring)) < 0)
  2763.     return(y);
  2764.     switch (y) {
  2765.       case XYDHUP:            /* DIAL HANGUP */
  2766.     return(seton(&dialhng));
  2767.       case XYDINI:            /* DIAL INIT-STRING */
  2768.     return(dialstr(&dialini,"Modem initialization string"));
  2769.       case XYDNPR:            /* DIAL PREFIX */
  2770.     return(dialstr(&dialnpr,"Telephone number prefix"));
  2771.       case XYDDIA:            /* DIAL DIAL-COMMAND */
  2772.     x = cmtxt("Dialing command for modem,\n\
  2773.  include \"%s\" to stand for phone number,\n\
  2774.  for example, \"set dial dial-command ATDT%s\\13\"",
  2775.           "",
  2776.           &s,
  2777.           xxstring);
  2778.     if (x < 0 && x != -3)        /* Handle parse errors */
  2779.       return(x);
  2780.     y = x = strlen(s);        /* Get length of text */
  2781.     if (x > 0 && *s == '{') {    /* Strip enclosing braces, */
  2782.         if (s[x-1] == '}') {    /* if any. */
  2783.         s[x-1] = NUL;
  2784.         s++;
  2785.         y -= 2;
  2786.         }
  2787.     }
  2788.     if (y > 0) {            /* If there is any text (left), */
  2789.         for (x = 0; x < y; x++) {    /* make sure they included "%s" */
  2790.         if (s[x] != '%') continue;
  2791.         if (s[x+1] == 's') break;
  2792.         }
  2793.         if (x == y) {
  2794.         printf(
  2795. "?Dial-command must contain \"%cs\" for phone number.\n",'%');
  2796.         return(-9);
  2797.         }
  2798.     }
  2799.     if (dialcmd) {            /* Free any previous string. */
  2800.         free(dialcmd);
  2801.         dialcmd = (char *) 0;
  2802.     }
  2803.     if (y > 0) {
  2804.         dialcmd = malloc(y + 1);    /* Allocate space for it */
  2805.         strcpy(dialcmd,s);        /* and make a safe copy. */
  2806.     }
  2807.     return(success = 1);
  2808. #ifndef NOXFER
  2809.       case XYDKSP:            /* DIAL KERMIT-SPOOF */
  2810.     return(seton(&dialksp));
  2811. #endif /* NOXFER */
  2812.       case XYDTMO:            /* DIAL TIMEOUT */
  2813.     y = cmnum("Seconds to wait for call completion","0",10,&x,xxstring);
  2814.     if (y < 0) return(y);
  2815.     y = cmnum("Kermit/modem timeout differential","10",10,&z,xxstring);
  2816.     if (y < 0) return(y);
  2817.     if ((y = cmcfm()) < 0)
  2818.       return(y);
  2819.     dialtmo = x;
  2820.     mdmwaitd = z;
  2821.       case XYDESC:            /* DIAL ESCAPE-CHARACTER */
  2822.     y = cmnum("ASCII value of character to escape back to modem",
  2823.           "43",10,&x,xxstring);
  2824.     y = setnum(&dialesc,x,y,128);
  2825.     if (y > -1 && dialesc < 0)    /* No escape character */
  2826.       dialmhu = 0;            /* So no hangup by modem command */
  2827.     return(y);
  2828.       case XYDDPY:            /* DIAL DISPLAY */
  2829.     return(seton(&dialdpy));
  2830.       case XYDSPD:            /* DIAL SPEED-MATCHING */
  2831.                     /* used to be speed-changing */
  2832.     if ((y = seton(&mdmspd)) < 0) return(y);
  2833. #ifdef COMMENT
  2834.     mdmspd = 1 - mdmspd;        /* so here we reverse the meaning */
  2835. #endif /* COMMENT */
  2836.     return(success = 1);
  2837.       case XYDMNP:            /* DIAL MNP-ENABLE */
  2838.       case XYDEC:            /* DIAL ERROR-CORRECTION */
  2839.     x = seton(&dialec);
  2840.     if (x > 0)
  2841.       if (!dialec) dialdc = 0;    /* OFF also turns off compression */
  2842.     return(x);
  2843.  
  2844.       case XYDDC:            /* DIAL COMPRESSION */
  2845.     x = seton(&dialdc);
  2846.     if (x > 0)
  2847.       if (dialdc) dialec = 1;    /* ON also turns on error correction */
  2848.     return(x);
  2849.  
  2850. #ifdef MDMHUP
  2851.       case XYDMHU:            /* DIAL MODEM-HANGUP */
  2852.     return(seton(&dialmhu));
  2853. #endif /* MDMHUP */
  2854.  
  2855. #ifndef NOSPL
  2856.       case XYDDIR:            /* DIAL DIRECTORY (zero or more) */
  2857.     return(parsdir(0));        /* 0 means DIAL */
  2858. #endif /* NOSPL */
  2859.  
  2860.       case XYDSTR:            /* DIAL STRING */
  2861.     if ((y = cmkey(mdmcmd,nmdmcmd,"","",xxstring)) < 0) return(y);
  2862.     switch (y) {
  2863.       case XYDS_AN:            /* Autoanswer ON/OFF */
  2864.       case XYDS_DC:            /* Data compression ON/OFF */
  2865.       case XYDS_EC:            /* Error correction ON/OFF */
  2866.         if ((x = cmkey(onoff,2,"","on",xxstring)) < 0) return(x);
  2867.         sprintf(tmpbuf,"Modem's command to %sable %s",
  2868.             x ? "en" : "dis",
  2869.             (y == XYDS_DC) ? "compression" :
  2870.             ((y == XYDS_EC) ? "error-correction" :
  2871.             "autoanswer")
  2872.             );
  2873.         if (x) {
  2874.         if (y == XYDS_DC)
  2875.           return(dialstr(&dialdcon,tmpbuf));
  2876.         else if (y == XYDS_EC)
  2877.           return(dialstr(&dialecon,tmpbuf));
  2878.         else
  2879.           return(dialstr(&dialaaon,tmpbuf));
  2880.         } else {
  2881.         if (y == XYDS_DC)
  2882.           return(dialstr(&dialdcoff,tmpbuf));
  2883.         else if (y == XYDS_EC)
  2884.           return(dialstr(&dialecoff,tmpbuf));
  2885.         else
  2886.           return(dialstr(&dialaaoff,tmpbuf));
  2887.         }
  2888.       case XYDS_HU:            /*    hangup command */
  2889.         return(dialstr(&dialhcmd,"Modem's hangup command"));
  2890.       case XYDS_HW:            /*    hwfc */
  2891.         return(dialstr(&dialhwfc,
  2892.                "Modem's command to enable hardware flow control"));
  2893.       case XYDS_IN:            /*    init */
  2894.         return(dialstr(&dialini,"Modem's initialization string"));
  2895.       case XYDS_NF:            /*    no flow control */
  2896.         return(dialstr(&dialnofc,
  2897.                "Modem's command to disable local flow control"));
  2898.       case XYDS_PX:            /*    prefix */
  2899.         return(dialstr(&dialnpr,"Telephone number prefix for dialing"));
  2900.       case XYDS_SW:            /*    swfc */
  2901.         return(dialstr(&dialswfc,
  2902.            "Modem's command to enable local software flow control"));
  2903.       case XYDS_DT:            /*    tone dialing */
  2904.         return(dialstr(&dialtone,
  2905.            "Command to configure modem for tone dialing"));
  2906.       case XYDS_DP:            /*    pulse dialing */
  2907.         return(dialstr(&dialpulse,
  2908.                "Command to configure modem for pulse dialing"));
  2909.       case XYDS_MS:            /*    dial mode string */
  2910.         return(dialstr(&dialmstr,
  2911.                          "Command to enter dial mode"));
  2912.       case XYDS_MP:            /*    dial mode prompt */
  2913.         return(dialstr(&dialmprmt,
  2914.                "Modem response upon entering dial mode"));
  2915.       case XYDS_SP:            /* SPEAKER OFF */
  2916.         if ((x = cmkey(onoff,2,"","on",xxstring)) < 0) return(x);
  2917.         if (x)
  2918.           return(dialstr(&dialspon,"Command to turn modem speaker on"));
  2919.         else
  2920.           return(dialstr(&dialspoff,"Command to turn modem speaker off"));
  2921.  
  2922.       case XYDS_VO:            /* VOLUME LOW */
  2923.         if ((x = cmkey(voltab,3,"","medium",xxstring)) < 0) return(x);
  2924.         switch (x) {
  2925.           case 0:
  2926.           case 1:
  2927.         return(dialstr(&dialvol1,
  2928.                    "Command for low modem speaker volume"));
  2929.           case 2:
  2930.         return(dialstr(&dialvol2,
  2931.                "Command for medium modem speaker volume"));
  2932.  
  2933.           case 3:
  2934.         return(dialstr(&dialvol3,
  2935.                    "Command for high modem speaker volume"));
  2936.           default:
  2937.         return(-2);
  2938.         }
  2939.  
  2940.       case XYDS_ID:            /* IGNORE-DIALTONE */
  2941.         return(dialstr(&dialx3,
  2942.                "Command to tell modem to ignore dialtone"));
  2943.  
  2944.       case XYDS_I2:            /* PREDIAL-INIT */
  2945.         return(dialstr(&dialini2,
  2946.                "Command to send to modem just prior to dialing"));
  2947.  
  2948.       default:
  2949.         printf("?Unexpected SET DIAL STRING parameter\n");
  2950.     }
  2951.  
  2952.       case XYDFC:            /* DIAL FLOW-CONTROL */
  2953.     if ((y = cmkey(dial_fc,4,"","auto",xxstring)) < 0) return(y);
  2954.     if ((x = cmcfm()) < 0) return(x);
  2955.     dialfc = y;
  2956.     return(success = 1);
  2957.  
  2958.       case XYDMTH:            /* DIAL METHOD */
  2959.     if ((y = cmkey(dial_m,ndial_m,"","default",xxstring)) < 0)
  2960.       return(y);
  2961.     if ((x = cmcfm()) < 0)
  2962.       return(x);
  2963.     if (y == XYDM_A) {        /* AUTO */
  2964.         extern int dialmauto;    /* Means choose based on */
  2965.         dialmauto = 1;        /* local country code, if known. */
  2966.         dialmth = XYDM_D;
  2967.     } else
  2968.       dialmth = y;
  2969.     return(success = 1);
  2970.  
  2971.       case XYDRTM:
  2972.     y = cmnum("Number of times to try dialing a number",
  2973.           "1",10,&x,xxstring);
  2974.     return(setnum(&dialrtr,x,y,16383));
  2975.  
  2976.       case XYDINT:
  2977.     y = cmnum("Seconds to wait between redial attempts",
  2978.           "30",10,&x,xxstring);
  2979.     return(setnum(&dialint,x,y,128));
  2980.  
  2981.       case XYDLAC:            /* DIAL AREA-CODE */
  2982.     if ((x = dialstr(&diallac,"Area code you are calling from")) < 0)
  2983.       return(x);
  2984.     if (diallac) {
  2985.         if (!rdigits(diallac)) {
  2986.         printf("?Sorry, area code must be numeric\n");
  2987.         if (*diallac == '(')
  2988.           printf("(please omit the parentheses)\n");
  2989.         if (*diallac == '/')
  2990.           printf("(no slashes, please)\n");
  2991.         if (diallac) free(diallac);
  2992.         diallac = NULL;
  2993.         return(-9);
  2994.         }
  2995.     }
  2996.     return(x);
  2997.  
  2998.       case XYDCNF:            /* CONFIRMATION */
  2999.     return(success = seton(&dialcnf));
  3000.  
  3001.       case XYDCVT:            /* CONVERT-DIRECTORY */
  3002.     if ((y = cmkey(dcnvtab,3,"","ask",xxstring)) < 0)
  3003.       return(y);
  3004.     if ((x = cmcfm()) < 0)
  3005.       return(x);
  3006.     dialcvt = y;
  3007.     return(success = 1);
  3008.  
  3009.       case XYDLCC:            /* DIAL COUNTRY-CODE */
  3010.     x = dialstr(&diallcc,"Country code you are calling from");
  3011.     if (x < 1) return(x);
  3012.     if (diallcc) {
  3013.         if (!rdigits(diallcc)) {
  3014.         printf("?Sorry, country code must be numeric\n");
  3015.         if (*diallcc == '+')
  3016.           printf("(please omit the plus sign)\n");
  3017.         if (diallcc) free(diallcc);
  3018.         diallcc = NULL;
  3019.         return(-9);
  3020.         }
  3021.         if (!strcmp(diallcc,"1")) {    /* Set defaults for USA and Canada */
  3022.         if (!dialldp)        /* Long-distance prefix */
  3023.           makestr(&dialldp,"1");
  3024.         if (!dialixp)         /* International dialing prefix */
  3025.           makestr(&dialixp,"011");
  3026.         if (ntollfree == 0) {    /* Toll-free area codes */
  3027.             if (dialtfc[0] = malloc(4)) {
  3028.             strcpy(dialtfc[0],"800"); /* 1970-something */
  3029.             ntollfree++;
  3030.             if (dialtfc[1] = malloc(4)) {
  3031.                 strcpy(dialtfc[1],"888"); /* 1996 */
  3032.                 ntollfree++;
  3033.                 if (dialtfc[2] = malloc(4)) {
  3034.                 strcpy(dialtfc[2],"877"); /* 5 April 1998 */
  3035.                 ntollfree++;
  3036.                 if (dialtfc[3] = malloc(4)) {
  3037.                     strcpy(dialtfc[3],"866"); /* Soon */
  3038.                     ntollfree++;
  3039.                 }
  3040.                 }
  3041.             }
  3042.             }
  3043.         }
  3044.         if (!dialtfp)         /* Toll-free dialing prefix */
  3045.           makestr(&dialtfp,"1");
  3046. #ifdef COMMENT
  3047. /* The time for this is past */
  3048.         } else if (!strcmp(diallcc,"358") &&
  3049.                ((int) strcmp(zzndate(),"19961011") > 0)
  3050.                ) {        /* Finland */
  3051.         if (!dialldp)        /* Long-distance prefix */
  3052.           makestr(&dialldp,"9");
  3053.         if (!dialixp)         /* International dialing prefix */
  3054.           makestr(&dialixp,"990");
  3055. #endif /* COMMENT */
  3056.         } else {            /* Everywhere else ... */
  3057.         if (!dialldp) {
  3058.             if (dialldp = malloc(4))
  3059.               strcpy(dialldp,"0");
  3060.         }
  3061.         if (!dialixp) {
  3062.             if (dialixp = malloc(4))
  3063.               strcpy(dialixp,"00");
  3064.         }
  3065.         }
  3066.         if (!strcmp(diallcc,"33"))    /* France */
  3067.           dialfld = 1;        /* Long-distance dialing is forced */
  3068.     }
  3069.     return(success = 1);
  3070.  
  3071.       case XYDIXP:            /* DIAL INTL-PREFIX */
  3072.     return(dialstr(&dialixp,"International dialing prefix"));
  3073.  
  3074.       case XYDIXS:            /* DIAL INTL-SUFFIX */
  3075.     return(dialstr(&dialixs,"International dialing suffix"));
  3076.  
  3077.       case XYDLDP:            /* DIAL LD-PREFIX */
  3078.     return(dialstr(&dialldp,"Long-distance dialing prefix"));
  3079.  
  3080.       case XYDLDS:            /* DIAL LD-SUFFIX */
  3081.     return(dialstr(&diallds,"Long-distance dialing suffix"));
  3082.  
  3083.       case XYDLCP:            /* DIAL LC-PREFIX */
  3084.     return(dialstr(&diallcp,"Local dialing prefix"));
  3085.  
  3086.       case XYDLCS:            /* DIAL LC-SUFFIX */
  3087.     return(dialstr(&diallcs,"Local dialing suffix"));
  3088.  
  3089. #ifdef COMMENT
  3090.       case XYDPXX:            /* DIAL PBX-EXCHANGE */
  3091.     return(dialstr(&dialpxx,"Exchange of PBX you are calling from"));
  3092. #endif /* COMMENT */
  3093.  
  3094.       case XYDPXI: {            /* DIAL PBX-INTERNAL-PREFIX */
  3095. #ifdef COMMENT
  3096.       return(dialstr(&dialpxi,
  3097.                "Internal-call prefix of PBX you are calling from"));
  3098. #else
  3099.       int x;
  3100.       if ((x = cmtxt("Internal-call prefix of PBX you are calling from",
  3101.              "",&s,NULL)) < 0) /* Don't evaluate */
  3102.         return(x);
  3103. #ifndef NOSPL
  3104.       if (*s) {
  3105.           char c, * p = tmpbuf;
  3106.           if (*s == '\\') {
  3107.           c = *(s+1);
  3108.           if (isupper(c)) c = tolower(c);
  3109.           if (c != 'f' &&
  3110.               ckstrcmp(s,"\\v(d$px)",8,0) &&
  3111.               ckstrcmp(s,"\\v(d$pxx)",9,0) &&
  3112.               ckstrcmp(s,"\\v(d$p)",7,0)) {
  3113.               x = TMPBUFSIZ;
  3114.               zzstring(s,&p,&x);
  3115.               s = tmpbuf;
  3116.           }
  3117.           }
  3118.       }
  3119. #endif /* NOSPL */
  3120.       makestr(&dialpxi,s);
  3121.       return(1);
  3122.       }
  3123. #endif /* COMMENT */
  3124.  
  3125.       case XYDPXO:            /* DIAL PBX-OUTSIDE-PREFIX */
  3126.     return(dialstr(&dialpxo,
  3127.                "Outside-line prefix of PBX you are calling from"));
  3128.  
  3129.       case XYDSFX:            /* DIAL INTL-SUFFIX */
  3130.     return(dialstr(&dialsfx," Telephone number suffix for dialing"));
  3131.  
  3132.       case XYDSRT:            /* DIAL SORT */
  3133.     return(success = seton(&dialsrt));
  3134.  
  3135.       case XYDPXX:            /* DIAL PBX-EXCHANGE */
  3136.       case XYDTFC: {            /* DIAL TOLL-FREE-AREA-CODE  */
  3137.       int n, i;            /* (zero or more of them...) */
  3138.       char * p[MAXTOLLFREE];    /* Temporary pointers */
  3139.       char * m;
  3140.       for (n = 0; n < MAXTOLLFREE; n++) {
  3141.           if (n == 0) {
  3142.           m = (y == XYDTFC) ?
  3143.           "Toll-free area code(s) in the country you are calling from"
  3144.             : "Exchange(s) of PBX you are calling from";
  3145.           } else {
  3146.           m = (y == XYDTFC) ?
  3147.             "Another toll-free area code"
  3148.               : "Another PBX exchange";
  3149.           }
  3150.           if ((x = cmfld(m,"",&s,xxstring)) < 0)
  3151.         break;
  3152.           if (s) {
  3153.           int k;
  3154.           k = (int) strlen(s);
  3155.           if (k > 0) {
  3156.               if (p[n] = malloc(k + 1))
  3157.             strcpy(p[n], s);
  3158.           } else break;
  3159.           } else break;
  3160.       }
  3161.       if (x == -3) {        /* Command was successful */
  3162.           int m;
  3163.           m = (y == XYDTFC) ? ntollfree : ndialpxx;
  3164.           if ((x = cmcfm()) < 0)
  3165.         return(x);
  3166.           x = 1;
  3167.           for (i = 0; i < m; i++) { /* Remove old list, if any */
  3168.           if  (y == XYDTFC)
  3169.             makestr(&(dialtfc[i]),NULL);
  3170.           else
  3171.             makestr(&(dialpxx[i]),NULL);
  3172.           }
  3173.           if  (y == XYDTFC)
  3174.         ntollfree = n;        /* New count */
  3175.           else
  3176.         ndialpxx = n;
  3177.           for (i = 0; i < n; i++) { /* New list */
  3178.           if  (y == XYDTFC)
  3179.             makestr(&(dialtfc[i]),p[i]);
  3180.           else
  3181.             makestr(&(dialpxx[i]),p[i]);
  3182.           }
  3183.           x = 1;
  3184.       }
  3185.       for (i = 0; i < n; i++)
  3186.         if (p[i]) free(p[i]);
  3187.       return(x);
  3188.       }
  3189.  
  3190.       case XYDTFP:            /* TOLL-FREE-PREFIX */
  3191.     return(dialstr(&dialtfp,
  3192.                " Long-distance prefix for toll-free dialing"));
  3193.  
  3194.       case XYDCON:            /* CONNECT */
  3195.     z = -1;
  3196.     if ((y = cmkey(crrtab,ncrr,"","auto",xxstring)) < 0) return(y);
  3197.     if (y != CAR_OFF)        /* AUTO or ON? */
  3198.       if ((z = cmkey(qvtab,nqvt,"","verbose",xxstring)) < 0) return(z);
  3199.     if ((x = cmcfm()) < 0) return(x);
  3200.     if (z > -1)
  3201.       dialcq = z;
  3202.     dialcon = y;
  3203.     return(success = 1);
  3204.  
  3205.       case XYDRSTR:            /* RESTRICT */
  3206.     if ((y = cmkey(drstrtab,4,"","none",xxstring)) < 0) return(y);
  3207.     if ((x = cmcfm()) < 0) return(x);
  3208.     dialrstr = y;
  3209.     return(success = 1);
  3210.  
  3211.       case XYDLLAC: {            /* Local area-code list  */
  3212.       int n, i;            /* (zero or more of them...) */
  3213.       char * p[MAXLOCALAC];    /* Temporary pointers */
  3214.       for (n = 0; n < MAXLOCALAC; n++) {
  3215.           if ((x = cmfld(
  3216.             "Area code to which calls from your area are local",
  3217.                "",&s,xxstring)) < 0)
  3218.         break;
  3219.           if (s) {
  3220.           int k;
  3221.           k = (int) strlen(s);
  3222.           if (k > 0) {
  3223.               if (p[n] = malloc(k + 1))
  3224.             strcpy(p[n], s);
  3225.           } else break;
  3226.           } else break;
  3227.       }
  3228.       if (x == -3) {        /* Command was successful */
  3229.           if ((x = cmcfm()) < 0)
  3230.         return(x);
  3231.           for (i = 0; i < nlocalac; i++) /* Remove old list, if any */
  3232.         if (diallcac[i]) {
  3233.             free(diallcac[i]);
  3234.             diallcac[i] = NULL;
  3235.         }
  3236.           nlocalac = n;        /* New count */
  3237.           for (i = 0; i < nlocalac; i++) /* New list */
  3238.         diallcac[i] = p[i];
  3239.           return(success = 1);
  3240.       } else {            /* Parse error, undo everything */
  3241.           for (i = 0; i < n; i++)
  3242.         if (p[i]) free(p[i]);
  3243.           return(x);
  3244.       }
  3245.       }
  3246.  
  3247.       case XYDFLD:
  3248.     return(success = seton(&dialfld));
  3249.  
  3250.       case XYDIDT:            /* DIAL IGNORE-DIALTONE */
  3251.     return(seton(&dialidt));
  3252.  
  3253.       case XYDPAC:
  3254.     y = cmnum(
  3255.           "Milliseconds to pause between each character sent to dialer",
  3256.           "",10,&x,xxstring);
  3257.     return(setnum(&dialpace,x,y,9999));
  3258.  
  3259. #ifndef NOSPL
  3260.       case XYDMAC:
  3261.     if ((x = cmfld("Name of macro to execute just prior to dialing",
  3262.                "",&s,xxstring)) < 0) {
  3263.         if (x == -3)
  3264.           s = NULL;
  3265.         else
  3266.           return(x);
  3267.     }
  3268.     if (s) {
  3269.         if (!*s) {
  3270.         s = NULL;
  3271.         } else {
  3272.         strcpy(line,s);
  3273.         s = line;
  3274.         }
  3275.     }
  3276.     if ((x = cmcfm()) < 0)
  3277.       return(x);
  3278.     makestr(&dialmac,s);
  3279.     return(success = 1);
  3280. #endif /* NOSPL */
  3281.  
  3282.       case XYDPUCC:            /* Pulse country codes */
  3283.       case XYDTOCC: {            /* Tone country codes */
  3284.       int n, i;
  3285.       char * p[MAXTPCC];
  3286.       char * m;
  3287.       for (n = 0; n < MAXTPCC; n++) {
  3288.           if (n == 0) {
  3289.           m = (y == XYDPUCC) ?
  3290.           "Country code where Pulse dialing is required"
  3291.             : "Country code where Tone dialing is available";
  3292.           } else
  3293.         m = "Another country code";
  3294.           if ((x = cmfld(m,"",&s,xxstring)) < 0)
  3295.         break;
  3296.           if (s) {
  3297.           int k;
  3298.           k = (int) strlen(s);
  3299.           if (k > 0) {
  3300.               if (p[n] = malloc(k + 1))
  3301.             strcpy(p[n], s);
  3302.           } else break;
  3303.           } else break;
  3304.       }
  3305.       if (x == -3) {        /* Command was successful */
  3306.           int m;
  3307.           m = (y == XYDPUCC) ? ndialpucc : ndialtocc;
  3308.           if ((x = cmcfm()) < 0)
  3309.         return(x);
  3310.           x = 1;
  3311.           for (i = 0; i < m; i++) { /* Remove old list, if any */
  3312.           if (y == XYDPUCC)
  3313.             makestr(&(dialpucc[i]),NULL);
  3314.           else
  3315.             makestr(&(dialtocc[i]),NULL);
  3316.           }
  3317.           if (y == XYDPUCC) {
  3318.           ndialpucc = n;        /* New count */
  3319.           } else {
  3320.           ndialtocc = n;
  3321.           }
  3322.           for (i = 0; i < n; i++) { /* New list */
  3323.           if (y == XYDPUCC) {
  3324.               makestr(&(dialpucc[i]),p[i]);
  3325.           } else {
  3326.               makestr(&(dialtocc[i]),p[i]);
  3327.           }
  3328.           }
  3329.           x = 1;
  3330.       }
  3331.       for (i = 0; i < n; i++)
  3332.         if (p[i]) free(p[i]);
  3333.       return(x);
  3334.       }
  3335.       case XYDTEST:
  3336.     return(seton(&dialtest));
  3337.  
  3338.       default:
  3339.     printf("?Unexpected SET DIAL parameter\n");
  3340.     return(-9);
  3341.     }
  3342. }
  3343.  
  3344. #ifdef CK_TAPI
  3345. int                        /* TAPI action commands */
  3346. dotapi() {
  3347.     int x,y;
  3348.     char *s;
  3349.  
  3350.     if (!TAPIAvail) {
  3351.     printf("\nTAPI is unavailable on this system.\n");
  3352.     return(-9);
  3353.     }
  3354.     if ((y = cmkey(tapitab,ntapitab,"MS TAPI command","",xxstring)) < 0)
  3355.       return(y);
  3356.     switch (y) {
  3357.       case XYTAPI_CFG: {            /* TAPI CONFIGURE-LINE */
  3358.       extern struct keytab * tapilinetab;
  3359.       extern struct keytab * _tapilinetab;
  3360.       extern int ntapiline;
  3361.       extern int LineDeviceId;
  3362.       int lineID=LineDeviceId;
  3363.       if (TAPIAvail)
  3364.         cktapiBuildLineTable(&tapilinetab, &_tapilinetab, &ntapiline);
  3365.       if (tapilinetab && _tapilinetab && ntapiline > 0) {
  3366.           int i=0, j = 9999, k = -1;
  3367.  
  3368.           if ( LineDeviceId == -1 ) {
  3369.           /* Find out what the lowest numbered TAPI device is */
  3370.           /* and use it as the default.                       */
  3371.           for (i = 0; i < ntapiline; i++ ) {
  3372.               if (tapilinetab[i].kwval < j) {
  3373.               k = i;
  3374.               }
  3375.           }
  3376.           } else {
  3377.           /* Find the LineDeviceId in the table and use that entry */
  3378.           for (i = 0; i < ntapiline; i++ ) {
  3379.               if (tapilinetab[i].kwval == LineDeviceId) {
  3380.               k = i;
  3381.               break;
  3382.               }
  3383.           }
  3384.           }
  3385.           if (k >= 0)
  3386.         s = _tapilinetab[k].kwd;
  3387.           else
  3388.         s = "";
  3389.  
  3390.           if ((y = cmkey(_tapilinetab,ntapiline,
  3391.                   "TAPI device name",s,xxstring)) < 0)
  3392.         return(y);
  3393.           lineID = y;
  3394.       }
  3395.       if ((x = cmcfm()) < 0) return(x);
  3396. #ifdef IKSD
  3397.           if (inserver) {
  3398.               printf("Sorry, command disabled\r\n");
  3399.               return(success = 0);
  3400.           }
  3401. #endif /* ISKD */
  3402.       cktapiConfigureLine(lineID);
  3403.       break;
  3404.       }
  3405.       case XYTAPI_DIAL:            /* TAPI DIALING-PROPERTIES */
  3406.     if ((x = cmcfm()) < 0)
  3407.       return(x);
  3408. #ifdef IKSD
  3409.     if (inserver) {
  3410.         printf("Sorry, command disabled\r\n");
  3411.         return(success = 0);
  3412.     }
  3413. #endif /* ISKD */
  3414.     cktapiDialingProp();
  3415.     break;
  3416.     }
  3417.     return(success = 1);
  3418. }
  3419.  
  3420. static int                /* SET TAPI command options */
  3421. settapi() {
  3422.     int x, y;
  3423.     char *s;
  3424.  
  3425.     if (!TAPIAvail) {
  3426.     printf("\nTAPI is unavailable on this system.\n");
  3427.     return(-9);
  3428.     }
  3429.     if ((y = cmkey(settapitab,nsettapitab,"MS TAPI option","",xxstring)) < 0)
  3430.       return(y);
  3431.     switch (y) {
  3432.       case XYTAPI_USE:
  3433.     return (success = seton(&tapiusecfg));
  3434.       case XYTAPI_LGHT:
  3435.     return (success = seton(&tapilights));
  3436.       case XYTAPI_PRE:
  3437.     return (success = seton(&tapipreterm));
  3438.       case XYTAPI_PST:
  3439.     return (success = seton(&tapipostterm));
  3440.       case XYTAPI_INA:
  3441.     y = cmnum("seconds of inactivity before auto-disconnect",
  3442.           "0",10,&x,xxstring);
  3443.     return(setnum(&tapiinactivity,x,y,65535));
  3444.       case XYTAPI_BNG:
  3445.     y = cmnum("seconds to wait for credit card tone",
  3446.           "8",10,&x,xxstring);
  3447.     return(setnum(&tapibong,x,y,90));
  3448.       case XYTAPI_MAN:
  3449.     return (success = seton(&tapimanual));
  3450.       case XYTAPI_CON:            /* TAPI CONVERSIONS */
  3451.     return (success = setonaut(&tapiconv));
  3452.       case XYTAPI_LIN:            /* TAPI LINE */
  3453.     x = setlin(XYTAPI_LIN,1,0);
  3454.     if (x > -1) didsetlin++;
  3455.     return(x);
  3456.       case XYTAPI_PASS:    {        /* TAPI PASSTHROUGH */
  3457.         /* Passthrough became Modem-dialing which is an antonym */
  3458.         success = seton(&tapipass);
  3459.         tapipass = !tapipass;
  3460.     return (success);
  3461.       }
  3462.       case XYTAPI_LOC: {        /* TAPI LOCATION */
  3463.       extern char tapiloc[];
  3464.       extern int tapilocid;
  3465.       int i = 0, j = 9999, k = -1;
  3466.  
  3467.       cktapiBuildLocationTable(&tapiloctab, &ntapiloc);
  3468.       if (!tapiloctab || !ntapiloc) {
  3469.           printf("\nNo TAPI Locations are configured for this system\n");
  3470.           return(-9);
  3471.       }
  3472.       if (tapilocid == -1)
  3473.         tapilocid = cktapiGetCurrentLocationID();
  3474.  
  3475.       /* Find the current tapiloc entry */
  3476.       /* and use it as the default. */
  3477.       for (k = 0; k < ntapiloc; k++) {
  3478.           if (tapiloctab[k].kwval == tapilocid)
  3479.         break;
  3480.       }
  3481.           if (k >= 0 && k < ntapiloc)
  3482.         s = tapiloctab[k].kwd;
  3483.       else
  3484.         s = "";
  3485.  
  3486.       if ((y = cmkey(tapiloctab,ntapiloc, "TAPI location",s,xxstring)) < 0)
  3487.         return(y);
  3488.  
  3489.       if ((x = cmcfm()) < 0)
  3490.         return(x);
  3491. #ifdef IKSD
  3492.           if (inserver) {
  3493.               printf("Sorry, command disabled\r\n");
  3494.               return(success = 0);
  3495.           }
  3496. #endif /* ISKD */
  3497.       cktapiFetchLocationInfoByID( y );
  3498.       CopyTapiLocationInfoToKermitDialCmd();
  3499.         }
  3500.     break;
  3501.     }
  3502.     return(success=1);
  3503. }
  3504. #endif /* CK_TAPI */
  3505.  
  3506. #ifndef NOSHOW
  3507. int                    /* SHOW MODEM */
  3508. shomodem() {
  3509.     MDMINF * p;
  3510.     int x, n;
  3511.     char c;
  3512.     long zz;
  3513.  
  3514. #ifdef IKSD
  3515.     if (inserver) {
  3516.         printf("Sorry, command disabled\r\n");
  3517.         return(success = 0);
  3518.     }
  3519. #endif /* ISKD */
  3520.  
  3521.     shmdmlin();
  3522.     printf("\n");
  3523.  
  3524.     p = (mdmtyp > 0) ? modemp[mdmtyp] : NULL;
  3525.     if (p) {
  3526.     printf(" %s\n\n", dialname ? dialname : p->name);
  3527.     printf(" Modem carrier-watch:    ");
  3528.     if (carrier == CAR_OFF) printf("off\n");
  3529.     else if (carrier == CAR_ON) printf("on\n");
  3530.     else if (carrier == CAR_AUT) printf("auto\n");
  3531.     else printf("unknown\n");
  3532.  
  3533.     printf(" Modem capabilities:    ");
  3534.     zz = dialcapas ? dialcapas : p->capas;
  3535.     if (!zz) {
  3536.         printf(" (none)");
  3537.     } else {
  3538.         if (zz & CKD_AT) printf(" AT");
  3539.         if (zz & CKD_V25) printf(" ITU");
  3540.         if (zz & CKD_SB) printf(" SB");
  3541.         if (zz & CKD_EC) printf(" EC");
  3542.         if (zz & CKD_DC) printf(" DC");
  3543.         if (zz & CKD_HW) printf(" HWFC");
  3544.         if (zz & CKD_SW) printf(" SWFC");
  3545.         if (zz & CKD_KS) printf(" KS");
  3546.         if (zz & CKD_TB) printf(" TB");
  3547.     }
  3548.     printf("\n Modem maximum-speed:    ");
  3549.     zz = (dialmax > 0L) ? dialmax : p->max_speed;
  3550.     if (zz > 0)
  3551.       printf("%ld bps\n", zz);
  3552.     else
  3553.       printf("(unknown)\n");
  3554.     printf(" Modem error-correction: %s\n", dialec ? "on" : "off");
  3555.     printf(" Modem compression:      %s\n", dialdc ? "on" : "off");
  3556.     printf(" Modem speed-matching:   %s",   mdmspd ? "on" : "off");
  3557.     printf(" (interface speed %s)\n", mdmspd ? "changes" : "is locked");
  3558.     printf(" Modem flow-control:     ");
  3559.     if (dialfc == FLO_NONE) printf("none\n");
  3560.         else if (dialfc == FLO_XONX) printf("xon/xoff\n");
  3561.     else if (dialfc == FLO_RTSC) printf("rts/cts\n");
  3562.     else if (dialfc == FLO_AUTO) printf("auto\n");
  3563.     printf(" Modem hangup-method:    %s\n",
  3564.            dialmhu ?
  3565.            "modem-command" :
  3566.            "rs232-signal"
  3567.            );
  3568.     printf(" Modem speaker:          %s\n", showoff(mdmspk));
  3569.     printf(" Modem volume:           %s\n",
  3570.            (mdmvol == 2) ? "medium" : ((mdmvol <= 1) ? "low" : "high"));
  3571.     printf(" Modem kermit-spoof:     %s\n", dialksp ? "on" : "off");
  3572.     c = (char) (x = (dialesc ? dialesc : p->esc_char));
  3573.     printf(" Modem escape-character: %d", x);
  3574.     if (isprint(c))
  3575.       printf(" (= \"%c\")",c);
  3576.     printf(
  3577. "\n\nMODEM COMMANDs (* = set automatically by SET MODEM TYPE):\n\n");
  3578.     debug(F110,"show dialini",dialini,0);
  3579.     printf(" %c Init-string:          ", dialini ? ' ' : '*' );
  3580.     shods(dialini ? dialini : p->wake_str);
  3581.     printf(" %c Dial-mode-string:     ", dialmstr ? ' ' : '*' );
  3582.     shods(dialmstr ? dialmstr : p->dmode_str);
  3583.     n = local ? 19 : 20;
  3584.     if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  3585.     printf(" %c Dial-mode-prompt:     ", dialmprmt ? ' ' : '*' );
  3586.     shods(dialmprmt ? dialmprmt : p->dmode_prompt);
  3587.     if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  3588.     printf(" %c Dial-command:         ", dialcmd ? ' ' : '*' );
  3589.     shods(dialcmd ? dialcmd : p->dial_str);
  3590.     if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  3591.     printf(" %c Compression on:       ", dialdcon ? ' ' : '*' );
  3592.     if (!dialdcon)
  3593.       debug(F110,"dialdcon","(null)",0);
  3594.     else
  3595.       debug(F110,"dialdcon",dialdcon,0);
  3596.     shods(dialdcon ? dialdcon : p->dc_on_str);
  3597.     if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  3598.     printf(" %c Compression off:      ", dialdcoff ? ' ' : '*' );
  3599.     shods(dialdcoff ? dialdcoff : p->dc_off_str);
  3600.     if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  3601.     printf(" %c Error-correction on:  ", dialecon ? ' ' : '*' );
  3602.     shods(dialecon ? dialecon : p->ec_on_str);
  3603.     if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  3604.     printf(" %c Error-correction off: ", dialecoff ? ' ' : '*' );
  3605.     shods(dialecoff ? dialecoff : p->ec_off_str);
  3606.     if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  3607.     printf(" %c Autoanswer on:        ", dialaaoff ? ' ' : '*' );
  3608.     shods(dialaaon ? dialaaon : p->aa_on_str);
  3609.     if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  3610.     printf(" %c Autoanswer off:       ", dialaaoff ? ' ' : '*' );
  3611.     shods(dialaaoff ? dialaaoff : p->aa_off_str);
  3612.     if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  3613.  
  3614.     printf(" %c Speaker on:           ", dialspon ? ' ' : '*' );
  3615.     shods(dialspon ? dialspon : p->sp_on_str);
  3616.     if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  3617.     printf(" %c Speaker off:          ", dialspoff ? ' ' : '*' );
  3618.     shods(dialspoff ? dialspoff : p->sp_off_str);
  3619.     if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  3620.     printf(" %c Volume low:           ", dialvol1 ? ' ' : '*' );
  3621.     shods(dialvol1 ? dialvol1 : p->vol1_str);
  3622.     if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  3623.     printf(" %c Volume medium:        ", dialvol2 ? ' ' : '*' );
  3624.     shods(dialvol2 ? dialvol2 : p->vol2_str);
  3625.     if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  3626.     printf(" %c Volume high:          ", dialvol3 ? ' ' : '*' );
  3627.     shods(dialvol3 ? dialvol3 : p->vol3_str);
  3628.     if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  3629.  
  3630.     printf(" %c Hangup-command:       ", dialhcmd ? ' ' : '*' );
  3631.     shods(dialhcmd ? dialhcmd : p->hup_str);
  3632.     if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  3633.     printf(" %c Hardware-flow:        ", dialhwfc ? ' ' : '*' );
  3634.     shods(dialhwfc ? dialhwfc : p->hwfc_str);
  3635.     if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  3636.     printf(" %c Software-flow:        ", dialswfc ? ' ' : '*' );
  3637.     shods(dialswfc ? dialswfc : p->swfc_str);
  3638.     if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  3639.     printf(" %c No-flow-control:      ", dialnofc ? ' ' : '*' );
  3640.     shods(dialnofc ? dialnofc : p->nofc_str);
  3641.     if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  3642.     printf(" %c Pulse:                ", dialpulse ? ' ' : '*');
  3643.     shods(dialpulse ? dialpulse : p->pulse);
  3644.     if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  3645.     printf(" %c Tone:                 ", dialtone ? ' ' : '*');
  3646.     shods(dialtone ? dialtone : p->tone);
  3647.  
  3648.     if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  3649.     printf(" %c Ignore-dialtone:      ", dialx3 ? ' ' : '*');
  3650.     shods(dialx3 ? dialx3 : p->ignoredt);
  3651.  
  3652.     if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  3653.     printf(" %c Predial-init:         ", dialini2 ? ' ' : '*');
  3654.     shods(dialini2 ? dialini2 : p->ini2);
  3655.  
  3656.     if (++n > cmd_rows - 4) if (!askmore()) return(0); else n = 0;
  3657.     printf("\n For more info: SHOW DIAL and SHOW COMMUNICATIONS\n");
  3658.  
  3659.     } else if (mdmtyp > 0) {
  3660.     printf("Modem info for \"%s\" not filled in yet\n", gmdmtyp());
  3661.     } else printf(
  3662. " No modem selected, so DIAL and most SET MODEM commands have no effect.\n\
  3663.  Use SET MODEM TYPE to select a modem.\n");
  3664.     return(1);
  3665. }
  3666. #endif /* NOSHOW */
  3667. #endif /* NODIAL */
  3668. #endif /* NOLOCAL */
  3669.  
  3670. #ifndef NOSPL
  3671.  
  3672. #ifdef CK_ANSIC                /* SET ALARM */
  3673. int
  3674. setalarm(long xx)
  3675. #else
  3676. int
  3677. setalarm(xx) long xx;
  3678. #endif /* CK_ANSIC */
  3679. /* setalarm */ {
  3680. #ifdef COMMENT
  3681.     int yyyy, mm, dd, x;
  3682.     char *s;
  3683.     long zz;
  3684.     char buf[6];
  3685. #endif /* COMMENT */
  3686.     long sec, jd;
  3687.     char xbuf[20], * p;
  3688.  
  3689.     debug(F101,"setalarm xx","",xx);
  3690.     ck_alarm = 0L;            /* 0 = no alarm (in case of error) */
  3691.     if (xx < 0L) {
  3692.     printf("%ld - illegal value, must be 0 or positive\n", xx);
  3693.     return(-9);
  3694.     }
  3695.     if (xx == 0L) {            /* CLEAR ALARM */
  3696.     alrm_date[0] = NUL;
  3697.     alrm_time[0] = NUL;
  3698.     return(1);
  3699.     }
  3700. #ifdef COMMENT
  3701.     x = 8;                /* Get current date */
  3702.     s = alrm_date;
  3703.     if (zzstring("\\v(ndate)",&s,&x) < 0) {
  3704.     printf("Internal date error, sorry.\n");
  3705.     alrm_date[0] = SP;
  3706.     return(-9);
  3707.     }
  3708.     x = 5;                /* Get current time */
  3709.     s = alrm_time;
  3710.     if (zzstring("\\v(ntime)",&s,&x) < 0) {
  3711.     printf("Internal time error, sorry.\n");
  3712.     alrm_time[0] = SP;
  3713.     return(-9);
  3714.     }
  3715.     sprintf(buf,"%05ld",atol(alrm_time));
  3716.     strcpy(alrm_time,buf);
  3717.     debug(F110,"SET ALARM date (1)",alrm_date,0);
  3718.     debug(F110,"SET ALARM time (1)",alrm_time,0);
  3719.  
  3720.     if ((zz = atol(alrm_time) + xx) < 0L) {
  3721.     printf("Internal time conversion error, sorry.\n");
  3722.     return(-9);
  3723.     }
  3724.     if (zz >= 86400L) {            /* Alarm crosses midnight */
  3725.     char d[10];            /* Local date buffer */
  3726.     int lastday;            /* Last day of this month */
  3727.  
  3728.     ckstrncpy(d,alrm_date,8);    /* We'll have to change the date */
  3729.  
  3730.     x = (zz / 86400L);        /* How many days after today */
  3731.  
  3732.     dd = atoi((char *)(d+6));    /* Parse yyyymmdd */
  3733.     d[6] = NUL;            /* into yyyy, mm, dd ... */
  3734.     mm = atoi((char *)(d+4));
  3735.     d[4] = NUL;
  3736.     yyyy = atoi((char *)d);
  3737.  
  3738.     /* How many days in this month */
  3739.  
  3740.     lastday = mdays[mm];
  3741.     if (mm == 2 && yyyy % 4 == 0)    /* Works thru 2099 AD... */
  3742.       lastday++;
  3743.  
  3744.     if (dd + x > lastday) {        /* Dumb loop */
  3745.         int y;
  3746.  
  3747.         x -= (mdays[mm] - dd);    /* Deduct rest of this month's days */
  3748.  
  3749.         /* There's a more elegant way to do this... */
  3750.  
  3751.         while (1) {
  3752.         mm++;            /* Next month */
  3753.         if (mm > 12) {        /* Wrap around */
  3754.             mm = 1;        /* Jan, next year */
  3755.             yyyy++;
  3756.         }
  3757.         y = mdays[mm];        /* Days in new month */
  3758.         if (mm == 2 && yyyy % 4 == 0) /* Feb in leap year */
  3759.           y++;            /* Works until 2100 AD */
  3760.         if (x - y < 1)
  3761.           break;
  3762.         x -= y;
  3763.         }
  3764.         dd = x;            /* Day of alarm month */
  3765.     } else dd += x;
  3766.  
  3767.     sprintf(alrm_date,"%04d%02d%02d",yyyy,mm,dd);
  3768.     zz = zz % 86400L;
  3769.     }
  3770.     sprintf(alrm_time,"%ld",zz);
  3771.     debug(F110,"SET ALARM date (2)",alrm_date,0);
  3772.     debug(F110,"SET ALARM time (2)",alrm_time,0);
  3773.     ck_alarm = xx;
  3774. #else
  3775.     /* Jul 1998 */
  3776.     ckstrncpy(xbuf,ckcvtdate("",1),20);    /* Get current date and time */
  3777.     p = xbuf;
  3778.     ckstrncpy(alrm_date,xbuf,10);
  3779.     alrm_date[8] = NUL;
  3780.     sec = atol(p+9) * 3600L + atol(p+12) * 60L + atol(p+15);
  3781.     debug(F110,"SET ALARM date (1)",alrm_date,0);
  3782.     debug(F101,"SET ALARM time (1)","",sec);
  3783.     if ((sec += xx) < 0L) {
  3784.     printf("Internal time conversion error, sorry.\n");
  3785.     return(-9);
  3786.     }
  3787.     if (sec >= 86400L) {        /* Alarm crosses midnight */
  3788.     long days;
  3789.     days = sec / 86400L;
  3790.     jd = mjd(p) + days;        /* Get modified Julian date */
  3791.     ckstrncpy(alrm_date,mjd2date(jd),10);
  3792.     sec %= 86400L;
  3793.     }
  3794.     sprintf(alrm_time,"%05ld",sec);
  3795.     debug(F110,"SET ALARM date (2)",alrm_date,0);
  3796.     debug(F110,"SET ALARM time (2)",alrm_time,0);
  3797.     ck_alarm = 1;            /* Alarm is set */
  3798.  
  3799. #endif /* COMMENT */
  3800.     return(1);
  3801. }
  3802. #endif /* NOSPL */
  3803.  
  3804. #ifndef NOSETKEY
  3805. int
  3806. dosetkey() {                /* SET KEY */
  3807.     int x, y;
  3808.     int flag = 0;
  3809.     int kc;                /* Key code */
  3810.     char *s;                /* Key binding */
  3811. #ifndef NOKVERBS
  3812.     char *p;                /* Worker */
  3813. #endif /* NOKVERBS */
  3814. #ifdef OS2
  3815.     extern int os2gks;
  3816.     extern int mskkeys;
  3817.     extern int initvik;
  3818. #endif /* OS2 */
  3819.  
  3820.     x_ifnum = 1;
  3821.     y = cmnum("numeric key code, or the word CLEAR,","",10,&kc,xxstring);
  3822.     x_ifnum = 0;
  3823.     if (y < 0) {
  3824.     debug(F111,"SET KEY",atmbuf,y);
  3825.     if (y == -2) {            /* Not a valid number */
  3826.         if ((y = strlen(atmbuf)) < 0) /* Check for SET KEY CLEAR */
  3827.           return(-2);
  3828.         if (ckstrcmp(atmbuf,"clear",y,0))
  3829.           return(-2);
  3830.         if ((x = cmcfm()) < 0)
  3831.           return(x);
  3832.         for (y = 0; y < KMSIZE; y++) {
  3833.         keymap[y] = (KEY) y;
  3834.         macrotab[y] = NULL;
  3835.         }
  3836. #ifdef OS2
  3837.         keymapinit();        /* Special OS/2 initializations */
  3838.         initvik = 1;        /* Update the VIK table */
  3839. #endif /* OS2 */
  3840.         return(1);
  3841.     } else if (y == -3) {        /* SET KEY <Return> */
  3842.         printf(" Press key to be defined: "); /* Prompt for a keystroke */
  3843. #ifdef UNIX
  3844. #ifdef NOSETBUF
  3845.         fflush(stdout);
  3846. #endif /* NOSETBUF */
  3847. #endif /* UNIX */
  3848.         conbin((char)escape);    /* Put terminal in binary mode */
  3849. #ifdef OS2
  3850.         os2gks = 0;            /* Turn off Kverb preprocessing */
  3851. #endif /* OS2 */
  3852.         kc = congks(0);        /* Get character or scan code */
  3853. #ifdef OS2
  3854.         os2gks = 1;            /* Turn on Kverb preprocessing */
  3855. #endif /* OS2 */
  3856.         concb((char)escape);    /* Restore terminal to cbreak mode */
  3857.         if (kc < 0) {        /* Check for error */
  3858.         printf("?Error reading key\n");
  3859.         return(0);
  3860.         }
  3861. #ifdef OS2
  3862.         shokeycode(kc,-1);        /* Show current definition */
  3863. #else
  3864.         shokeycode(kc);        /* Show current definition */
  3865. #endif /* OS2 */
  3866.         flag = 1;            /* Remember it's a multiline command */
  3867.     } else                /* Error */
  3868.       return(y);
  3869.     }
  3870.  
  3871.     /* Normal SET KEY <scancode> <value> command... */
  3872.  
  3873. #ifdef OS2
  3874.     if (mskkeys)
  3875.       kc = msktock(kc);
  3876. #endif /* OS2 */
  3877.  
  3878.     if (kc < 0 || kc >= KMSIZE) {
  3879.     printf("?key code must be between 0 and %d\n", KMSIZE - 1);
  3880.     return(-9);
  3881.     }
  3882.     if (kc == escape) {
  3883.     printf("Sorry, %d is the CONNECT-mode escape character\n",kc);
  3884.     return(-9);
  3885.     }
  3886. #ifdef OS2
  3887.     wideresult = -1;
  3888. #endif /* OS2 */
  3889.     if (flag) {
  3890.     cmsavp(psave,PROMPTL);
  3891.     cmsetp(" Enter new definition: ");
  3892.     cmini(ckxech);
  3893.     cmflgs = 0;
  3894.     prompt(NULL);
  3895.     }
  3896.   def_again:
  3897.     if (flag)
  3898.       cmres();
  3899.     if ((y = cmtxt("key definition,\n\
  3900. or Ctrl-C to cancel this command,\n\
  3901. or Enter to restore default definition",
  3902.            "",&s,NULL)) < 0) {
  3903.     if (flag)            /* Handle parse errors */
  3904.       goto def_again;
  3905.     else
  3906.       return(y);
  3907.     }
  3908.     s = brstrip(s);
  3909. #ifndef NOKVERBS
  3910.     p = s;                /* Save this place */
  3911. #endif /* NOKVERBS */
  3912. /*
  3913.   If the definition included any \Kverbs, quote the backslash so the \Kverb
  3914.   will still be in the definition when the key is pressed.  We don't do this
  3915.   in zzstring(), because \Kverbs are valid only in this context and nowhere
  3916.   else.
  3917.  
  3918.   We use this code active for all versions that support SET KEY, even if they
  3919.   don't support \Kverbs, because otherwise \K would behave differently for
  3920.   different versions.
  3921. */
  3922.     for (x = 0, y = 0; s[x]; x++, y++) { /* Convert \K to \\K */
  3923.     if ((x > 0) &&
  3924.         (s[x] == 'K' || s[x] == 'k')
  3925.         ) {                /* Have K */
  3926.  
  3927.         if ((x == 1 && s[x-1] == CMDQ) ||
  3928.         (x > 1 && s[x-1] == CMDQ && s[x-2] != CMDQ)) {
  3929.         line[y++] = CMDQ;    /* Make it \\K */
  3930.         }
  3931.         if (x > 1 && s[x-1] == '{' && s[x-2] == CMDQ) {
  3932.           line[y-1] = CMDQ;    /* Have \{K */
  3933.           line[y++] = '{';    /* Make it \\{K */
  3934.         }
  3935.     }
  3936.     line[y] = s[x];
  3937.     }
  3938.     line[y++] = NUL;            /* Terminate */
  3939.     s = line + y + 1;            /* Point to after it */
  3940.     x = LINBUFSIZ - (int) strlen(line) - 1; /* Calculate remaining space */
  3941.     if ((x < (LINBUFSIZ / 2)) ||
  3942.     (zzstring(line, &s, &x) < 0)) { /* Expand variables, etc. */
  3943.     printf("?Key definition too long\n");
  3944.     if (flag) cmsetp(psave);
  3945.     return(-9);
  3946.     }
  3947.     s = line + y + 1;            /* Point to result. */
  3948.  
  3949. #ifndef NOKVERBS
  3950. /*
  3951.   Special case: see if the definition starts with a \Kverb.
  3952.   If it does, point to it with p, otherwise set p to NULL.
  3953. */
  3954.     p = s;
  3955.     if (*p++ == CMDQ) {
  3956.     if (*p == '{') p++;
  3957.     p = (*p == 'k' || *p == 'K') ? p + 1 : NULL;
  3958.     }
  3959. #endif /* NOKVERBS */
  3960.  
  3961.     if (macrotab[kc]) {            /* Possibly free old macro from key. */
  3962.     free(macrotab[kc]);
  3963.     macrotab[kc] = NULL;
  3964.     }
  3965.     switch (strlen(s)) {        /* Action depends on length */
  3966.       case 0:                /* Reset to default binding */
  3967.     keymap[kc] = (KEY) kc;
  3968.     break;
  3969.       case 1:                /* Single character */
  3970.       keymap[kc] = (CHAR) *s;
  3971.       break;
  3972.       default:                /* Character string */
  3973. #ifndef NOKVERBS
  3974.     if (p) {
  3975.         y = xlookup(kverbs,p,nkverbs,&x); /* Look it up */
  3976.         debug(F101,"set key kverb lookup",0,y); /* exact match required */
  3977.         if (y > -1) {
  3978.         keymap[kc] = F_KVERB | y;
  3979.         break;
  3980.         }
  3981.     }
  3982. #endif /* NOKVERBS */
  3983.     keymap[kc] = (KEY) kc;
  3984.     macrotab[kc] = (MACRO) malloc(strlen(s)+1);
  3985.     if (macrotab[kc])
  3986.       strcpy((char *) macrotab[kc], s);
  3987.     break;
  3988.     }
  3989.     if (flag) cmsetp(psave);
  3990. #ifdef OS2
  3991.     initvik = 1;            /* Update VIK table */
  3992. #endif /* OS2 */
  3993.     return(1);
  3994. }
  3995. #endif /* NOSETKEY */
  3996.  
  3997. #ifdef HWPARITY
  3998. struct keytab stoptbl[] = {
  3999.     "1", 1, 0,
  4000.     "2", 2, 0
  4001. };
  4002. #endif /* HWPARITY */
  4003.  
  4004. static struct keytab sertbl[] = {
  4005.     "7E1", 0, 0,
  4006. #ifdef HWPARITY
  4007.     "7E2", 1, 0,
  4008. #endif /* HWPARITY */
  4009.     "7M1", 2, 0,
  4010. #ifdef HWPARITY
  4011.     "7M2", 3, 0,
  4012. #endif /* HWPARITY */
  4013.     "7O1", 4, 0,
  4014. #ifdef HWPARITY
  4015.     "7O2", 5, 0,
  4016. #endif /* HWPARITY */
  4017.     "7S1", 6, 0,
  4018. #ifdef HWPARITY
  4019.     "7S2", 7, 0,
  4020.     "8E1", 9, 0,
  4021.     "8E2", 10, 0,
  4022. #endif /* HWPARITY */
  4023. #ifdef HWPARITY
  4024.     "8N1", 8, 0,
  4025. #endif /* HWPARITY */
  4026. #ifdef HWPARITY
  4027.     "8N2", 11, 0,
  4028.     "8O1", 12, 0,
  4029.     "8O2", 13, 0,
  4030. #endif /* HWPARITY */
  4031.     "", 0, 0
  4032. };
  4033. static int nsertbl = (sizeof(sertbl) / sizeof(struct keytab)) - 1;
  4034.  
  4035. static char * sernam[] = {        /* Keep this in sync with sertbl[] */
  4036.   "7E1", "7E2", "7M1", "7M2", "7O1", "7O2", "7S1", "7S2",
  4037.   "8N1", "8E1", "8E2", "8N2", "8O1", "8O2"
  4038. };
  4039.  
  4040. static struct keytab optstab[] = {    /* SET OPTIONS table */
  4041. #ifndef NOFRILLS
  4042.     "delete",    XXDEL,   0,            /* DELETE */
  4043. #endif /* NOFRILLS */
  4044.     "directory", XXDIR,   0,        /* DIRECTORY */
  4045. #ifdef CKPURGE
  4046.     "purge",     XXPURGE, 0,        /* PURGE */
  4047. #endif /* CKPURGE */
  4048.     "type",      XXTYP,   0,        /* TYPE */
  4049.     "", 0, 0
  4050. };
  4051. static int noptstab =  (sizeof(optstab) / sizeof(struct keytab)) - 1;
  4052.  
  4053. #ifndef NOXFER
  4054. /*
  4055.   PROTOCOL SELECTION.  Kermit is always available.  If CK_XYZ is defined at
  4056.   compile time, then the others become selections also.  In OS/2 and
  4057.   Windows, they are integrated and the various SET commands (e.g. "set file
  4058.   type") affect them as they would Kermit.  In other OS's (UNIX, VMS, etc),
  4059.   they are external protocols which are run via Kermit's REDIRECT mechanism.
  4060.   All we do is collect and verify the filenames and pass them along to the
  4061.   external protocol.
  4062. */
  4063. struct keytab protos[] = {
  4064. #ifdef CK_XYZ
  4065.     "g",          PROTO_G,  CM_INV,
  4066. #endif /* CK_XYZ */
  4067.     "kermit",     PROTO_K,  0,
  4068. #ifdef CK_XYZ
  4069.     "other",      PROTO_O,  0,
  4070.     "x",          PROTO_X,  CM_INV|CM_ABR,
  4071.     "xmodem",     PROTO_X,  0,
  4072.     "xmodem-crc", PROTO_XC, 0,
  4073.     "y",          PROTO_Y,  CM_INV|CM_ABR,
  4074.     "ymodem",     PROTO_Y,  0,
  4075.     "ymodem-g",   PROTO_G,  0,
  4076.     "zmodem",     PROTO_Z,  0
  4077. #endif /* CK_XYZ */
  4078. };
  4079. int nprotos =  (sizeof(protos) / sizeof(struct keytab));
  4080.  
  4081. #define XPCMDLEN 71
  4082.  
  4083. _PROTOTYP(static int protofield, (char *, char *, char *));
  4084. _PROTOTYP(static int setproto, (void));
  4085.  
  4086. static int
  4087. protofield(current, help, px) char * current, * help, * px; {
  4088.  
  4089.     char *s, tmpbuf[XPCMDLEN+1];
  4090.     int x;
  4091.  
  4092.     if (current)            /* Put braces around default */
  4093.       sprintf(tmpbuf,"{%s}",current);
  4094.     else
  4095.       tmpbuf[0] = NUL;
  4096.  
  4097.     if ((x = cmfld(help, (char *)tmpbuf, &s, xxstring)) < 0)
  4098.       return(x);
  4099.     if ((int)strlen(s) > XPCMDLEN) {
  4100.     printf("?Sorry - maximum length is %d\n", XPCMDLEN);
  4101.     return(-9);
  4102.     } else if (*s) {
  4103.     strcpy(px,s);
  4104.     } else {
  4105.     px = NULL;
  4106.     }
  4107.     return(x);
  4108. }
  4109.  
  4110. static int
  4111. setproto() {                /* Select a file transfer protocol */
  4112.     /* char * s = NULL; */
  4113.     int x = 0, y;
  4114.     char s1[XPCMDLEN+1], s2[XPCMDLEN+1], s3[XPCMDLEN+1];
  4115.     char s4[XPCMDLEN+1], s5[XPCMDLEN+1], s6[XPCMDLEN+1], s7[XPCMDLEN+1];
  4116.     char * p1 = s1, * p2 = s2, *p3 = s3;
  4117.     char * p4 = s4, * p5 = s5, *p6 = s6, *p7 = s7;
  4118.  
  4119. #ifdef XYZ_INTERNAL
  4120.     extern int p_avail;
  4121. #else
  4122. #ifndef CK_REDIR
  4123.     x = 1;
  4124. #endif /* CK_REDIR */
  4125. #endif /* XYZ_INTERNAL */
  4126.     s1[0] = NUL;
  4127.     s2[0] = NUL;
  4128.     s3[0] = NUL;
  4129.     s4[0] = NUL;
  4130.     s5[0] = NUL;
  4131.     s6[0] = NUL;
  4132.  
  4133.     if ((y = cmkey(protos,nprotos,"","kermit",xxstring)) < 0)
  4134.       return(y);
  4135.  
  4136.     if (x && y != PROTO_K) {
  4137.     printf(
  4138.        "?Sorry, REDIRECT capability required for external protocols.\n");
  4139.     return(-9);
  4140.     }
  4141.     if ((x = protofield(ptab[y].h_b_init,
  4142.      "Optional command to send to host prior to uploading in binary mode",
  4143.            p1)) < 0) {
  4144.     if (x == -3) {
  4145.         protocol = y;        /* Set protocol but don't change */
  4146.         return(1);            /* anything else */
  4147.     } else
  4148.       return(x);
  4149.     }
  4150.     if ((x = protofield(ptab[y].h_t_init,
  4151.      "Optional command to send to host prior to uploading in text mode",
  4152.            p2)) < 0) {
  4153.     if (x == -3)
  4154.       goto protoexit;
  4155.     else
  4156.       return(x);
  4157.     }
  4158.  
  4159.     if (y == PROTO_K) {
  4160.     if ((x = protofield(ptab[y].h_x_init,
  4161.             "Optional command to send to host to start Kermit server",
  4162.                 p3)) < 0) {
  4163.         if (x == -3)
  4164.           goto protoexit;
  4165.         else
  4166.           return(x);
  4167.     }
  4168.     }
  4169.  
  4170.  
  4171. #ifndef XYZ_INTERNAL            /* If XYZMODEM are external... */
  4172.  
  4173.     if (y != PROTO_K) {
  4174.     if ((x = protofield(ptab[y].p_b_scmd,
  4175.                "External command to SEND in BINARY mode with this protocol",
  4176.                 p4)) < 0) {
  4177.         if (x == -3)
  4178.           goto protoexit;
  4179.         else
  4180.           return(x);
  4181.     }
  4182.     if ((x = protofield(ptab[y].p_t_scmd,
  4183.          "External command to SEND in TEXT mode with this protocol",
  4184.                 p5)) < 0) {
  4185.         if (x == -3)
  4186.           goto protoexit;
  4187.         else
  4188.           return(x);
  4189.     }
  4190.     if ((x = protofield(ptab[y].p_b_rcmd,
  4191.            "External command to RECEIVE in BINARY mode with this protocol",
  4192.                 p6)) < 0) {
  4193.         if (x == -3)
  4194.           goto protoexit;
  4195.         else
  4196.           return(x);
  4197.     }
  4198.     if ((x = protofield(ptab[y].p_t_rcmd,
  4199.          "External command to RECEIVE in TEXT mode with this protocol",
  4200.                 p7)) < 0) {
  4201.         if (x == -3)
  4202.           goto protoexit;
  4203.         else
  4204.           return(x);
  4205.     }
  4206.     }
  4207. #endif /* XYZ_INTERNAL */
  4208.  
  4209.     if ((x = cmcfm()) < 0)        /* Confirm the command */
  4210.       return(x);
  4211.  
  4212. protoexit:                /* Common exit from this routine */
  4213.  
  4214. #ifdef XYZ_INTERNAL
  4215.     if (!p_avail) {
  4216.     bleep(BP_WARN);
  4217.     printf("\n?X,Y, and Zmodem are unavailable\n");
  4218.     return(success = 0);
  4219.     }
  4220. #endif /* XYZ_INTERNAL */
  4221.  
  4222.     p1 = brstrip(p1);
  4223.     p2 = brstrip(p2);
  4224.     p3 = brstrip(p3);
  4225.     p4 = brstrip(p4);
  4226.     p5 = brstrip(p5);
  4227.     p6 = brstrip(p6);
  4228.     p7 = brstrip(p7);
  4229.     initproto(y,p1,p2,p3,p4,p5,p6,p7);
  4230.     return(success = 1);
  4231. }
  4232.  
  4233. int
  4234. setdest() {
  4235.     int x, y;
  4236.     if ((y = cmkey(desttab,ndests,"","disk",xxstring)) < 0) return(y);
  4237.     if ((x = cmcfm()) < 0) return(x);
  4238.     dest = y;
  4239.     return(1);
  4240. }
  4241. #endif /* NOXFER */
  4242.  
  4243. #ifdef DECNET
  4244. struct keytab dnettab[] = {
  4245. #ifndef OS2ONLY
  4246.     "cterm", NP_CTERM, 0,
  4247. #endif /* OS2ONLY */
  4248.     "lat",   NP_LAT,   0
  4249. };
  4250. int ndnet =  (sizeof(dnettab) / sizeof(struct keytab));
  4251. #endif /* DECNET */
  4252.  
  4253. /*  S E T P R I N T E R  --  SET PRINTER command  */
  4254.  
  4255. #ifdef PRINTSWI
  4256. static struct keytab prntab[] = {    /* SET PRINTER switches */
  4257.     "/bidirectional",    PRN_BID, 0,
  4258.     "/command",          PRN_PIP, CM_ARG,
  4259.     "/dos-device",       PRN_DOS, CM_ARG,
  4260.     "/end-of-job-string",PRN_TRM, CM_ARG,
  4261.     "/file",             PRN_FIL, CM_ARG,
  4262. #ifdef BPRINT
  4263.     "/flow-control",     PRN_FLO, CM_ARG,
  4264. #endif /* BPRINT */
  4265.     "/job-header-file",  PRN_SEP, CM_ARG,
  4266. #ifdef OS2
  4267.     "/length",           PRN_LEN, CM_ARG,
  4268. #endif /* OS2 */
  4269.     "/none",             PRN_NON, 0,
  4270. #ifdef OS2
  4271.     "/nopostscript",     PRN_RAW, 0,
  4272.     "/nops",             PRN_RAW, CM_INV,
  4273. #endif /* OS2 */
  4274.     "/output-only",      PRN_OUT, 0,
  4275. #ifdef BPRINT
  4276.     "/parity",           PRN_PAR, CM_ARG,
  4277. #endif /* BPRINT */
  4278.     "/pipe",             PRN_PIP, CM_ARG|CM_INV,
  4279. #ifdef OS2
  4280.     "/postscript",       PRN_PS,  0,
  4281.     "/ps",               PRN_PS,  CM_INV,
  4282. #endif /* OS2 */
  4283.     "/separator",        PRN_SEP, CM_ARG|CM_INV,
  4284. #ifdef BPRINT
  4285.     "/speed",            PRN_SPD, CM_ARG,
  4286. #endif /* BPRINT */
  4287.     "/timeout",          PRN_TMO, CM_ARG,
  4288.     "/terminator",       PRN_TRM, CM_ARG|CM_INV,
  4289. #ifdef OS2
  4290. #ifdef NT
  4291.     "/w",                PRN_WIN, CM_ARG|CM_ABR|CM_INV,
  4292.     "/wi",               PRN_WIN, CM_ARG|CM_ABR|CM_INV,
  4293. #endif /* NT */
  4294.     "/width",            PRN_WID, CM_ARG,
  4295. #endif /* OS2 */
  4296. #ifdef NT
  4297.     "/windows-queue",    PRN_WIN, CM_ARG,
  4298. #endif /* NT */
  4299.     "",                 0,      0
  4300. };
  4301. int nprnswi =  (sizeof(prntab) / sizeof(struct keytab)) - 1;
  4302. #endif /* PRINTSWI */
  4303.  
  4304. static int
  4305. setprinter(xx) int xx; {
  4306.     int x, y;
  4307.     char * s;
  4308.     char * defname = NULL;
  4309.  
  4310. #ifdef BPRINT
  4311.     char portbuf[64];
  4312.     long portspeed = 0L;
  4313.     int portparity = 0;
  4314.     int portflow = 0;
  4315. #endif /* BPRINT */
  4316.  
  4317. #ifdef PRINTSWI
  4318.     int c, i, n, wild, confirmed = 0;    /* Workers */
  4319.     int getval = 0;            /* Whether to get switch value */
  4320.     struct stringint {            /* Temporary array for switch values */
  4321.     char * sval;
  4322.     int ival;
  4323.     } pv[PRN_MAX+1];
  4324.     struct FDB sw, of, cm;        /* FDBs for each parse function */
  4325.     int haveque = 0;
  4326. #endif /* PRINTSWI */
  4327.  
  4328. #ifdef NT
  4329.     struct keytab * printtab = NULL, * _printtab = NULL;
  4330.     int nprint = 0, printdef=0;
  4331. #endif /* NT */
  4332.  
  4333. #ifdef OS2
  4334.     defname = "PRN";            /* default */
  4335. #else
  4336. #ifdef VMS
  4337.     defname = "LPT:";
  4338. #else
  4339. #ifdef UNIX
  4340.     defname = "|lpr";
  4341. #endif /* UNIX */
  4342. #endif /* VMS */
  4343. #endif /* OS2 */
  4344.  
  4345. #ifdef PRINTSWI
  4346. #ifdef NT
  4347.     haveque = Win32EnumPrt(&printtab,&_printtab,&nprint,&printdef);
  4348.     haveque = haveque && nprint;
  4349. #endif /* NT */
  4350.  
  4351.     for (i = 0; i <= PRN_MAX; i++) {    /* Initialize switch values */
  4352.     pv[i].sval = NULL;        /* to null pointers */
  4353.     pv[i].ival = -1;        /* and -1 int values */
  4354.     }
  4355.     if (xx == XYBDCP) {            /* SET BPRINTER == /BIDIRECTIONAL */
  4356.     pv[PRN_BID].ival = 1;
  4357.     pv[PRN_OUT].ival = 0;
  4358.     }
  4359.  
  4360.     /* Initialize defaults based upon current printer settings */
  4361.     if (printername) {
  4362.         defname = printername;
  4363.         switch (printertype) {
  4364.       case PRT_WIN: pv[PRN_WIN].ival = 1; break;
  4365.       case PRT_DOS: pv[PRN_DOS].ival = 1; break;
  4366.       case PRT_PIP: pv[PRN_PIP].ival = 1; break;
  4367.       case PRT_FIL: pv[PRN_FIL].ival = 1; break;
  4368.       case PRT_NON: pv[PRN_NON].ival = 1; break;
  4369.         }
  4370.     }
  4371. #ifdef BPRINT
  4372.     /* only set the BIDI flag if we are bidi */
  4373.     if (printbidi)
  4374.         pv[PRN_BID].ival = 1;
  4375.  
  4376.     /* serial port parameters may be set for non-bidi devices */
  4377.     pv[PRN_SPD].ival = pportspeed / 10L;
  4378.     pv[PRN_PAR].ival = pportparity;
  4379.     pv[PRN_FLO].ival = pportflow;
  4380. #endif /* BPRINT */
  4381.     if (printtimo)
  4382.         pv[PRN_TMO].ival = printtimo;
  4383.     if (printterm) {
  4384.         pv[PRN_TRM].ival = 1;
  4385.         makestr(&pv[PRN_TRM].sval,printterm);
  4386.     }
  4387.     if (printsep) {
  4388.         pv[PRN_SEP].ival = 1;
  4389.         makestr(&pv[PRN_SEP].sval,printsep);
  4390.     }
  4391.     if (txt2ps) {
  4392.         pv[PRN_PS].ival = 1;
  4393.         pv[PRN_WID].ival = ps_width;
  4394.         pv[PRN_LEN].ival = ps_length;
  4395.     } else {
  4396.         pv[PRN_RAW].ival = 1;
  4397.     }
  4398.  
  4399.     /* Set up chained parse functions... */
  4400.  
  4401.     cmfdbi(&sw,                /* First FDB - command switches */
  4402.        _CMKEY,            /* fcode */
  4403.        "Switch",            /* hlpmsg */
  4404.        "",                /* default */
  4405.        "",                /* addtl string data */
  4406.        nprnswi,            /* addtl numeric data 1: tbl size */
  4407.        4,                /* addtl numeric data 2: 4 = cmswi */
  4408.        xxstring,            /* Processing function */
  4409.        prntab,            /* Keyword table */
  4410.        &cm                /* Pointer to next FDB */
  4411.        );
  4412.     cmfdbi(&cm,                /* Second fdb for confirmation */
  4413.        _CMCFM,            /* fcode */
  4414.        "",                /* hlpmsg */
  4415.        "",                /* default */
  4416.        "",                /* addtl string data */
  4417.        0,                /* addtl numeric data 1 */
  4418.        0,                /* addtl numeric data 2 */
  4419.        NULL,
  4420.        NULL,
  4421.        &of
  4422.        );
  4423.     cmfdbi(&of,                /* Third FDB for printer name */
  4424.        _CMOFI,            /* fcode */
  4425.        "Printer or file name",    /* hlpmsg */
  4426.        defname,            /* default */
  4427.        "",                /* addtl string data */
  4428.        0,                /* addtl numeric data 1: tbl size */
  4429.        0,                /* addtl numeric data 2: 4 = cmswi */
  4430.        xxstring,            /* Processing function */
  4431.        NULL,            /* Nothing */
  4432.        NULL
  4433.        );
  4434.  
  4435.     while (1) {                /* Parse 0 or more switches */
  4436.     x = cmfdb(&sw);            /* Parse switch or other thing */
  4437.     debug(F101,"setprinter cmfdb","",x);
  4438.     if (x < 0)            /* Error */
  4439.       goto xsetprn;            /* or reparse needed */
  4440.     if (cmresult.fcode != _CMKEY)    /* Break out if not a switch */
  4441.       break;
  4442.     if (cmresult.fdbaddr != &sw)    /* Advanced usage :-) */
  4443.       break;
  4444.     c = cmgbrk();            /* Get break character */
  4445.     getval = (c == ':' || c == '='); /* to see how they ended the switch */
  4446.     n = cmresult.nresult;        /* Numeric result = switch value */
  4447.     debug(F101,"setprinter switch","",n);
  4448.  
  4449.     switch (n) {            /* Process the switch */
  4450.       case PRN_PS:                  /* Text to Postscript */
  4451.             pv[PRN_PS].ival = 1;
  4452.         pv[PRN_BID].ival = 0;
  4453.         pv[PRN_OUT].ival = 1;
  4454.             pv[PRN_RAW].ival = 0;
  4455.             break;
  4456.  
  4457.       case PRN_RAW:            /* Non-Postscript */
  4458.             pv[PRN_PS].ival = 0;
  4459.             pv[PRN_RAW].ival = 1;
  4460.             break;
  4461.  
  4462.       case PRN_BID:            /* Bidirectional */
  4463.         pv[PRN_BID].ival = 1;
  4464.         pv[PRN_OUT].ival = 0;
  4465.             pv[PRN_PS].ival = 0;
  4466.             pv[PRN_RAW].ival = 1;
  4467.         break;
  4468.  
  4469.       case PRN_OUT:            /* Output-only */
  4470.         pv[PRN_OUT].ival = 1;
  4471.         pv[PRN_BID].ival = 0;
  4472.             pv[PRN_PS].ival = 0;
  4473.             pv[PRN_RAW].ival = 1;
  4474.         break;
  4475.  
  4476.       case PRN_NON:            /* NONE */
  4477.         pv[n].ival = 1;
  4478.         pv[PRN_SPD].ival = 0;
  4479.         pv[PRN_PAR].ival = 0;
  4480.         pv[PRN_FLO].ival = FLO_KEEP;
  4481.         break;
  4482.  
  4483. #ifdef UNIX
  4484.       case PRN_WIN:
  4485. #endif /* UNIX */
  4486.       case PRN_DOS:            /* DOS printer name */
  4487.       case PRN_FIL:            /* Or filename */
  4488.       case PRN_PIP:
  4489.         if (pv[n].sval) free(pv[n].sval);
  4490.         pv[n].sval = NULL;
  4491.         pv[PRN_NON].ival = 0;    /* Zero any previous selections */
  4492.         pv[PRN_WIN].ival = 0;
  4493.         pv[PRN_DOS].ival = 0;
  4494.         pv[PRN_FIL].ival = 0;
  4495.         pv[PRN_PIP].ival = 0;
  4496.         pv[n].ival = 1;        /* Flag this one */
  4497.         if (!getval) break;        /* No value wanted */
  4498.  
  4499.         if (n == PRN_FIL) {        /* File, check accessibility */
  4500.         int wild = 0;
  4501.         if ((x = cmiofi("Filename","kermit.prn",&s,&wild,xxstring))< 0)
  4502.           if (x == -9) {
  4503.               if (zchko(s) < 0) {
  4504.               printf("Can't create \"%s\"\n",s);
  4505.               return(x);
  4506.               }
  4507.           } else goto xsetprn;
  4508.         if (iswild(s)) {
  4509.             printf("?A single file please\n");
  4510.             return(-9);
  4511.         }
  4512.                 pv[PRN_SPD].ival = 0;
  4513.                 pv[PRN_PAR].ival = 0;
  4514.                 pv[PRN_FLO].ival = FLO_KEEP;
  4515.         } else if ((x = cmfld(n == PRN_DOS ? /* Value wanted - parse it */
  4516.                "DOS printer device name" : /* Help message */
  4517.                (n == PRN_PIP ?
  4518.                "Program name" :
  4519.                "Filename"),
  4520.                n == PRN_DOS ?
  4521.                "PRN" :    /* Default */
  4522.                "",
  4523.                &s,
  4524.                xxstring
  4525.                )) < 0)
  4526.           goto xsetprn;
  4527.         s = brstrip(s);        /* Strip enclosing braces */
  4528.         while (*s == SP)        /* Strip leading blanks */
  4529.           s++;
  4530.         if (n == PRN_PIP) {        /* If /PIPE: */
  4531.         if (*s == '|') {    /* strip any extraneous pipe sign */
  4532.             s++;
  4533.             while (*s == SP)
  4534.               s++;
  4535.         }
  4536.                 pv[PRN_SPD].ival = 0;
  4537.                 pv[PRN_PAR].ival = 0;
  4538.                 pv[PRN_FLO].ival = FLO_KEEP;
  4539.         }
  4540.         if ((y = strlen(s)) > 0)    /* Anything left? */
  4541.           if (pv[n].sval = (char *) malloc(y+1)) /* Yes, keep it */
  4542.         strcpy(pv[n].sval,s);
  4543.         break;
  4544. #ifdef NT
  4545.       case PRN_WIN:            /* Windows queue name */
  4546.         if (pv[n].sval) free(pv[n].sval);
  4547.         pv[n].sval = NULL;
  4548.         pv[PRN_NON].ival = 0;
  4549.         pv[PRN_DOS].ival = 0;
  4550.         pv[PRN_FIL].ival = 0;
  4551.         pv[n].ival = 1;
  4552.             pv[PRN_SPD].ival = 0;
  4553.             pv[PRN_PAR].ival = 0;
  4554.             pv[PRN_FLO].ival = FLO_KEEP;
  4555.  
  4556.         if (!getval || !haveque)
  4557.           break;
  4558.         if ((x = cmkey(_printtab,nprint,"Print queue name",
  4559.                _printtab[printdef].kwd,xxstring)) < 0) {
  4560.         if (x != -2)
  4561.           goto xsetprn;
  4562.  
  4563.         if (pv[PRN_WIN].sval) free(pv[PRN_WIN].sval);
  4564.         s = atmbuf;
  4565.         if ((y = strlen(s)) > 0)
  4566.           if (pv[n].sval = (char *)malloc(y+1))
  4567.             strcpy(pv[n].sval,s);
  4568.         } else {
  4569.         if (pv[PRN_WIN].sval) free(pv[PRN_WIN].sval);
  4570.         s = printtab[x].kwd;
  4571.         if ((y = strlen(s)) > 0)
  4572.           if (pv[n].sval = (char *)malloc(y+1))
  4573.             strcpy(pv[n].sval,s);
  4574.         }
  4575.         break;
  4576. #endif /* NT */
  4577.  
  4578.       case PRN_SEP:            /* /JOB-HEADER (separator) */
  4579.         if (pv[n].sval) free(pv[n].sval);
  4580.         pv[n].sval = NULL;
  4581.         pv[n].ival = 1;
  4582.         if (!getval) break;
  4583.         if ((x = cmifi("Filename","",&s,&y,xxstring)) < 0)
  4584.           goto xsetprn;
  4585.         if (y) {
  4586.         printf("?Wildcards not allowed\n");
  4587.         x = -9;
  4588.         goto xsetprn;
  4589.         }
  4590.         if ((y = strlen(s)) > 0)
  4591.           if (pv[n].sval = (char *) malloc(y+1))
  4592.         strcpy(pv[n].sval,s);
  4593.         break;
  4594.  
  4595.       case PRN_TMO:            /* /TIMEOUT:number */
  4596.         pv[n].ival = 0;
  4597.         if (!getval) break;
  4598.         if ((x = cmnum("Seconds","0",10,&y,xxstring)) < 0)
  4599.           goto xsetprn;
  4600.         if (y > 999) {
  4601.         printf("?Sorry - 999 is the maximum\n");
  4602.         x = -9;
  4603.         goto xsetprn;
  4604.         } else
  4605.           pv[n].ival = y;
  4606.         break;
  4607.  
  4608.       case PRN_TRM:            /* /END-OF-JOB:string */
  4609.         if (pv[n].sval) free(pv[n].sval);
  4610.         pv[n].sval = NULL;
  4611.         pv[n].ival = 1;
  4612.         if (!getval) break;
  4613.         if ((x = cmfld("String (enclose in braces if it contains spaces)",
  4614.                "",&s,xxstring)) < 0)
  4615.           goto xsetprn;
  4616.         s = brstrip(s);
  4617.         if ((y = strlen(s)) > 0)
  4618.           if (pv[n].sval = (char *) malloc(y+1))
  4619.         strcpy(pv[n].sval,s);
  4620.         break;
  4621.  
  4622. #ifdef BPRINT
  4623.       case PRN_FLO:
  4624.         if (!getval) break;
  4625.         if ((x = cmkey(flotab,nflo,
  4626.                   "Serial printer-port flow control",
  4627.                   "rts/cts",xxstring)) < 0)
  4628.           goto xsetprn;
  4629.         pv[n].ival = x;
  4630.         break;
  4631.  
  4632. #ifndef NOLOCAL
  4633.       case PRN_SPD:
  4634.         if (!getval) break;
  4635.         if ((x = cmkey(spdtab,    /* Speed (no default) */
  4636.                nspd,
  4637.                "Serial printer-port interface speed",
  4638.                "9600",
  4639.                xxstring)
  4640.          ) < 0)
  4641.           goto xsetprn;
  4642.         pv[n].ival = x;
  4643.         break;
  4644. #endif /* NOLOCAL */
  4645.  
  4646.       case PRN_PAR:
  4647.         pv[n].ival = 0;
  4648.         if (!getval) break;
  4649.         if ((x = cmkey(partbl,npar,"Serial printer-port parity",
  4650.                "none",xxstring)) < 0)
  4651.           goto xsetprn;
  4652.         pv[n].ival = x;
  4653.         break;
  4654. #endif /* BPRINT */
  4655.  
  4656. #ifdef OS2
  4657.       case PRN_LEN:
  4658.         if (!getval) break;
  4659.             if ((x = cmnum("PS page length", "66",10,&y,xxstring)) < 0)
  4660.           goto xsetprn;
  4661.         pv[n].ival = y;
  4662.         break;
  4663.  
  4664.       case PRN_WID:
  4665.         if (!getval) break;
  4666.             if ((x = cmnum("PS page width", "80",10,&y,xxstring)) < 0)
  4667.           goto xsetprn;
  4668.         pv[n].ival = y;
  4669.             break;
  4670. #endif /* OS2 */
  4671.  
  4672.       default:
  4673.         printf("?Unexpected switch value - %d\n",cmresult.nresult);
  4674.         x = -9;
  4675.         goto xsetprn;
  4676.     }
  4677.     }
  4678.     line[0] = NUL;            /* Initialize printer name value */
  4679.     switch (cmresult.fcode) {        /* How did we get here? */
  4680.       case _CMOFI:            /* They typed a filename */
  4681.     strcpy(line,cmresult.sresult);    /* Name */
  4682.     wild = cmresult.nresult;    /* Wild flag */
  4683.     if ((x = cmcfm()) < 0)        /* Confirm the command */
  4684.       goto xsetprn;
  4685.     break;
  4686.       case _CMCFM:            /* They entered the command */
  4687.     if (pv[PRN_DOS].ival > 0)
  4688.       strcpy(line,pv[PRN_DOS].sval ? pv[PRN_DOS].sval : "");
  4689.     else if (pv[PRN_WIN].ival > 0)
  4690.       strcpy(line,pv[PRN_WIN].sval ? pv[PRN_WIN].sval : "");
  4691.     else if (pv[PRN_FIL].ival > 0)
  4692.       strcpy(line,pv[PRN_FIL].sval ? pv[PRN_FIL].sval : "");
  4693.     else if (pv[PRN_PIP].ival > 0)
  4694.       strcpy(line,pv[PRN_PIP].sval ? pv[PRN_PIP].sval : "");
  4695.     break;
  4696.       default:                /* By mistake */
  4697.     printf("?Unexpected function code: %d\n",cmresult.fcode);
  4698.     x = -9;
  4699.     goto xsetprn;
  4700.     }
  4701.  
  4702. #else  /* No PRINTSWI */
  4703.  
  4704.     if ((x = cmofi("Printer or file name",defname,&s,xxstring)) < 0)
  4705.       return(x);
  4706.     if (x > 1) {
  4707.     printf("?Directory names not allowed\n");
  4708.     return(-9);
  4709.     }
  4710.     while (*s == SP || *s == HT) s++;    /* Trim leading whitespace */
  4711.     strcpy(line,s);            /* Make a temporary safe copy */
  4712.     if ((x = cmcfm()) < 0) return(x);    /* Confirm the command */
  4713. #endif /* PRINTSWI */
  4714.  
  4715. #ifdef IKSD
  4716.     if (inserver && (isguest
  4717. #ifndef NOSERVER
  4718.              || !ENABLED(en_pri)
  4719. #endif /* NOSERVER */
  4720.              )) {
  4721.         printf("Sorry, printing disabled\r\n");
  4722.         return(success = 0);
  4723.     }
  4724. #endif /* ISKD */
  4725.  
  4726. #ifdef PRINTSWI
  4727. #ifdef BPRINT
  4728.     if (printbidi) {            /* If bidi printing active */
  4729. #ifndef UNIX
  4730.     bprtstop();            /* Stop it before proceeding */
  4731. #endif /* UNIX */
  4732.     printbidi = 0;
  4733.     }
  4734.     if (pv[PRN_SPD].ival > 0) {
  4735.         portspeed = (long) pv[PRN_SPD].ival * 10L;
  4736.         if (portspeed == 70L) portspeed = 75L;
  4737.     }
  4738.     if (pv[PRN_PAR].ival > 0)
  4739.         portparity = pv[PRN_PAR].ival;
  4740.     if (pv[PRN_FLO].ival > 0)
  4741.         portflow = pv[PRN_FLO].ival;
  4742. #endif /* BPRINT */
  4743. #endif /* PRINTSWI */
  4744.  
  4745.     s = line;                /* Printer name, if given */
  4746.  
  4747. #ifdef OS2ORUNIX
  4748. #ifdef PRINTSWI
  4749.     if (pv[PRN_PIP].ival > 0) {        /* /PIPE was given? */
  4750.     printpipe = 1;
  4751.     noprinter = 0;
  4752.     if (*s ==  '|') {        /* It might still have a pipe sign */
  4753.         s++;            /* if name give later */
  4754.         while (*s == SP)        /* so remove it and spaces */
  4755.           s++;
  4756.     }
  4757.     } else
  4758. #endif /* PRINTSWI */
  4759.       if (*s == '|') {            /* Or pipe implied by name? */
  4760.     s++;                /* Point past pipe sign */
  4761.     while (*s == SP)        /* Gobble whitespace */
  4762.       s++;
  4763.     if (*s) {
  4764.         printpipe = 1;
  4765.         noprinter = 0;
  4766.     }
  4767.     }
  4768.  
  4769. #ifdef PRINTSWI
  4770. #ifdef BPRINT
  4771.     if (printpipe && pv[PRN_BID].ival > 0) {
  4772.     printf("?Sorry, pipes not allowed for bidirectional printer\n");
  4773.     return(-9);
  4774.     }
  4775. #endif /* BPRINT */
  4776. #endif /* PRINTSWI */
  4777. #endif /* OS2ORUNIX */
  4778.  
  4779. #ifdef OS2
  4780.     if ( pv[PRN_PS].ival > 0 ) {
  4781.         txt2ps = 1;
  4782.         ps_width = pv[PRN_WID].ival <= 0 ? 80 : pv[PRN_WID].ival;
  4783.         ps_length = pv[PRN_LEN].ival <= 0 ? 66 : pv[PRN_LEN].ival;
  4784.     }
  4785. #endif /* OS2 */
  4786.  
  4787.     y = strlen(s);            /* Length of name of new print file */
  4788.     if (y > 0
  4789. #ifdef OS2
  4790.     && ((y != 3) || (ckstrcmp(s,"PRN",3,0) != 0))
  4791. #endif /* OS2 */
  4792.     ) {
  4793.     if (printername) {        /* Had a print file before? */
  4794.         free(printername);        /* Remove its name */
  4795.         printername = NULL;
  4796.     }
  4797.     printername = (char *) malloc(y + 1); /* Allocate space for it */
  4798.     if (!printername) {
  4799.         printf("?Memory allocation failure\n");
  4800.         return(-9);
  4801.     }
  4802.     strcpy(printername,s);    /* Copy new name to new space */
  4803.     debug(F110,"printername",printername,0);
  4804.     }
  4805.  
  4806. #ifdef PRINTSWI
  4807.     /* Set printer type from switches that were given explicitly */
  4808.  
  4809.     if (pv[PRN_NON].ival > 0) {        /* No printer */
  4810.     printertype = PRT_NON;
  4811.     noprinter = 1;
  4812.     printpipe = 0;
  4813.     } else if (pv[PRN_FIL].ival > 0) {    /* File */
  4814.     printertype = PRT_FIL;
  4815.     noprinter = 0;
  4816.     printpipe = 0;
  4817.     } else if (pv[PRN_PIP].ival > 0) {    /* Pipe */
  4818.     printertype = PRT_PIP;
  4819.     noprinter = 0;
  4820.     printpipe = 1;
  4821.     } else if (pv[PRN_WIN].ival > 0) {    /* Windows print queue */
  4822.     printertype = PRT_WIN;
  4823.     noprinter = 0;
  4824.     printpipe = 0;
  4825.     } else if (pv[PRN_DOS].ival > 0) {    /* DOS device */
  4826.     printertype = PRT_DOS;
  4827.     noprinter = 0;
  4828.     printpipe = 0;
  4829.     } else if (line[0]) {        /* Name given without switches */
  4830.     noprinter = 0;
  4831.     printertype = printpipe ? PRT_PIP : PRT_DOS;
  4832. #ifdef NT
  4833.         if (!lookup(_printtab,line,nprint,&x)) {
  4834.             printertype = PRT_WIN;
  4835.             if (pv[PRN_WIN].sval) free(pv[PRN_WIN].sval);
  4836.             if (printername) {        /* Had a print file before? */
  4837.                 free(printername);    /* Remove its name */
  4838.                 printername = NULL;
  4839.             }
  4840.             pv[PRN_WIN].sval = NULL;
  4841.             pv[PRN_WIN].ival = 1;
  4842. #ifdef COMMENT
  4843.             pv[PRN_NON].ival = 0;    /* These aren't needed */
  4844.             pv[PRN_DOS].ival = 0;
  4845.             pv[PRN_FIL].ival = 0;
  4846. #endif /* COMMENT */
  4847.             s = printtab[x].kwd;    /* Get full new name */
  4848.             if ((y = strlen(s)) > 0) {
  4849.                 makestr(&pv[PRN_WIN].sval,s);
  4850.                 makestr(&printername,s);
  4851.                 if (!printername) {
  4852.                     printf("?Memory allocation failure\n");
  4853.                     return(-9);
  4854.                 }
  4855.                 debug(F110,"printername",printername,0);
  4856.             }
  4857.         }
  4858. #endif /* NT */
  4859.     }
  4860.  
  4861. #ifdef BPRINT
  4862.     /* Port parameters may be set for non-bidi mode */
  4863.  
  4864.     pportspeed = portspeed;        /* Set parameters */
  4865.     pportparity = portparity;
  4866.     pportflow = portflow;
  4867.  
  4868.     if (pv[PRN_BID].ival > 0) {        /* Bidirectional */
  4869. #ifdef UNIX
  4870.     printbidi = 1;            /* (just to test parsing...) */
  4871. #else
  4872.     printbidi = bprtstart();    /* Start bidirectional printer */
  4873. #endif /* UNIX */
  4874.     return(success = printbidi);
  4875.     } else
  4876.       printbidi = 0;            /* Not BPRINTER, unset flag */
  4877. #endif /* BPRINT */
  4878.  
  4879.     if (pv[PRN_TMO].ival > -1) {    /* Take care of timeout */
  4880.     printtimo = pv[PRN_TMO].ival;
  4881.     }
  4882.     if (pv[PRN_TRM].ival > 0) {        /* Termination string */
  4883.     if (printterm) {
  4884.         free(printterm);
  4885.         printterm = NULL;
  4886.     }
  4887.     if (pv[PRN_TRM].sval)
  4888.       makestr(&printterm,pv[PRN_TRM].sval);
  4889.     }
  4890.     if (pv[PRN_SEP].ival > 0) {        /* and separator file */
  4891.     if (printsep) {
  4892.         free(printsep);
  4893.         printsep = NULL;
  4894.     }
  4895.     if (pv[PRN_SEP].sval)
  4896.       makestr(&printsep,pv[PRN_SEP].sval);
  4897.     }
  4898. #endif /* PRINTSWI */
  4899.  
  4900. #ifdef UNIXOROSK
  4901.     if (!printpipe
  4902. #ifdef PRINTSWI
  4903.     && !noprinter
  4904. #endif /* PRINTSWI */
  4905.     ) {                /* File - check access */
  4906.     if (zchko(s) < 0) {
  4907.         printf("?Access denied - %s\n",s);
  4908.         x = -9;
  4909.         goto xsetprn;
  4910.     }
  4911.     }
  4912. #endif /* UNIXOROSK */
  4913.  
  4914.     x = 1;                /* Return code */
  4915.  
  4916.   xsetprn:                /* Common exit */
  4917. #ifdef PRINTSWI
  4918.     for (i = 0; i <= PRN_MAX; i++) {    /* Free malloc'd memory */
  4919.     if (pv[i].sval)
  4920.       free(pv[i].sval);
  4921.     }
  4922. #endif /* PRINTSWI */
  4923.     success = (x > 0) ? 1 : 0;
  4924.     return(x);
  4925. }
  4926.  
  4927. /*  D O P R M  --  Set a parameter.  */
  4928. /*
  4929.  Returns:
  4930.   -2: illegal input
  4931.   -1: reparse needed
  4932.    0: success
  4933. */
  4934. int
  4935. doprm(xx,rmsflg) int xx, rmsflg; {
  4936.     int i = 0, x = 0, y = 0, z = 0;
  4937.     long zz = 0L;
  4938.     char *s = NULL, *p = NULL;
  4939. #ifdef OS2
  4940.     char portbuf[64];
  4941.     long portspeed = 0L;
  4942.     int portparity = 0;
  4943.     int portflow = 0;
  4944. #endif /* OS2 */
  4945.  
  4946. #ifdef OS2
  4947.     if (xx == XYMSK)
  4948.       return(setmsk());
  4949. #endif /* OS2 */
  4950.  
  4951.     if (xx == XYFLAG) {            /* SET FLAG */
  4952.     extern int ooflag;
  4953.     return(success = seton(&ooflag));
  4954.     }
  4955.     if (xx == XYPRTR            /* SET PRINTER (or BPRINTER) */
  4956. #ifdef BPRINT
  4957.     || xx == XYBDCP
  4958. #endif /* BPRINT */
  4959.     )
  4960.       return(setprinter(xx));
  4961.  
  4962. switch (xx) {
  4963.  
  4964. #ifdef ANYX25                /* SET X25 ... */
  4965. case XYX25:
  4966.     return(setx25());
  4967.  
  4968. #ifndef IBMX25
  4969. case XYPAD:                /* SET PAD ... */
  4970.     return(setpadp());
  4971. #endif /* IBMX25 */
  4972. #endif /* ANYX25 */
  4973.  
  4974. #ifndef NOXFER
  4975. case XYEOL:    /* These have all been moved to set send/receive... */
  4976. case XYLEN:     /* Let the user know what to do. */
  4977. case XYMARK:
  4978. case XYNPAD:
  4979. case XYPADC:
  4980. case XYTIMO:
  4981.     printf("...Use SET SEND or SET RECEIVE instead.\n");
  4982.     printf("Type HELP SET SEND or HELP SET RECEIVE for more info.\n");
  4983.     return(success = 0);
  4984.  
  4985. case XYATTR:                /* File Attribute packets */
  4986.     return(setat(rmsflg));
  4987.  
  4988. case XYIFD:                /* Incomplete file disposition */
  4989.     if ((y = cmkey(ifdatab,3,"","auto",xxstring)) < 0) return(y);
  4990.     if ((x = cmcfm()) < 0) return(x);
  4991.     if (rmsflg) {
  4992.     sstate = setgen('S',
  4993.             "310",
  4994.             y == 0 ? "0" : (y == 1 ? "1" : "2"),
  4995.              ""
  4996.             );
  4997.     return((int) sstate);
  4998.     } else {
  4999.     keep = y;
  5000.     return(success = 1);
  5001.  
  5002.     }
  5003. #endif /* NOXFER */
  5004.  
  5005. #ifndef NOSPL
  5006. case XYINPU:                /* SET INPUT */
  5007.     return(setinp());
  5008. #endif /* NOSPL */
  5009.  
  5010. #ifdef NETCONN
  5011. case XYNET: {                /* SET NETWORK */
  5012.  
  5013.     struct FDB k1, k2;
  5014.  
  5015.     cmfdbi(&k1,_CMKEY,"","","",nnetkey, 0, xxstring, netkey, &k2);
  5016.     cmfdbi(&k2,_CMKEY,"","","",nnets,   0, xxstring, netcmd, NULL);
  5017.  
  5018. #ifdef OS2     /* Hide network-type keywords for networks not installed */
  5019.     for (z = 0; z < nnets; z++) {
  5020.     if (netcmd[z].kwval == NET_TCPB && tcp_avail == 0)
  5021.       netcmd[z].flgs =  CM_INV;
  5022. #ifdef DECNET
  5023.     else if (netcmd[z].kwval == NET_DEC  && dnet_avail == 0)
  5024.       netcmd[z].flgs =  CM_INV;
  5025. #endif /* DECNET */
  5026. #ifdef CK_NETBIOS
  5027.     else if (netcmd[z].kwval == NET_BIOS && netbiosAvail == 0)
  5028.       netcmd[z].flgs =  CM_INV;
  5029. #endif /* CK_NETBIOS */
  5030. #ifdef SUPERLAT
  5031.     else if (netcmd[z].kwval == NET_SLAT  && slat_avail == 0)
  5032.       netcmd[z].flgs =  CM_INV;
  5033. #endif /* SUPERLAT */
  5034.     }
  5035.     if (tcp_avail)            /* Default network type */
  5036.       strcpy(tmpbuf,"tcp/ip");
  5037. #ifdef DECNET
  5038.     else if (dnet_avail)
  5039.       strcpy(tmpbuf,"decnet");
  5040. #endif /* DECNET */
  5041. #ifdef SUPERLAT
  5042.     else if (slat_avail)
  5043.       strcpy(tmpbuf,"superlat");
  5044. #endif /* SUPERLAT */
  5045. #ifdef CK_NETBIOS
  5046.     else if (netbiosAvail)
  5047.       strcpy(tmpbuf,"netbios");
  5048. #endif /* CK_NETBIOS */
  5049.     else strcpy(tmpbuf,"named-pipe");
  5050. #else
  5051. #ifdef TCPSOCKET
  5052.     strcpy(tmpbuf,"tcp/ip");
  5053. #else
  5054. #ifdef ANYX25
  5055.     strcpy(tmpbuf,"x.25");
  5056. #else
  5057.     strcpy(tmpbuf,"");
  5058. #endif /* ANYX25 */
  5059. #endif /* TCPSOCKET */
  5060. #endif /* OS2 */
  5061.  
  5062.     x = cmfdb(&k1);
  5063.     if (x < 0) {            /* Error */
  5064.     if (x == -2 || x == -9)
  5065.       printf("?No keywords match: \"%s\"\n",atmbuf);
  5066.     return(x);
  5067.     }
  5068.     z = cmresult.nresult;        /* Keyword value */
  5069.     if (cmresult.fdbaddr == &k1) {    /* Which table? */
  5070. #ifndef NOSPL
  5071. #ifndef NODIAL
  5072.     if (z == XYNET_D)
  5073.       return(parsdir(1));
  5074. #endif /* NODIAL */
  5075. #endif /* NOSPL */
  5076.     if ((z = cmkey(netcmd,nnets,"",tmpbuf,xxstring)) < 0)
  5077.       return(z);
  5078.     }
  5079.  
  5080. #ifdef NETCMD
  5081.     if (z == NET_CMD && nopush) {
  5082.         printf("\n?Sorry, access to external commands is disabled\n");
  5083.     return(-9);
  5084.     }
  5085. #endif /* NETCMD */
  5086.  
  5087. #ifndef NOPUSH
  5088. #ifdef NETPTY
  5089.     if (z == NET_PTY && nopush) {
  5090.         printf("\n?Sorry, access to external commands is disabled\n");
  5091.     return(-9);
  5092.     }
  5093. #endif /* NETPTY */
  5094. #endif /* NOPUSH */
  5095.  
  5096. #ifdef OS2
  5097.     if (z == NET_TCPB && tcp_avail == 0) {
  5098.         printf("\n?Sorry, either TCP/IP is not available on this system or\n\
  5099. necessary DLLs did not load.  Use SHOW NETWORK to check network status.\n");
  5100.     return(-9);
  5101. #ifdef CK_NETBIOS
  5102.     } else if (z == NET_BIOS && netbiosAvail == 0) {
  5103.     printf("\n?Sorry, NETBIOS is not available on this system.\n") ;
  5104.     return(-9);
  5105. #endif /* CK_NETBIOS */
  5106. #ifdef DECNET
  5107.     } else if (z == NET_DEC && dnet_avail == 0) {
  5108.     printf("\n?Sorry, DECnet is not available on this system.\n") ;
  5109.     return(-9);
  5110. #endif /* DECNET */
  5111. #ifdef SUPERLAT
  5112.     } else if (z == NET_SLAT && slat_avail == 0) {
  5113.     printf("\n?Sorry, SuperLAT is not available on this system.\n") ;
  5114.     return(-9);
  5115. #endif /* SUPERLAT */
  5116.     }
  5117. #endif /* OS2 */
  5118.  
  5119. #ifdef NPIPEORBIOS
  5120.     if (z == NET_PIPE ||         /* Named pipe -- also get pipename */
  5121.     z == NET_BIOS) {        /* NETBIOS -- also get local name */
  5122.     char *defnam;
  5123. #ifdef CK_NETBIOS
  5124.     char tmpnbnam[NETBIOS_NAME_LEN+1];
  5125. #endif /* CK_NETBIOS */
  5126.     /* Construct default name  */
  5127.     if (z == NET_PIPE) {        /* Named pipe */
  5128.         defnam = "kermit";        /* Default name is always "kermit" */
  5129.     } else {            /* NetBIOS */
  5130.         if (NetBiosName[0] != SP) {    /* If there is already a name, */
  5131.         char *p = NULL;
  5132.                 int n;        /* use it as the default. */
  5133.         ckstrncpy(tmpnbnam,NetBiosName,NETBIOS_NAME_LEN+1);
  5134.                 /* convert trailing spaces to NULs */
  5135.         p = &tmpnbnam[NETBIOS_NAME_LEN-1];
  5136.         while (*p == SP) {
  5137.             *p = NUL;
  5138.             p--;
  5139.         }
  5140.         defnam = tmpnbnam;
  5141.         } else if (*myhost)        /* Otherwise use this PC's host name */
  5142.           defnam = (char *) myhost;
  5143.         else            /* Otherwise use "kermit" */
  5144.           defnam = "kermit";
  5145.     }
  5146.     if ((y = cmtxt((z == NET_PIPE) ? "pipe name" : "local NETBIOS name",
  5147.                defnam, &s, xxstring)) < 0)
  5148.       return(y);
  5149. #ifdef NPIPE
  5150.     pipename[0] = NUL;
  5151. #endif /* NPIPE */
  5152.     if ((y = (int) strlen(s)) < 1) {
  5153.         printf("?You must also specify a %s name\n",
  5154.            (z == NET_PIPE) ? "pipe" : "local NETBIOS" );
  5155.          return(-9);
  5156.     }
  5157. #ifdef CK_NETBIOS
  5158.     if (z == NET_BIOS) {
  5159.         if ( !netbiosAvail ) {
  5160.         printf("?NETBIOS support is not available on this system.\n") ;
  5161.         return(-9) ;
  5162.         }
  5163.         if ( y - NETBIOS_NAME_LEN > 0) {
  5164.         printf("?NETBIOS name too long, %ld maximum\n",
  5165.                NETBIOS_NAME_LEN);
  5166.         return(-9);
  5167.         } else if ( !strcmp(s,tmpnbnam) ) {
  5168.               nettype = z;        /* Returning to old connection... */
  5169.         return(success = 1);    /* Done */
  5170.         } else if (strcmp("                ",NetBiosName)) {
  5171.            printf("?Local NETBIOS name already assigned to \"%s\"\n",
  5172.                NetBiosName);
  5173.            return(-9) ;
  5174.        } else {
  5175.         NCB ncb ;
  5176.         APIRET rc ;
  5177.         strcpy(NetBiosName,s);
  5178.         for (x = y; x < NETBIOS_NAME_LEN; x++)
  5179.           NetBiosName[x] = SP;
  5180.         NetBiosName[NETBIOS_NAME_LEN] = NUL;
  5181.         printf("Verifying \"%s\" is a unique NetBIOS node name ...\n",
  5182.                NetBiosName) ;
  5183.         rc = NCBAddName( NetbeuiAPI,
  5184.                 &ncb, NetBiosAdapter, NetBiosName ) ;
  5185.         if ( rc ) {
  5186.             printf(
  5187.         "?Sorry, \"%s\" is already in use by another NetBIOS node.\n",
  5188.                NetBiosName);
  5189.             for ( x=0; x < NETBIOS_NAME_LEN; x++)
  5190.               NetBiosName[x] = SP ;
  5191.             return(-9) ;
  5192.         }
  5193.         }
  5194.     }
  5195. #endif /* CK_NETBIOS */
  5196. #ifdef NPIPE
  5197.     if (z == NET_PIPE)
  5198.       ckstrncpy(pipename,s,PIPENAML);
  5199. #endif /* NPIPE */
  5200.     } else
  5201. #endif /* NPIPEORBIOS */
  5202. #ifdef DECNET
  5203.       if (z == NET_DEC) {
  5204.           /* Determine if we are using LAT or CTERM */
  5205.           if ((y = cmkey(dnettab,ndnet,"DECNET protocol","lat",xxstring)) < 0)
  5206.               return(y);
  5207.           if ((x = cmcfm()) < 0) return(x);
  5208.           ttnproto = y;
  5209.       } else
  5210. #endif /* DECNET */
  5211. #ifdef NETDLL
  5212.     if (z == NET_DLL) {
  5213.         /* Find out which DLL they are using */
  5214.         char dllname[256]="";
  5215.         char * p=NULL;
  5216.     if ((x = cmifi("Dynamic load library","",&p,&y,xxstring)) < 0) {
  5217.         if (x == -3) {
  5218.         printf("?Name of dynamic load library (dll) required\n");
  5219.         return(-9);
  5220.         }
  5221.         return(x);
  5222.     }
  5223.         ckstrncpy(dllname,p,256);
  5224.         if ((x = cmcfm()) < 0) return(x);
  5225.  
  5226.         /* Try to load the dll */
  5227.         if (netdll_load(dllname) < 0)
  5228.             return(success = 0);
  5229.         else {
  5230.             nettype = z;
  5231.             return(success = 1);
  5232.         }
  5233.     } else
  5234. #endif /* NETDLL */
  5235.       if ((x = cmcfm()) < 0) return(x);
  5236.     nettype = z;
  5237.     if (
  5238. #ifdef DECNET
  5239.     (nettype != NET_DEC)  &&
  5240. #endif /* DECNET */
  5241. #ifdef NPIPE
  5242.     (nettype != NET_PIPE) &&
  5243. #endif /* NPIPE */
  5244. #ifdef CK_NETBIOS
  5245.     (nettype != NET_BIOS) &&
  5246. #endif /* CK_NETBIOS */
  5247. #ifdef NETFILE
  5248.     (nettype != NET_FILE) &&
  5249. #endif /* NETFILE */
  5250. #ifdef NETCMD
  5251.         (nettype != NET_CMD) &&
  5252. #endif /* NETCMD */
  5253. #ifdef NETPTY
  5254.         (nettype != NET_PTY) &&
  5255. #endif /* NETPTY */
  5256. #ifdef NETDLL
  5257.         (nettype != NET_DLL) &&
  5258. #endif /* NETDLL */
  5259. #ifdef SSH
  5260.         (nettype != NET_SSH) &&
  5261. #endif /* SSH */
  5262. #ifdef SUPERLAT
  5263.     (nettype != NET_SLAT) &&
  5264. #endif /* SUPERLAT */
  5265.     (nettype != NET_SX25) &&
  5266.     (nettype != NET_VX25) &&
  5267. #ifdef IBMX25
  5268.     (nettype != NET_IX25) &&
  5269. #endif /* IBMX25 */
  5270.         (nettype != NET_TCPB)) {
  5271.     printf("?Network type not supported\n");
  5272.     return(success = 0);
  5273.     } else {
  5274.     return(success = 1);
  5275.     }
  5276. }
  5277.  
  5278. #ifndef NOTCPOPTS
  5279. #ifdef TCPSOCKET
  5280. case XYTCP:
  5281. if ((z = cmkey(tcpopt,ntcpopt,"TCP option","nodelay",xxstring)) < 0)
  5282.    return(z);
  5283.  
  5284.    switch (z) {
  5285.      case XYTCP_ADDRESS:
  5286.        if ((y = cmtxt("preferred IP Address for TCP connections","",
  5287.               &s,xxstring)) < 0)
  5288.      return(y);
  5289.        if (tcp_address) {
  5290.        free(tcp_address);        /* Free any previous storage */
  5291.        tcp_address = NULL;
  5292.        }
  5293.        if (s == NULL || *s == NUL) {    /* If none given */
  5294.        tcp_address = NULL;        /* remove the override string */
  5295.        return(success = 1);
  5296.        } else if (tcp_address = malloc(strlen(s)+1)) { /* Make new storage */
  5297.        strcpy(tcp_address,s);    /* Copy string to new storage */
  5298.        return(success = 1);
  5299.        } else
  5300.      return(success = 0);
  5301. #ifdef SO_KEEPALIVE
  5302.    case XYTCP_KEEPALIVE:
  5303.       if ((z = cmkey(onoff,2,"","on",xxstring)) < 0) return(z);
  5304.       if ((y = cmcfm()) < 0) return(y);
  5305.       success = keepalive(z) ;
  5306.       return(success);
  5307. #endif /* SO_KEEPALIVE */
  5308. #ifdef SO_DONTROUTE
  5309.    case XYTCP_DONTROUTE:
  5310.       if ((z = cmkey(onoff,2,"","off",xxstring)) < 0) return(z);
  5311.       if ((y = cmcfm()) < 0) return(y);
  5312.       success = dontroute(z) ;
  5313.       return(success);
  5314. #endif /* SO_DONTROUTE */
  5315. #ifdef TCP_NODELAY
  5316.    case XYTCP_NODELAY:
  5317.       if ((z = cmkey(onoff,2,"","off",xxstring)) < 0) return(z);
  5318.       if ((y = cmcfm()) < 0) return(y);
  5319.       success = no_delay(z) ;
  5320.       return(success);
  5321.    case XYTCP_NAGLE: /* The inverse of NODELAY */
  5322.       if ((z = cmkey(onoff,2,"","on",xxstring)) < 0) return(z);
  5323.       if ((y = cmcfm()) < 0) return(y);
  5324.       success = no_delay(!z) ;
  5325.       return(success);
  5326. #endif /* TCP_NODELAY */
  5327. #ifdef SO_LINGER
  5328.     case XYTCP_LINGER:
  5329.       if ((z = cmkey(onoff,2,"","on",xxstring)) < 0)
  5330.     return(z);
  5331.       if (z) {                /* if on, we need a timeout value */
  5332.       if ((x = cmnum("Linger timeout in 10th of a millisecond",
  5333.              "0",10,&y,xxstring)) < 0)
  5334.         return(x);
  5335.       } else
  5336.     y = 0;
  5337.       if ((x = cmcfm()) < 0)
  5338.     return(x);
  5339.       success = ck_linger(z,y);
  5340.       return(success);
  5341. #endif /* SO_LINGER */
  5342. #ifdef SO_SNDBUF
  5343.    case XYTCP_SENDBUF:
  5344.       x = cmnum("Send buffer size, bytes","8192",10,&z,xxstring);
  5345.       if (x < 0) return(x);
  5346.       if ((x = cmcfm()) < 0) return(x);
  5347.       success = sendbuf(z);
  5348.       return(success);
  5349. #endif /* SO_SNDBUF */
  5350. #ifdef SO_RCVBUF
  5351.    case XYTCP_RECVBUF:
  5352.       x = cmnum("Receive buffer size, bytes","8192",10,&z,xxstring);
  5353.       if (x < 0) return(x);
  5354.       if ((x = cmcfm()) < 0) return(x);
  5355.  
  5356. /* Note: The following is not 16-bit safe */
  5357.  
  5358. #ifndef QNX16
  5359.       if (x > 52248) {
  5360.           printf("?Warning: receive buffers larger than 52248 bytes\n");
  5361.           printf(" may not be understood by all hosts.  Performance\n");
  5362.           printf(" may suffer.\n");
  5363.           return(-9);
  5364.       }
  5365. #endif /* QNX16 */
  5366.       success = recvbuf(z);
  5367.       return(success);
  5368. #endif /* SO_RCVBUF */
  5369.  
  5370. #ifdef VMS
  5371. #ifdef DEC_TCPIP
  5372.     case XYTCP_UCX: {            /* UCX 2.0 port swabbing bug */
  5373.     extern int ucx_port_bug;
  5374.     return(success = seton(&ucx_port_bug));
  5375.     }
  5376. #endif /* DEC_TCPIP */
  5377. #endif /* VMS */
  5378.  
  5379.     case XYTCP_RDNS: {
  5380.     extern int tcp_rdns;
  5381.     return(success = setonaut(&tcp_rdns));
  5382.     }
  5383.  
  5384. #ifdef CK_DNS_SRV
  5385.      case XYTCP_DNS_SRV: {
  5386.        extern int tcp_dns_srv;
  5387.        return(success = setonaut(&tcp_dns_srv));
  5388.      }
  5389. #endif /* CK_DNS_SRV */
  5390.  
  5391.      default:
  5392.        return(0);
  5393.    }
  5394. #endif /* TCPSOCKET */
  5395. #endif /* NOTCPOPTS */
  5396. #endif /* NETCONN */
  5397. }
  5398.  
  5399. switch (xx) {
  5400.  
  5401. #ifndef NOLOCAL
  5402. #ifdef NETCONN
  5403. case XYHOST:                /* SET HOST */
  5404. {
  5405.     z = ttnproto;            /* Save protocol in case of failure */
  5406. #ifdef DECNET
  5407.     if (nettype != NET_DEC)
  5408. #endif /* DECNET */
  5409.       ttnproto = NP_NONE;
  5410.     if ((y = setlin(XYHOST,1,0)) < 0) {
  5411.     debug(F101,"SET HOST fail mdmtyp","",mdmtyp);
  5412.         ttnproto = z;                /* Failed, restore protocol */
  5413.         success = 0;
  5414.     }
  5415.     didsetlin++;
  5416.     debug(F101,"SET HOST OK mdmtyp","",mdmtyp);
  5417.     return(y);
  5418. }
  5419. #endif /* NETCONN */
  5420.  
  5421. case XYLINE:                /* SET LINE (= SET PORT) */
  5422.     debug(F101,"setlin flow 1","",flow);
  5423.     x = setlin(xx,1,0);
  5424.     if (x > -1) didsetlin++;
  5425.     debug(F101,"setlin returns","",x);
  5426.     debug(F101,"setlin flow 2","",flow);
  5427.     debug(F101,"setlin local","",local);
  5428.     return(x);
  5429. #endif /* NOLOCAL */
  5430.  
  5431. #ifndef NOSETKEY
  5432. case XYKEY:                /* SET KEY */
  5433.     return(dosetkey());
  5434. #endif /* NOSETKEY */
  5435.  
  5436. #ifndef NOCSETS
  5437. case XYLANG:                 /* Language */
  5438.     if ((y = cmkey(lngtab,nlng,"","none",xxstring)) < 0) /* language code */
  5439.       return(y);
  5440.     if ((x = cmcfm()) < 0) return(x);    /* And confirmation of command */
  5441.  
  5442.     /* Look up language and get associated character sets */
  5443.     for (i = 0; (i < nlangs) && (langs[i].id != y); i++) ;
  5444.     if (i >= nlangs) {
  5445.     printf("?internal error, sorry\n");
  5446.     return(success = 0);
  5447.     }
  5448.     language = i;            /* All good, set the language, */
  5449.     return(success = 1);
  5450. #endif /* NOCSETS */
  5451.  
  5452. #ifndef MAC
  5453. case XYBACK:                /* BACKGROUND */
  5454.     if ((z = cmkey(onoff,2,"","",xxstring)) < 0) return(z);
  5455.     if ((y = cmcfm()) < 0) return(y);
  5456.     bgset = z;
  5457. #ifdef VMS
  5458.     if (batch && bgset == 0)        /* To enable echoing of commands */
  5459.       ckxech = 1;            /* in VMS batch logs */
  5460. #endif /* VMS */
  5461.     success = 1;
  5462.     bgchk();
  5463.     return(success);
  5464. #endif /* MAC */
  5465.  
  5466. case XYQUIE: {                /* QUIET */
  5467. #ifdef DCMDBUF
  5468.       extern int * xquiet;
  5469. #else
  5470.       extern int xquiet[];
  5471. #endif /* DCMDBUF */
  5472.       x = seton(&quiet);
  5473.       if (x < 0) return(x);
  5474.       xquiet[cmdlvl] = quiet;
  5475.       return(success = x);
  5476.     }
  5477.  
  5478. #ifndef NOXFER
  5479. case XYBUF: {                /* BUFFERS */
  5480. #ifdef DYNAMIC
  5481.     int sb, rb;
  5482.     if ((y = cmnum("Send buffer size","",10,&sb,xxstring)) < 0) {
  5483.     if (y == -3) printf("?Buffer size required\n");
  5484.     return(y);
  5485.     }
  5486.     if (sb < 0) {
  5487.     if (*atmbuf == '-') printf("?Negative numbers can't be used here\n");
  5488.     else printf("?Integer overflow, use a smaller number please\n");
  5489.     return(-9);
  5490.     } else if (sb < 80) {
  5491.     printf("?Too small\n");
  5492.     return(-9);
  5493.     }
  5494.     if ((y = cmnum("Receive buffer size",ckitoa(sb),10,&rb,xxstring)) < 0)
  5495.       return(y);
  5496.     if (rb < 0) {
  5497.     if (*atmbuf == '-') printf("?Negative numbers can't be used here\n");
  5498.     else printf("?Integer overflow, use a smaller number please\n");
  5499.     return(-9);
  5500.     } else if (rb < 80) {
  5501.     printf("?Too small\n");
  5502.     return(-9);
  5503.     }
  5504.     if ((y = cmcfm()) < 0) return(y);
  5505.     if ((y = inibufs(sb,rb)) < 0) return(y);
  5506.     y = adjpkl(urpsiz,wslotr,bigrbsiz); /* Maybe adjust packet sizes */
  5507.     if (y != urpsiz) urpsiz = y;
  5508.     y = adjpkl(spsiz,wslotr,bigsbsiz);
  5509.     if (y != spsiz) spsiz = spmax = spsizr = y;
  5510.     return(success = 1);
  5511. #else
  5512.     printf("?Sorry, not available\n");
  5513.     return(success = 0);
  5514. #endif /* DYNAMIC */
  5515. }
  5516.  
  5517. case XYCHKT:                /* BLOCK-CHECK */
  5518.     if ((x = cmkey(chktab,4,"","3",xxstring)) < 0) return(x);
  5519.     if ((y = cmcfm()) < 0) return(y);
  5520.     bctr = x;                 /* Set locally too, even if REMOTE SET */
  5521.     if (rmsflg) {
  5522.     if (x == 4) {
  5523.         tmpbuf[0] = 'B';
  5524.         tmpbuf[1] = '\0';
  5525.     } else sprintf(tmpbuf,"%d",x);
  5526.     sstate = setgen('S', "400", tmpbuf, "");
  5527.     return((int) sstate);
  5528.     } else {
  5529.     return(success = 1);
  5530.     }
  5531. #endif /* NOXFER */
  5532.  
  5533. #ifndef NOLOCAL
  5534. #ifndef MAC                /* The Mac has no RS-232 */
  5535. case XYCARR:                /* CARRIER-WATCH */
  5536.     return(setdcd());
  5537. #endif /* MAC */
  5538. #endif /* NOLOCAL */
  5539.  
  5540. }
  5541.  
  5542. #ifdef TNCODE
  5543. switch (xx) {                /* Avoid long switch statements... */
  5544.     case XYTELOP: {
  5545.         int c, n;            /* Workers */
  5546.         int getval = 0;            /* Whether to get switch value */
  5547.         int tnserver = 0;               /* Client by default */
  5548.         int opt = -1;                   /* Telnet Option */
  5549.         struct FDB sw, op;        /* FDBs for each parse function */
  5550. #ifdef CK_AUTHENTICATION
  5551.         extern int sl_topt_a_s_saved;
  5552.         extern int sl_topt_a_c_saved;
  5553.         extern int sl_topt_e_s_saved;
  5554.         extern int sl_topt_e_c_saved;
  5555. #endif /* CK_AUTHENTICATION */
  5556. #ifdef IKSD
  5557.         if (inserver)            /* Server by default when IKSD */
  5558.       tnserver = 1;
  5559. #endif /* IKSD */
  5560.  
  5561.         /* Set up chained parse functions... */
  5562.  
  5563.         cmfdbi(&op,            /* First fdb - telopts*/
  5564.            _CMKEY,            /* fcode */
  5565.            "/client, /server or",    /* hlpmsg */
  5566.            "",            /* default */
  5567.            "",            /* addtl string data */
  5568.            ntnopt,            /* addtl numeric data 1 */
  5569.            0,            /* addtl numeric data 2 */
  5570.            xxstring,
  5571.            tnopttab,
  5572.            &sw
  5573.            );
  5574.         cmfdbi(&sw,            /* Second FDB - command switches */
  5575.            _CMKEY,            /* fcode */
  5576.            "",                 /* hlpmsg */
  5577.            "",            /* default */
  5578.            "",            /* addtl string data */
  5579.            ntnoptsw,        /* addtl numeric data 1: tbl size */
  5580.            4,            /* addtl numeric data 2: 4 = cmswi */
  5581.            xxstring,        /* Processing function */
  5582.            tnoptsw,            /* Keyword table */
  5583.            NULL            /* Pointer to next FDB */
  5584.            );
  5585.  
  5586.         while (opt < 0) {        /* Parse 0 or more switches */
  5587.             x = cmfdb(&op);        /* Parse switch or other thing */
  5588.             debug(F101,"XYTELOP cmfdb","",x);
  5589.             if (x < 0)            /* Error */
  5590.           return(x);        /* or reparse needed */
  5591.             if (cmresult.fcode != _CMKEY) /* Break out if not a switch */
  5592.           break;
  5593.             c = cmgbrk();        /* Get break character */
  5594.             getval = (c == ':' || c == '='); /* see how switch ended */
  5595.             if (getval && !(cmresult.kflags & CM_ARG)) {
  5596.                 printf("?This switch does not take arguments\n");
  5597.                 return(-9);
  5598.             }
  5599.             z = cmresult.nresult;    /* Numeric result = switch value */
  5600.             debug(F101,"XYTELOP switch","",z);
  5601.  
  5602.             switch (z) {            /* Process the switch */
  5603.           case CK_TN_CLIENT:
  5604.                 tnserver = 0;
  5605.                 break;
  5606.           case CK_TN_SERVER:
  5607.                 tnserver = 1;
  5608.                 break;
  5609.           case CK_TN_EC:
  5610.                 opt = TELOPT_ECHO;
  5611.                 break;
  5612.           case CK_TN_TT:
  5613.                 opt = TELOPT_TTYPE;
  5614.                 break;
  5615.           case CK_TN_BM:
  5616.                 opt = TELOPT_BINARY;
  5617.                 break;
  5618.           case CK_TN_ENV:
  5619.                 opt = TELOPT_NEWENVIRON;
  5620.                 break;
  5621.           case CK_TN_LOC:
  5622.                 opt = TELOPT_SNDLOC;
  5623.                 break;
  5624.           case CK_TN_AU:
  5625.                 opt = TELOPT_AUTHENTICATION;
  5626.                 break;
  5627.               case CK_TN_FX:
  5628.                 opt = TELOPT_FORWARD_X;
  5629.                 break;
  5630.           case CK_TN_ENC:
  5631.                 opt = TELOPT_ENCRYPTION;
  5632.                 break;
  5633.           case CK_TN_IKS:
  5634.                 opt = TELOPT_KERMIT;
  5635.                 break;
  5636.           case CK_TN_TLS:
  5637.                 opt = TELOPT_START_TLS;
  5638.                 break;
  5639.           case CK_TN_XD:
  5640.                 opt = TELOPT_XDISPLOC;
  5641.                 break;
  5642.           case CK_TN_NAWS:
  5643.                 opt = TELOPT_NAWS;
  5644.                 break;
  5645.           case CK_TN_SGA:
  5646.                 opt = TELOPT_SGA;
  5647.                 break;
  5648.               case CK_TN_PHR:
  5649.                 opt = TELOPT_PRAGMA_HEARTBEAT;
  5650.                 break;
  5651.               case CK_TN_PSP:
  5652.                 opt = TELOPT_SSPI_LOGON;
  5653.                 break;
  5654.               case CK_TN_PLG:
  5655.                 opt = TELOPT_PRAGMA_LOGON;
  5656.                 break;
  5657.               case CK_TN_SAK:
  5658.                 opt = TELOPT_IBM_SAK;
  5659.                 break;
  5660.               case CK_TN_CPC:
  5661.                 opt = TELOPT_COM_PORT;
  5662.                 break;
  5663.               case CK_TN_FLW:
  5664.                 opt = TELOPT_LFLOW;
  5665.                 break;
  5666.           default:
  5667.                 printf("?Unexpected value - %d\n",z);
  5668.                 return(-9);
  5669.             }
  5670. #ifdef COMMENT
  5671.             if (cmresult.fdbaddr == &op)
  5672.           break;
  5673. #endif /* COMMENT */
  5674.         }
  5675.         switch (opt) {
  5676.       case TELOPT_ECHO:        /* Options only the Server WILL */
  5677.           case TELOPT_FORWARD_X:
  5678.       case TELOPT_SEND_URL:
  5679.           case TELOPT_IBM_SAK:
  5680.             if ((x = cmkey(tnnegtab,
  5681.                ntnnegtab,
  5682.                "desired server state",
  5683.    TELOPT_MODE(tnserver?TELOPT_DEF_S_ME_MODE(opt):TELOPT_DEF_C_U_MODE(opt)),
  5684.                xxstring)
  5685.          ) < 0)
  5686.           return(x);
  5687.             if ((z = cmcfm()) < 0)
  5688.           return(z);
  5689.             if (tnserver) {
  5690.                 TELOPT_DEF_S_ME_MODE(opt) = x;
  5691.                 TELOPT_ME_MODE(opt) = x;
  5692.             } else {
  5693.                 TELOPT_DEF_C_U_MODE(opt) = x;
  5694.                 TELOPT_U_MODE(opt) = x;
  5695.             }
  5696.             break;
  5697.  
  5698.       case TELOPT_TTYPE:        /* Options only the Client WILL */
  5699.       case TELOPT_NEWENVIRON:
  5700.       case TELOPT_SNDLOC:
  5701.       case TELOPT_AUTHENTICATION:
  5702.       case TELOPT_START_TLS:
  5703.       case TELOPT_XDISPLOC:
  5704.       case TELOPT_NAWS:
  5705.           case TELOPT_LFLOW:
  5706.           case TELOPT_COM_PORT:
  5707.             if ((x = cmkey(tnnegtab,
  5708.                ntnnegtab,
  5709.                "desired client state",
  5710.     TELOPT_MODE(!tnserver?TELOPT_DEF_S_U_MODE(opt):TELOPT_DEF_C_ME_MODE(opt)),
  5711.                             xxstring)
  5712.          ) < 0)
  5713.           return(x);
  5714.             if ((z = cmcfm()) < 0)
  5715.           return(z);
  5716.             if (tnserver) {
  5717.                 TELOPT_DEF_S_U_MODE(opt) = x;
  5718.                 TELOPT_U_MODE(opt) = x;
  5719. #ifdef CK_AUTHENTICATION
  5720.                 if (opt == TELOPT_AUTHENTICATION)
  5721.           sl_topt_a_s_saved = 0;
  5722. #endif /* CK_AUTHENTICATION */
  5723.             } else {
  5724.                 TELOPT_DEF_C_ME_MODE(opt) = x;
  5725.                 TELOPT_ME_MODE(opt) = x;
  5726. #ifdef CK_AUTHENTICATION
  5727.                 if (opt == TELOPT_AUTHENTICATION)
  5728.           sl_topt_a_c_saved = 0;
  5729. #endif /* CK_AUTHENTICATION */
  5730.             }
  5731.             break;
  5732.  
  5733.       default:
  5734.             if ((x = cmkey(tnnegtab,
  5735.                ntnnegtab,
  5736.                tnserver ?
  5737.                "desired server state" :
  5738.                "desired client state",
  5739.     TELOPT_MODE(tnserver?TELOPT_DEF_S_ME_MODE(opt):TELOPT_DEF_C_ME_MODE(opt)),
  5740.                xxstring
  5741.                )
  5742.          ) < 0)
  5743.           return(x);
  5744.             if ((y = cmkey(tnnegtab,
  5745.                ntnnegtab,
  5746.                !tnserver ? "desired server state" :
  5747.                "desired client state",
  5748.     TELOPT_MODE(!tnserver?TELOPT_DEF_S_U_MODE(opt):TELOPT_DEF_C_U_MODE(opt)),
  5749.                xxstring
  5750.                )
  5751.          ) < 0)
  5752.           return(y);
  5753.             if ((z = cmcfm()) < 0)
  5754.           return(z);
  5755.             if (tnserver) {
  5756.                 TELOPT_DEF_S_ME_MODE(opt) = x;
  5757.                 TELOPT_ME_MODE(opt) = x;
  5758.                 TELOPT_DEF_S_U_MODE(opt) = y;
  5759.                 TELOPT_U_MODE(opt) = y;
  5760. #ifdef CK_ENCRYPTION
  5761.                 if (opt == TELOPT_ENCRYPTION)
  5762.           sl_topt_e_s_saved = 0;
  5763. #endif /* CK_ENCRYPTION */
  5764.             } else {
  5765.                 TELOPT_DEF_C_ME_MODE(opt) = x;
  5766.                 TELOPT_ME_MODE(opt) = x;
  5767.                 TELOPT_DEF_C_U_MODE(opt) = y;
  5768.                 TELOPT_U_MODE(opt) = y;
  5769. #ifdef CK_ENCRYPTION
  5770.                 if (opt == TELOPT_ENCRYPTION)
  5771.           sl_topt_e_c_saved = 0;
  5772. #endif /* CK_ENCRYPTION */
  5773.             }
  5774.         }
  5775.         return(success = 1);
  5776.     }
  5777.  
  5778.   case XYTEL:                /* TELNET */
  5779.     if ((z = cmkey(tntab,ntn,"parameter for TELNET negotiations", "",
  5780.            xxstring)) < 0)
  5781.       return(z);
  5782.     switch (z) {
  5783.       case CK_TN_EC:            /* ECHO */
  5784.     if ((x = cmkey(rltab,nrlt,
  5785.                "initial TELNET echoing state","local",xxstring)) < 0)
  5786.       return(x);
  5787.     if ((y = cmcfm()) < 0) return(y);
  5788.     tn_duplex = x;
  5789.     return(success = 1);
  5790.  
  5791.       case CK_TN_RE:                    /* REMOTE-ECHO */
  5792.         return(success = seton(&tn_rem_echo));
  5793.  
  5794.       case CK_TN_DB:                    /* DEBUG */
  5795.           return(success = seton(&tn_deb));
  5796.  
  5797.       case CK_TN_TT:            /* TERMINAL TYPE */
  5798.     if ((y = cmtxt("terminal type for TELNET connections","",
  5799.                &s,xxstring)) < 0)
  5800.       return(y);
  5801.     if (tn_term) {
  5802.         free(tn_term);        /* Free any previous storage */
  5803.         tn_term = NULL;
  5804.     }
  5805.     if (s == NULL || *s == NUL) {    /* If none given */
  5806.         tn_term = NULL;        /* remove the override string */
  5807.         return(success = 1);
  5808.     } else if (tn_term = malloc(strlen(s)+1)) { /* Make storage for new */
  5809.         strcpy(tn_term,s);        /* Copy string into new storage */
  5810.         return(success = 1);
  5811.     } else return(success = 0);
  5812.  
  5813.       case CK_TN_NL:            /* TELNET NEWLINE-MODE */
  5814.         if ((x = cmkey(tn_nlmtab,ntn_nlm,"","nvt",xxstring)) < 0)
  5815.       return(x);
  5816.     if (x == TN_NL_BIN) {
  5817.         if ((x = cmkey(tnlmtab,ntnlm,"","raw",xxstring)) < 0)
  5818.           return(x);
  5819.         if ((y = cmcfm()) < 0)
  5820.           return(y);
  5821.         tn_b_nlm = x;
  5822.         return(success = 1);
  5823.     } else if (x == TN_NL_NVT) {
  5824.         if ((x = cmkey(tnlmtab,ntnlm,"","on",xxstring)) < 0)
  5825.           return(x);
  5826.         if ((y = cmcfm()) < 0)
  5827.           return(y);
  5828.         tn_nlm = x;
  5829.         return(success = 1);
  5830.     } else {
  5831.         if ((y = cmcfm()) < 0)
  5832.           return(y);
  5833.         tn_nlm = x;
  5834.         return(success = 1);
  5835.     }
  5836.  
  5837.       case CK_TN_XF:            /* BINARY-TRANSFER-MODE */
  5838.           if ((z = cmkey(onoff,2,"","on",xxstring)) < 0) return(z);
  5839.           if ((y = cmcfm()) < 0) return(y);
  5840.           tn_b_xfer = z;
  5841.           return(success = 1);
  5842.  
  5843.       case CK_TN_NE:            /* NO-ENCRYPT-DURING-XFER */
  5844.           if ((z = cmkey(onoff,2,"","on",xxstring)) < 0) return(z);
  5845.           if ((y = cmcfm()) < 0) return(y);
  5846. #ifdef CK_APC
  5847.           /* Don't let this be set remotely */
  5848.           if (apcactive == APC_LOCAL ||
  5849.                apcactive == APC_REMOTE && apcstatus != APC_UNCH)
  5850.               return(success = 0);
  5851. #endif /* CK_APC */
  5852.           tn_no_encrypt_xfer = z;
  5853.           return(success = 1);
  5854.  
  5855.       case CK_TN_BM:            /* BINARY-MODE */
  5856.         if ((x = cmkey(tnnegtab,ntnnegtab,"","refused",xxstring)) < 0)
  5857.       return(x);
  5858.     if ((y = cmcfm()) < 0)
  5859.       return(y);
  5860.     TELOPT_DEF_S_ME_MODE(TELOPT_BINARY) = x;
  5861.     TELOPT_DEF_S_U_MODE(TELOPT_BINARY) = x;
  5862.     TELOPT_DEF_C_ME_MODE(TELOPT_BINARY) = x;
  5863.     TELOPT_DEF_C_U_MODE(TELOPT_BINARY) = x;
  5864.     return(success = 1);
  5865.  
  5866. #ifdef IKS_OPTION
  5867.       case CK_TN_IKS:            /* KERMIT */
  5868.     if ((x = cmkey(tnnegtab,ntnnegtab,"DO","accept",xxstring)) < 0)
  5869.       return(x);
  5870.         if ((y = cmkey(tnnegtab,ntnnegtab,"WILL","accept",xxstring)) < 0)
  5871.             return(y);
  5872.         if ((z = cmcfm()) < 0)
  5873.           return(z);
  5874.     TELOPT_DEF_S_ME_MODE(TELOPT_KERMIT) = y;
  5875.     TELOPT_DEF_S_U_MODE(TELOPT_KERMIT) = x;
  5876.     TELOPT_DEF_C_ME_MODE(TELOPT_KERMIT) = y;
  5877.     TELOPT_DEF_C_U_MODE(TELOPT_KERMIT) = x;
  5878.     return(success = 1);
  5879. #endif /* IKS_OPTION */
  5880.  
  5881. #ifdef CK_SSL
  5882.       case CK_TN_TLS:            /* START_TLS */
  5883.     if ((x = cmkey(tnnegtab,ntnnegtab,"me","accept",xxstring)) < 0)
  5884.       return(x);
  5885.     if ((y = cmkey(tnnegtab,ntnnegtab,"u","accept",xxstring)) < 0)
  5886.       return(y);
  5887.     if ((z = cmcfm()) < 0)
  5888.       return(z);
  5889.     TELOPT_DEF_S_ME_MODE(TELOPT_START_TLS) = x;
  5890.     TELOPT_DEF_S_U_MODE(TELOPT_START_TLS) = y;
  5891.     TELOPT_DEF_C_ME_MODE(TELOPT_START_TLS) = x;
  5892.     TELOPT_DEF_C_U_MODE(TELOPT_START_TLS) = y;
  5893.     return(success = 1);
  5894. #endif /* CK_SSL */
  5895.  
  5896. #ifdef CK_NAWS
  5897.       case CK_TN_NAWS:            /* NAWS */
  5898.     if ((x = cmkey(tnnegtab,ntnnegtab,"me","accept",xxstring)) < 0)
  5899.       return(x);
  5900.     if ((y = cmkey(tnnegtab,ntnnegtab,"u","accept",xxstring)) < 0)
  5901.       return(y);
  5902.     if ((z = cmcfm()) < 0)
  5903.       return(z);
  5904.     TELOPT_DEF_S_ME_MODE(TELOPT_NAWS) = x;
  5905.     TELOPT_DEF_S_U_MODE(TELOPT_NAWS) = y;
  5906.     TELOPT_DEF_C_ME_MODE(TELOPT_NAWS) = x;
  5907.     TELOPT_DEF_C_U_MODE(TELOPT_NAWS) = y;
  5908.     return(success = 1);
  5909. #endif /* CK_NAWS */
  5910.  
  5911. #ifdef CK_AUTHENTICATION
  5912.       case CK_TN_AU:            /* AUTHENTICATION */
  5913.     if ((x = cmkey(tnauthtab,ntnauth,"","accept",xxstring)) < 0)
  5914.       return(x);
  5915.     if (x == TN_AU_FWD) {
  5916.         extern int forward_flag;
  5917.         return(success = seton(&forward_flag));
  5918.     } else if (x == TN_AU_TYP) {
  5919.         extern int auth_type_user[];
  5920.             extern int sl_auth_type_user[];
  5921.             extern int sl_auth_saved;
  5922.             int i, j, atypes[AUTHTYPLSTSZ];
  5923.  
  5924.             for (i = 0; i < AUTHTYPLSTSZ; i++) {
  5925.                 if ((y = cmkey(autyptab,nautyp,"",
  5926.                    i == 0 ? "automatic" : "" ,
  5927.                    xxstring)) < 0) {
  5928.                     if (y == -3)
  5929.               break;
  5930.                     return(y);
  5931.                 }
  5932.                 if (i > 0 && (y == AUTHTYPE_AUTO || y == AUTHTYPE_NULL)) {
  5933.             printf(
  5934.                "\r\n?Choice may only be used in first position.\r\n");
  5935.             return(-9);
  5936.                 }
  5937.                 for (j=0 ; j< i; j++) {
  5938.                     if (atypes[j] == y) {
  5939.                         printf("\r\n?Choice has already been used.\r\n");
  5940.                         return(-9);
  5941.                     }
  5942.                 }
  5943.                 atypes[i] = y;
  5944.                 if (y == AUTHTYPE_NULL || y == AUTHTYPE_AUTO) {
  5945.                     i++;
  5946.                     break;
  5947.                 }
  5948.             }
  5949.             if (i < AUTHTYPLSTSZ)
  5950.           atypes[i] = AUTHTYPE_NULL;
  5951.         if ((z = cmcfm()) < 0)
  5952.           return(z);
  5953.             sl_auth_saved = 0;
  5954.             for (i = 0; i < AUTHTYPLSTSZ; i++) {
  5955.                 auth_type_user[i] = atypes[i];
  5956.                 sl_auth_type_user[i] = 0;
  5957.             }
  5958.     } else if (x == TN_AU_HOW) {
  5959.         if ((y = cmkey(auhowtab,nauhow,"","any",xxstring)) < 0)
  5960.           return(y);
  5961.         if ((z = cmcfm()) < 0)
  5962.           return(z);
  5963.         tn_auth_how = y;
  5964.     } else if (x == TN_AU_ENC) {
  5965.         if ((y = cmkey(auenctab,nauenc,"","encrypt",xxstring)) < 0)
  5966.           return(y);
  5967.         if ((z = cmcfm()) < 0)
  5968.           return(z);
  5969.         tn_auth_enc = y;
  5970.     } else {
  5971.         if ((y = cmcfm()) < 0)
  5972.           return(y);
  5973.         TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = x;
  5974.         TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = x;
  5975.     }
  5976.     return(success = 1);
  5977. #endif /* CK_AUTHENTICATION */
  5978.  
  5979. #ifdef CK_ENCRYPTION
  5980.       case CK_TN_ENC: {            /* ENCRYPTION */
  5981.       int c, tmp = -1;
  5982.       int getval = 0;
  5983.       static struct keytab * tnetbl = NULL;
  5984.       static int ntnetbl = 0;
  5985.  
  5986.           if ((y = cmkey(tnenctab,ntnenc,"","accept",xxstring)) < 0)
  5987.         return(y);
  5988.           switch (y) {
  5989.         case TN_EN_TYP:
  5990.               x = ck_get_crypt_table(&tnetbl,&ntnetbl);
  5991.               debug(F101,"ck_get_crypt_table x","",x);
  5992.               debug(F101,"ck_get_crypt_table n","",ntnetbl);
  5993.               if (x < 1 || !tnetbl || ntnetbl < 1) /* Didn't get it */
  5994.         x = 0;
  5995.               if (!x) {
  5996.                   printf("?Oops, types not loaded\n");
  5997.                   return(-9);
  5998.               }
  5999.               if ((x = cmkey(tnetbl,ntnetbl,"type of encryption",
  6000.                  "automatic",xxstring)) < 0)
  6001.         return(x);
  6002.               if ((z = cmcfm()) < 0)
  6003.         return(z);
  6004.               cx_type = x;
  6005.               sl_cx_type = 0;
  6006.               break;
  6007.         case TN_EN_START:
  6008.               if ((z = cmcfm()) < 0)
  6009.         return(z);
  6010. #ifdef CK_APC
  6011.           /* Don't let this be set remotely */
  6012.           if (apcactive == APC_LOCAL ||
  6013.               apcactive == APC_REMOTE && apcstatus != APC_UNCH)
  6014.             return(success = 0);
  6015. #endif /* CK_APC */
  6016.               ck_tn_enc_start();
  6017.               break;
  6018.         case TN_EN_STOP:
  6019.               if ((z = cmcfm()) < 0)
  6020.         return(z);
  6021. #ifdef CK_APC
  6022.           /* Don't let this be set remotely */
  6023.           if (apcactive == APC_LOCAL ||
  6024.               apcactive == APC_REMOTE && apcstatus != APC_UNCH)
  6025.             return(success = 0);
  6026. #endif /* CK_APC */
  6027.               ck_tn_enc_stop();
  6028.               break;
  6029.         default:
  6030.               if ((z = cmcfm()) < 0)
  6031.         return(z);
  6032.           TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = y;
  6033.           TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = y;
  6034.           TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = y;
  6035.           TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = y;
  6036.           }
  6037.           return(success = 1);
  6038.       }
  6039. #endif /* CK_ENCRYPTION */
  6040.  
  6041.       case CK_TN_BUG:            /* BUG */
  6042.     if ((x = cmkey(tnbugtab,4,"","binary-me-means-u-too",xxstring)) < 0)
  6043.       return(x);
  6044.     if ((z = cmkey(onoff,2,"","off",xxstring)) < 0) return(z);
  6045.     if ((y = cmcfm()) < 0) return(y);
  6046.     switch (x) {
  6047.       case 0:
  6048.         tn_b_meu = z;
  6049.         break;
  6050.       case 1:
  6051.         tn_b_ume = z;
  6052.         break;
  6053.           case 2:
  6054.         tn_infinite = z;
  6055.             break;
  6056.           case 3:
  6057.             tn_sb_bug = z;
  6058.             break;
  6059.     }
  6060.     return(success = 1);
  6061.  
  6062. #ifdef CK_ENVIRONMENT
  6063.       case CK_TN_XD:            /* XDISPLOC */
  6064.     if ((x = cmkey(tnnegtab,ntnnegtab,"me","accept",xxstring)) < 0)
  6065.       return(x);
  6066.     if ((y = cmkey(tnnegtab,ntnnegtab,"u","accept",xxstring)) < 0)
  6067.       return(y);
  6068.     if ((z = cmcfm()) < 0)
  6069.       return(z);
  6070.     TELOPT_DEF_S_ME_MODE(TELOPT_XDISPLOC) = x;
  6071.     TELOPT_DEF_S_U_MODE(TELOPT_XDISPLOC) = y;
  6072.     TELOPT_DEF_C_ME_MODE(TELOPT_XDISPLOC) = x;
  6073.     TELOPT_DEF_C_U_MODE(TELOPT_XDISPLOC) = y;
  6074.     return(success = 1);
  6075.  
  6076.       case CK_TN_ENV: {
  6077.       char * msg = "value of telnet environment variable";
  6078.       extern int tn_env_flg;
  6079.       extern char tn_env_acct[], tn_env_disp[], tn_env_job[],
  6080.       tn_env_prnt[], tn_env_sys[];
  6081.       if ((x = cmkey(tnenvtab,ntnenv,"","",xxstring)) < 0)
  6082.         return(x);
  6083. #ifdef COMMENT
  6084.           /* If we ever support USERVAR variables */
  6085.       if (x == TN_ENV_UVAR) {
  6086.           /* Get the user variable name */
  6087.       }
  6088. #endif /* COMMENT */
  6089.       if (x == TN_ENV_OFF || x == TN_ENV_ON) {
  6090.           if ((y = cmcfm()) < 0) return(y);
  6091. #ifdef IKSD
  6092.               if (inserver) {
  6093.                   printf("?Sorry, command disabled.\r\n");
  6094.                   return(success = 0);
  6095.               }
  6096. #endif /* IKSD */
  6097.           tn_env_flg = x == TN_ENV_OFF ? 0 : 1;
  6098.           return(success = 1);
  6099.       }
  6100.  
  6101.       /* Not ON/OFF - Get the value */
  6102.       z = cmdgquo();
  6103.       cmdsquo(0);
  6104.       if ((y = cmtxt(msg,
  6105.              "", &s, xxstring)) < 0) {
  6106.           cmdsquo(z);
  6107.           return(y);
  6108.       }
  6109.       cmdsquo(z);
  6110. #ifdef IKSD
  6111.           if (inserver)
  6112.         return(success = 0);
  6113. #endif /* IKSD */
  6114.       if ((int)strlen(s) > 63) {
  6115.           printf("Sorry, too long\n");
  6116.           return(-9);
  6117.       }
  6118.       switch (x) {
  6119.         case TN_ENV_USR:
  6120.           ckstrncpy(uidbuf,s,UIDBUFLEN);
  6121.               sl_uid_saved = 0;
  6122.           break;
  6123.         case TN_ENV_ACCT:
  6124.           ckstrncpy(tn_env_acct,s,64);
  6125.           break;
  6126.         case TN_ENV_DISP:
  6127.           ckstrncpy(tn_env_disp,s,64);
  6128.           break;
  6129.         case TN_ENV_JOB:
  6130.           ckstrncpy(tn_env_job,s,64);
  6131.           break;
  6132.         case TN_ENV_PRNT:
  6133.           ckstrncpy(tn_env_prnt,s,64);
  6134.           break;
  6135.         case TN_ENV_SYS:
  6136.           ckstrncpy(tn_env_sys,s,64);
  6137.           break;
  6138.         case TN_ENV_UVAR:
  6139.           printf("\n?Not yet implemented\n");
  6140.           break;
  6141.       }
  6142.       return(success = 1);
  6143.       }
  6144. #endif /* CK_ENVIRONMENT */
  6145.  
  6146. #ifdef CK_SNDLOC
  6147.       case CK_TN_LOC: {            /* LOCATION */
  6148.       extern char * tn_loc;
  6149.       if ((y = cmtxt("Location string","",&s,xxstring)) < 0)
  6150.         return(y);
  6151.       if (!*s) s = NULL;
  6152.       makestr(&tn_loc,s);
  6153.       return(success = 1);
  6154.       }
  6155. #endif /* CK_SNDLOC */
  6156.  
  6157.       case CK_TN_WAIT:            /* WAIT-FOR-NEGOTIATIONS */
  6158.     if ((z = cmkey(onoff,2,"","on",xxstring)) < 0) return(z);
  6159.     if ((y = cmcfm()) < 0) return(y);
  6160. #ifdef IKSD
  6161.     if (inserver &&
  6162. #ifdef IKSDCONF
  6163.         iksdcf
  6164. #else
  6165.         1
  6166. #endif /* IKSDCONF */
  6167.         ) {
  6168.         printf("?Sorry, command disabled.\r\n");
  6169.         return(success = 0);
  6170.     }
  6171. #endif /* IKSD */
  6172.     tn_wait_flg = z;
  6173.         sl_tn_saved = 0;
  6174.     return(success = 1);
  6175.  
  6176.       case CK_TN_PUID: {                /* PROMPT-FOR-USERID */
  6177.     int i,len;
  6178.     if ((y = cmtxt("Prompt string","",&s,xxstring)) < 0)
  6179.       return(y);
  6180.     if (s == "") s = NULL;
  6181.     if (s) {
  6182.         s = brstrip(s);
  6183.         if (s == "") s = NULL;
  6184.     }
  6185.         /* we must check to make sure there are no % fields */
  6186.         len = strlen(s);
  6187.         for (i = 0; i < len; i++) {
  6188.             if (s[i] == '%') {
  6189.                 if (s[i+1] != '%') {
  6190.                     printf("%% fields are not used in this command.\n");
  6191.                     return(-9);
  6192.                 }
  6193.                 i++;
  6194.             }
  6195.         }
  6196.     makestr(&tn_pr_uid,s);
  6197.         return(success = 1);
  6198.       }
  6199.       default:
  6200.     return(-2);
  6201.     }
  6202. }
  6203. #endif /* TNCODE */
  6204.  
  6205. switch (xx) {
  6206. #ifndef NOSPL
  6207. case XYCOUN:                /* SET COUNT */
  6208.     x = cmnum("Positive number","0",10,&z,xxstring);
  6209.     if (x < 0) return(x);
  6210.     if ((x = cmcfm()) < 0) return(x);
  6211.     if (z < 0) {
  6212.     printf("?A positive number, please\n");
  6213.     return(0);
  6214.     }
  6215.     debug(F101,"XYCOUN: z","",z);
  6216.     return(success = setnum(&count[cmdlvl],z,0,10000));
  6217. #endif /* NOSPL */
  6218.  
  6219. #ifndef NOSPL
  6220. case XYCASE:
  6221.     return(success = seton(&inpcas[cmdlvl]));
  6222. #endif /* NOSPL */
  6223.  
  6224. case XYCMD:                /* COMMAND ... */
  6225.     if ((y = cmkey(scmdtab,nbytt,"","",xxstring)) < 0) return(y);
  6226.     switch(y) {
  6227.       case 876:
  6228.     if ((y = cmcfm()) < 0) return(y);
  6229.     concb((char)escape);
  6230.     return(success = 1);
  6231.  
  6232.       case SCMD_BSZ:
  6233.     if ((y = cmnum("bytesize for command characters, 7 or 8","7",10,&x,
  6234.                xxstring)) < 0)
  6235.       return(y);
  6236.     if (x != 7 && x != 8) {
  6237.         printf("\n?The choices are 7 and 8\n");
  6238.         return(success = 0);
  6239.     }
  6240.     if ((y = cmcfm()) < 0) return(y);
  6241.     if (x == 7) cmdmsk = 0177;
  6242.     else if (x == 8) cmdmsk = 0377;
  6243.     return(success = 1);
  6244. #ifdef CK_RECALL
  6245.       case SCMD_RCL:
  6246.     if ((y = cmnum("maximum number of commands in recall buffer","10",
  6247.                10,&x,xxstring)) < 0)
  6248.       return(y);
  6249.     if ((y = cmcfm()) < 0) return(y);
  6250.     return(success = cmrini(x));
  6251. #endif /* CK_RECALL */
  6252. #ifdef CK_RECALL
  6253.       case SCMD_RTR:
  6254.     return(success = seton(&cm_retry));
  6255. #endif /* CK_RECALL */
  6256.       case SCMD_MOR:            /* More-prompting */
  6257.     return(success = seton(&xaskmore));
  6258.       case SCMD_QUO:
  6259.     if ((x = seton(&y)) < 0) return(x);
  6260.     cmdsquo(y);            /* Do it the right way */
  6261.     cmd_quoting = y;        /* Also keep a global copy */
  6262.     /* Set string-processing function */
  6263. #ifdef datageneral
  6264.     xxstring = y ? zzstring : (xx_strp) NULL;
  6265. #else
  6266. #ifdef CK_ANSIC
  6267.     xxstring = y ? zzstring : (xx_strp) NULL;
  6268. #else
  6269.     xxstring = y ? zzstring : (xx_strp) NULL;
  6270. #endif /* CK_ANSIC */
  6271. #endif /* datageneral */
  6272.     return(success = 1);
  6273.  
  6274. #ifdef OS2
  6275.       case SCMD_COL: {            /* Command-screen colors */
  6276.          int fg, bg;
  6277.          fg = cmkey(ttyclrtab, nclrs,
  6278.                      "foreground color and then background color",
  6279.                      "white",
  6280.                      xxstring);
  6281.          if (fg < 0)
  6282.             return(fg);
  6283.          if ((bg = cmkey(ttyclrtab,nclrs,
  6284.                           "background color","black",xxstring)) < 0)
  6285.             return(bg);
  6286.          if ((y = cmcfm()) < 0)
  6287.             return(y);
  6288.          colorcmd = fg | bg << 4;
  6289.          return(success = 1);
  6290.       }
  6291.  
  6292.     case SCMD_SCR:       /* Command Scrollback size */
  6293.           if ((y = cmnum("COMMAND scrollback buffer size, lines","512",10,&x,
  6294.                           xxstring)) < 0)
  6295.             return(y);
  6296.     /* The max number of lines is the RAM  */
  6297.     /* we can actually dedicate to a       */
  6298.     /* scrollback buffer given the maximum */
  6299.     /* process memory space of 512MB       */
  6300.     if (x < 256 || x > 2000000L) {
  6301.         printf("\n?The size must be between 256 and 2,000,000.\n");
  6302.         return(success = 0);
  6303.      }
  6304.     if ((y = cmcfm()) < 0) return(y);
  6305.           tt_scrsize[VCMD] = x;
  6306.           VscrnInit( VCMD ) ;
  6307.     return(success = 1);
  6308.  
  6309.           break;
  6310.  
  6311.       case SCMD_WID: {
  6312.       if ((y = cmnum("number of columns in display window during CONNECT",
  6313.              "80",10,&x,xxstring)) < 0)
  6314.         return(y);
  6315.       if ((y = cmcfm()) < 0) return(y);
  6316.  
  6317.       if (IsOS2FullScreen()) {
  6318.           if (x != 40 && x != 80 && x != 132) {
  6319.           printf("\n?The width must be 40, 80,");
  6320. #ifdef NT
  6321.           printf(" or 132 under Windows 95.\n.");
  6322. #else /* NT */
  6323.           printf(" or 132 in a Full Screen session.\n.");
  6324. #endif /* NT */
  6325.           return(success = 0);
  6326.           }
  6327.       } else {
  6328.           if (!IsWARPed() && x != 80) {
  6329.           printf("\n?OS/2 version is pre-WARP: the width must equal ");
  6330.           printf("80 in a Windowed Session\n.");
  6331.           return(success = 0);
  6332.           }
  6333.           if (x < 20 || x > MAXTERMCOL) {
  6334.           printf(
  6335.               "\n?The width must be between 20 and %d\n.",MAXTERMCOL);
  6336.           return(success = 0);
  6337.           }
  6338.       }
  6339.       if (x > 8192/(tt_rows[VCMD]+1)) {
  6340.           printf(
  6341. "\n?The max screen area is 8192 cells: %d(rows) x %d(cols) = %d cells.\n",
  6342.              tt_rows[VCMD]+1,x,x*(tt_rows[VCMD]+1));
  6343.           return(success = 0);
  6344.       }
  6345.       tt_cols[VCMD] = x;
  6346.       VscrnSetWidth(VCMD, x);
  6347.       cmd_cols = x;
  6348.       SetCols(VCMD);
  6349.       return(success = 1);
  6350.       }
  6351.       case SCMD_HIG:
  6352.        if ((y = cmnum(
  6353. "number of rows in display window during CONNECT",
  6354.                "25",10,&x,xxstring)) < 0)
  6355.       return(y);
  6356.     if ((y = cmcfm()) < 0) return(y);
  6357.  
  6358.     if (tt_modechg == TVC_DIS) {
  6359.         printf("\n?SET TERMINAL VIDEO-CHANGE DISABLED\n");
  6360.         return(success = 0);
  6361.     }
  6362.     if (IsOS2FullScreen()) {
  6363.         if (x != 25 && x != 43 && x != 50 && x != 60) {
  6364.         printf("\n?The height must be 25, 43, 50");
  6365. #ifdef NT
  6366.         printf(" or 60 under Windows 95.\n.");
  6367. #else /* NT */
  6368.         printf(" or 60 in a Full Screen session.\n.");
  6369. #endif /* NT */
  6370.         return(success = 0);
  6371.         }
  6372.     } else if (tt_modechg == TVC_W95) {
  6373.         if (x != 25 && x != 43 && x != 50) {
  6374.         printf("\n?The height must be 25, 43, 50");
  6375. #ifdef NT
  6376.         printf(" under Windows 95.\n.");
  6377. #else /* NT */
  6378.         printf(" in a Full Screen session.\n.");
  6379. #endif /* NT */
  6380.         return(success = 0);
  6381.         }
  6382.     } else {
  6383.             if (x < 8 || x > MAXTERMROW ) {
  6384.                 printf("\n?The height must be between 8 and %d\n.",MAXTERMROW);
  6385.                 return(success = 0);
  6386.         }
  6387.     }
  6388.         if (x > 8192/tt_cols[VCMD]) {
  6389.             printf(
  6390. "\n?The max screen area is 8192 cells: %d(rows) x %d(cols) = %d cells.\n",
  6391.            x,tt_cols[VCMD],x*tt_cols[VCMD]);
  6392.             return(success = 0);
  6393.     }
  6394.         tt_szchng[VCMD] = 1;
  6395.         tt_rows[VCMD] = cmd_rows = x;
  6396.         VscrnInit(VCMD);
  6397.     SetCols(VCMD);
  6398.         return(success = 1);
  6399.  
  6400.     case SCMD_CUR: {
  6401.         int row, col;
  6402.         position * ppos;
  6403.  
  6404.         ppos = VscrnGetCurPos(VCMD);
  6405. #ifdef NT
  6406. #define itoa _itoa
  6407. #endif
  6408.         itoa(ppos->y+1, tmpbuf, 10);
  6409.         if ((y = cmnum("row (1-based)",tmpbuf,10,&row,xxstring)) < 0)
  6410.       return(y);
  6411.  
  6412.         itoa(ppos->x+1, tmpbuf, 10);
  6413.         if ((y = cmnum("col (1-based)",tmpbuf,10,&col,xxstring)) < 0)
  6414.       return(y);
  6415.         if ((x = cmcfm()) < 0) return(x);
  6416.  
  6417.         VscrnSetCurPos( VCMD, (short) (col-1), (short) (row-1) ) ;
  6418.         VscrnIsDirty( VCMD );
  6419.         return(success=1);
  6420.     }
  6421. #else
  6422.       case SCMD_WID:
  6423.     y = cmnum("Command screen width, characters","80",10,&x,xxstring);
  6424.     return(setnum(&cmd_cols,x,y,1024));
  6425.  
  6426.       case SCMD_HIG:
  6427.     y = cmnum("Command screen height, rows","24",10,&x,xxstring);
  6428.     return(setnum(&cmd_rows,x,y,1024));
  6429. #endif /* OS2 */
  6430.  
  6431.       case SCMD_INT:
  6432.     return(seton(&cmdint));
  6433.  
  6434. #ifdef CK_AUTODL
  6435.       case SCMD_ADL:
  6436.     return(seton(&cmdadl));
  6437. #endif /* CK_AUTODL */
  6438.  
  6439.       default:
  6440.     return(-2);
  6441.     }
  6442. }
  6443.  
  6444. switch (xx) {
  6445.  
  6446. case XYDFLT:                /* SET DEFAULT = CD */
  6447.     return(success = docd(XXCWD));
  6448.  
  6449. case XYDEBU:                /* SET DEBUG { on, off, session } */
  6450.     if ((y = cmkey(dbgtab,ndbg,"","",xxstring)) < 0) {
  6451.     return(y);
  6452.     } else if (y == 3) {        /* 3 = timestamp */
  6453.     debug(F101,"set debug y","",y);
  6454.     x = seton(&debtim);
  6455.     debug(F101,"set debug x","",x);
  6456.     if (x < 0)
  6457.       return(x);
  6458.     else
  6459.       return(success = 1);
  6460.     } else if ((x = cmcfm()) < 0)
  6461.       return(x);
  6462. #ifdef IKSD
  6463.     if (inserver && isguest) {
  6464.         printf("?Sorry, command disabled.\r\n");
  6465.         return(success = 0);
  6466.     }
  6467. #endif /* IKSD */
  6468.     debug(F101,"set debug y","",y);
  6469.     switch (y) {
  6470.       case 0:                /* 0 = all debugging off. */
  6471.     debses = 0;
  6472. #ifdef DEBUG
  6473.     if (deblog) doclslog(LOGD);
  6474. #endif /* DEBUG */
  6475.         return(success = 1);
  6476.  
  6477.       case 1:                /* 1 = log debugging to debug.log */
  6478. #ifdef DEBUG
  6479.     deblog = debopn("debug.log", 0);
  6480.     return(success = deblog ? 1 : 0);
  6481. #else
  6482.     printf("?Sorry, debug log feature not enabled\n");
  6483.     return(success = 0);
  6484. #endif /* DEBUG */
  6485.  
  6486.       case 2:                /* 2 = session */
  6487.     return(success = debses = 1);
  6488.  
  6489.       default:
  6490.         return(-2);
  6491.     }
  6492.     break;
  6493.  
  6494. #ifndef NOXFER
  6495. case XYDELA:                /* SET DELAY */
  6496.     y = cmnum("Number of seconds before starting to send","5",10,&x,xxstring);
  6497.     if (x < 0) x = 0;
  6498.     return(success = setnum(&ckdelay,x,y,999));
  6499. #endif /* NOXFER */
  6500.  
  6501. default:
  6502.     break;
  6503. }
  6504.  
  6505. switch (xx) {
  6506. #ifndef NODIAL
  6507. #ifdef CK_TAPI
  6508. case XYTAPI:
  6509.     return(settapi());
  6510. #endif /* CK_TAPI */
  6511. case XYDIAL:                /* SET MODEM or SET DIAL */
  6512.     return(setdial(-1));
  6513. case XYMODM:
  6514.     return(setmodem());
  6515. #endif /* NODIAL */
  6516.  
  6517. #ifndef NOLOCAL
  6518. case XYDUPL:                /* SET DUPLEX */
  6519.     if ((y = cmkey(dpxtab,2,"","full",xxstring)) < 0) return(y);
  6520.     if ((x = cmcfm()) < 0) return(x);
  6521.     duplex = y;
  6522.     return(success = 1);
  6523.  
  6524. case XYLCLE:                /* LOCAL-ECHO (= DUPLEX) */
  6525.     return(success = seton(&duplex));
  6526.  
  6527. case XYESC:                /* SET ESCAPE */
  6528.     return(success = setcc(ckitoa(DFESC),&escape));
  6529. #endif /* NOLOCAL */
  6530.  
  6531. case XYEXIT:                /* SET EXIT */
  6532.     if ((z = cmkey(xittab,nexit,"","",xxstring)) < 0)
  6533.       return(z);
  6534.     switch (z) {
  6535.       case 0:                /* STATUS */
  6536.     y = cmnum("EXIT status code","",10,&x,xxstring);
  6537.     return(success = setnum(&xitsta,x,y,-1));
  6538.       case 1:                /* WARNING */
  6539.     if ((z = cmkey(xitwtab,nexitw,"","",xxstring)) < 0) return(z);
  6540.     if ((y = cmcfm()) < 0) return(y);
  6541.     xitwarn = z;
  6542.     return(success = 1);
  6543.       case 2:
  6544.     success = seton(&exitonclose);
  6545. #ifdef TCPSOCKET
  6546.     if (success) tn_exit = exitonclose;
  6547. #endif /* TCPSOCKET */
  6548.     return(success);
  6549.       default:
  6550.     return(-2);
  6551.     } /* End of SET EXIT switch() */
  6552.  
  6553. default:
  6554.     break;
  6555. }
  6556.  
  6557. switch (xx) {
  6558.   extern int cxflow[];
  6559.  
  6560.   case XYFILE:                /* SET FILE */
  6561.     return(setfil(rmsflg));
  6562.  
  6563.   case XYFLOW: {            /* FLOW-CONTROL */
  6564.     struct FDB k1, k2;
  6565.     cmfdbi(&k1,_CMKEY,
  6566. /* This is because chained FDB's don't give chained help yet */
  6567. #ifdef Plan9
  6568. #ifdef CK_RTSCTS
  6569.        "Flow control type, one of the following:\n\
  6570.    keep   none    rts/cts\n\
  6571.  or connection type",
  6572. #else
  6573.        "Flow control type, one of the following:\n\
  6574.    keep   none\n\
  6575.  or connection type",
  6576. #endif /* CK_RTSCTS */
  6577. #else
  6578. #ifdef CK_RTSCTS
  6579. #ifdef CK_DTRCD
  6580.        "Flow control type, one of the following:\n\
  6581.    dtr/cd    ctr/cts   keep    none    rts/cts   xon/xoff\n\
  6582.  or connection type",
  6583. #else
  6584.        "Flow control type, one of the following:\n\
  6585.    keep   none    rts/cts   xon/xoff\n\
  6586.  or connection type",
  6587. #endif /* CK_DTRCD */
  6588. #else
  6589.        "Flow control type, one of the following:\n\
  6590.    keep   none    xon/xoff\n\
  6591.  or connection type",
  6592. #endif /* CK_RTSCTS */
  6593. #endif /* Plan9 */
  6594.        "","",ncxtypesw, 4, xxstring, cxtypesw, &k2);
  6595.     cmfdbi(&k2,_CMKEY,"","","", nflo, 0, xxstring, flotab, NULL);
  6596.     x = cmfdb(&k1);
  6597.     if (x < 0) {            /* Error */
  6598.     if (x == -2 || x == -9)
  6599.       printf("?No keywords or switches match: \"%s\"\n",atmbuf);
  6600.     return(x);
  6601.     }
  6602.     z = cmresult.nresult;        /* Keyword value */
  6603.     if (cmresult.fdbaddr == &k2) {    /* Flow-control type keyword table */
  6604.     if ((x = cmcfm()) < 0)        /* Set it immediately */
  6605.       return(x);
  6606.     flow = z;
  6607.     debug(F101,"set flow","",flow);
  6608. #ifdef CK_SPEED
  6609.     if (flow == FLO_XONX)        /* Xon/Xoff forces prefixing */
  6610.       ctlp[XON] = ctlp[XOFF] = ctlp[XON+128] = ctlp[XOFF+128] = 1;
  6611. #endif /* CK_SPEED */
  6612.     autoflow = (flow == FLO_AUTO);
  6613.     return(success = 1);        /* Done */
  6614.     }
  6615.     debug(F101,"set flow /blah 1","",z); /* SET FLOW /for-what */
  6616.     if ((y = cmkey(flotab,nflo,"Flow control type","none",xxstring)) < 0)
  6617.       return(y);
  6618.     if ((x = cmcfm()) < 0) return(x);
  6619.     debug(F101,"set flow /blah 2","",y);
  6620.     if (z != FLO_AUTO && z >= 0 && z <= CXT_MAX)
  6621.       cxflow[z] = y;
  6622.     debug(F101,"set flow","",flow);
  6623.     debug(F101,"set flow autoflow","",autoflow);
  6624.     return(success = 1);
  6625.   }
  6626.  
  6627. case XYHAND:                /* HANDSHAKE */
  6628.     if ((y = cmkey(hshtab,nhsh,"","none",xxstring)) < 0) return(y);
  6629.     if (y == 998) {
  6630.     if ((x = cmnum("ASCII value","",10,&y,xxstring)) < 0)
  6631.       return(x);
  6632.     if ((y < 1) || ((y > 31) && (y != 127))) {
  6633.         printf("?Character must be in ASCII control range\n");
  6634.         return(-9);
  6635.     }
  6636.     }
  6637.     if ((x = cmcfm()) < 0) return(x);
  6638.     turn = (y > 0127) ? 0 : 1 ;
  6639.     turnch = y;
  6640.     return(success = 1);
  6641.  
  6642. #ifndef NOSPL
  6643. case XYMACR:                /* SET MACRO */
  6644.     if ((y = cmkey(smactab,2,"","",xxstring)) < 0) return(y);
  6645.     switch (y) {
  6646.       case 0: return(success = seton(&mecho));
  6647.       case 1: return(success = seton(&merror[cmdlvl]));
  6648.       default: return(-2);
  6649.     }
  6650. #endif /* NOSPL */
  6651.  
  6652.   case XYMSGS:
  6653. #ifdef VMS
  6654.     if ((z = cmkey(onoff,2,"","",xxstring)) < 0) return(z);
  6655.     if ((y = cmcfm()) < 0) return(y);
  6656.     vms_msgs = z;
  6657.     printf("Sorry, SET MESSAGES not implemented yet\n");
  6658.     return(success = 0);
  6659. #endif /* VMS */
  6660. default:
  6661.     break;
  6662. }
  6663.  
  6664. switch (xx) {
  6665.  
  6666. case XYPARI:                /* PARITY */
  6667.     if ((y = cmkey(partbl,npar,"","none",xxstring)) < 0)
  6668.       return(y);
  6669.  
  6670. /* If parity not none, then we also want 8th-bit prefixing */
  6671.  
  6672. #ifdef HWPARITY
  6673.     if (y == 'H') {            /* Hardware */
  6674.     if ((x = cmkey(hwpartbl,nhwpar,"","even",xxstring)) < 0)
  6675.       return(x);
  6676.     }
  6677. #endif /* HWPARITY */
  6678.  
  6679.     if ((z = cmcfm()) < 0)
  6680.       return(z);
  6681.  
  6682. #ifdef HWPARITY
  6683.     if (y == 'H') {            /* 8 data bits plus hardware parity */
  6684.     parity = 0;
  6685. #ifndef NOXFER
  6686.     ebqflg = 0;
  6687. #endif /* NOXFER */
  6688.     hwparity = x;
  6689.     } else {                /* 7 data bits + software parity */
  6690.     hwparity = 0;
  6691. #endif /* HWPARITY */
  6692.     parity = y;
  6693. #ifndef NOXFER
  6694.     ebqflg = (parity) ? 1 : 0;
  6695. #endif /* NOXFER */
  6696. #ifdef HWPARITY
  6697.     }
  6698. #endif /* HWPARITY */
  6699.  
  6700.     return(success = 1);
  6701.  
  6702. #ifndef NOFRILLS
  6703. case XYPROM:                /* SET PROMPT */
  6704. /*
  6705.   Note: xxstring not invoked here.  Instead, it is invoked every time the
  6706.   prompt is issued.  This allows the prompt string to contain variables
  6707.   that can change, like \v(dir), \v(time), etc.
  6708. */
  6709.     sprintf(line,
  6710.         "{%s}",                /* Default might have a trailing space */
  6711.         inserver ? ikprompt : ckprompt
  6712.         );
  6713.     if ((x = cmtxt("Program's command prompt",line,&s,NULL)) < 0)
  6714.       return(x);
  6715.     s = brstrip(s);            /* Remove enclosing braces, if any */
  6716. #ifdef COMMENT
  6717. /*
  6718.   Let's not do this any more -- we don't do it anywhere else.
  6719. */
  6720.     else if (*s == '"') {        /* For compatibility with pre-5A */
  6721.     x = (int)strlen(s);
  6722.     if (s[x-1] == '"') {
  6723.         s[x-1] = NUL;
  6724.         s++;
  6725.     }
  6726.     }
  6727. #endif /* COMMENT */
  6728.     cmsetp(s);                /* Set the prompt */
  6729.     return(success = 1);
  6730. #endif /* NOFRILLS */
  6731.  
  6732. #ifndef NOXFER
  6733. case XYRETR:                /* RETRY: per-packet retry limit */
  6734.     y = cmnum("Maximum retries per packet","10",10,&x,xxstring);
  6735.     if (x < 0) x = 0;
  6736.     if ((x = setnum(&maxtry,x,y,999)) < 0) return(x);
  6737. #ifdef COMMENT
  6738.     if (maxtry <= wslotr) {
  6739.     printf("?Retry limit must be greater than window size\n");
  6740.     return(success = 0);
  6741.     }
  6742. #endif /* COMMENT */
  6743.     if (rmsflg) {
  6744.     sstate = setgen('S', "403", ckitoa(maxtry), "");
  6745.     return((int) sstate);
  6746.     } else return(success = x);
  6747. #endif /* NOXFER */
  6748.  
  6749. #ifndef NOSERVER
  6750. case XYSERV:                /* SET SERVER items */
  6751.     if ((y = cmkey(srvtab,nsrvt,"","",xxstring)) < 0) return(y);
  6752.     switch (y) {
  6753.       case XYSERI:
  6754.     if ((y = cmnum("Number of seconds, or 0 for no idle timeout",
  6755.                        "0",10,&x,xxstring)) < 0)
  6756.       return(y);
  6757.     if (x < 0)
  6758.       x = 0;
  6759.     if ((y = cmcfm()) < 0)
  6760.       return(y);
  6761. #ifndef OS2
  6762.     srvtim = 0;
  6763. #endif /* OS2 */
  6764.     srvidl = x;
  6765.     return(success = 1);
  6766.       case XYSERT:
  6767.     if ((y = cmnum("Interval for server NAKs, 0 = none",ckitoa(DSRVTIM),
  6768.                10,&x, xxstring)) < 0)
  6769.       return(y);
  6770.     if (x < 0) {
  6771.         printf("\n?Specify a positive number, or 0 for no server NAKs\n");
  6772.         return(0);
  6773.     }
  6774.     if ((y = cmcfm()) < 0) return(y);
  6775.     if (rmsflg) {
  6776.         sstate = setgen('S', "404", ckitoa(x), "");
  6777.         return((int) sstate);
  6778.     } else {
  6779. #ifndef OS2
  6780.         srvidl = 0;
  6781. #endif /* OS2 */
  6782.         srvtim = x;            /* Set the server timeout variable */
  6783.         return(success = 1);
  6784.     }
  6785.       case XYSERD:            /* SERVER DISPLAY */
  6786.     return(success = seton(&srvdis)); /* ON or OFF... */
  6787.  
  6788. #ifndef NOSPL
  6789.       case XYSERP:            /* SERVER GET-PATH */
  6790.     return(parsdir(2));
  6791. #endif /* NOSPL */
  6792.  
  6793.       case XYSERL:            /* SERVER LOGIN */
  6794.     return(cklogin());
  6795.  
  6796.       case XYSERC:            /* SERVER CD-MESSAGE */
  6797.     x = rmsflg ?
  6798.       cmkey(onoff,2,"","",xxstring) :
  6799.       cmkey(cdmsg,3,"","",xxstring);
  6800.     if (x < 0)
  6801.       return(x);
  6802.     if (x == 2) {            /* CD-MESSAGE FILE */
  6803.         if ((x = cmtxt("Name of file","",&s,NULL)) < 0)
  6804.           return(x);
  6805.         if (!*s) {
  6806.         s = NULL;
  6807.         srvcdmsg = 0;
  6808.         }
  6809.         makestr(&cdmsgstr,s);
  6810.         makelist(cdmsgstr,cdmsgfile,8);
  6811.         return(success = 1);
  6812.     }
  6813.     if ((y = cmcfm()) < 0)        /* CD-MESSAGE ON/OFF */
  6814.       return(y);
  6815.     if (rmsflg) {
  6816.         sstate = setgen('S', "420", x ? "1" : "0", "");
  6817.         return((int) sstate);
  6818.     } else {
  6819.         if (x > 0)
  6820.           srvcdmsg |= 1;
  6821.         else
  6822.           srvcdmsg &= 2;
  6823.         return(success = 1);
  6824.     }
  6825.       case XYSERK:            /* SERVER KEEPALIVE */
  6826.     return(success = seton(&srvping)); /* ON or OFF... */
  6827.  
  6828.       default:
  6829.     return(-2);
  6830.     }
  6831. #endif /* NOSERVER */
  6832. }
  6833.  
  6834. switch (xx) {
  6835. #ifdef UNIX
  6836. #ifndef NOJC
  6837. case XYSUSP:                /* SET SUSPEND */
  6838.     seton(&suspend);            /* on or off... */
  6839.     return(success = 1);
  6840. #endif /* NOJC */
  6841. #endif /* UNIX */
  6842.  
  6843. case XYTAKE:                /* SET TAKE */
  6844.     if ((y = cmkey(taktab,4,"","",xxstring)) < 0) return(y);
  6845.     switch (y) {
  6846.       case 0: return(success = seton(&techo));
  6847. #ifndef NOSPL
  6848.       case 1: return(success = seton(&takerr[cmdlvl]));
  6849. #else
  6850.       case 1: return(success = seton(&takerr[tlevel]));
  6851. #endif /* NOSPL */
  6852.       case 2: techo = 0; return(success = 1); /* For compatibility with */
  6853.       case 3: techo = 1; return(success = 1); /* MS-DOS Kermit */
  6854.       default: return(-2);
  6855.     }
  6856.  
  6857. #ifndef NOSCRIPT
  6858. case XYSCRI:                /* SET SCRIPT */
  6859.     if ((y = cmkey(scrtab,1,"","echo",xxstring)) < 0) return(y);
  6860.     switch (y) {
  6861.       case 0: return(success = seton(&secho));
  6862.       default: return(-2);
  6863.     }
  6864. #endif /* NOSCRIPT */
  6865.  
  6866. default:
  6867.     break;
  6868. }
  6869.  
  6870. #ifndef NOLOCAL
  6871. switch (xx) {
  6872. case XYTERM:                /* SET TERMINAL */
  6873.     x = settrm();
  6874.     success = (x > 0) ? 1 : 0;
  6875.     return(x);
  6876.  
  6877. #ifdef NT
  6878. case XYWIN95:                /* SET WIN95 workarounds */
  6879.     x = setwin95();
  6880.     success = (x > 0 ? 1 : 0);
  6881.     return(x);
  6882. #endif /* NT */
  6883.  
  6884. #ifdef OS2
  6885. case XYDLR:                /* SET DIALER workarounds */
  6886.     x = setdialer();
  6887.     success = (x > 0 ? 1 : 0);
  6888.     return(x);
  6889.  
  6890. case XYTITLE:                /* SET TITLE of window */
  6891.     x = settitle();
  6892.     success = (x > 0 ? 1 : 0);
  6893.     return(x);
  6894. #endif /* OS2 */
  6895.  
  6896. #ifdef OS2MOUSE
  6897. case XYMOUSE:                /* SET MOUSE */
  6898.     return(success = setmou());
  6899. #endif /* OS2MOUSE */
  6900.  
  6901. case XYBELL:                /* SET BELL */
  6902.     return( success = setbell() );
  6903.  
  6904. #ifdef OS2
  6905. case XYPRTY:
  6906.     return( success = setprty() );
  6907. #endif /* OS2 */
  6908.  
  6909. default:
  6910.     break;
  6911. }
  6912. #endif /* NOLOCAL */
  6913.  
  6914. switch (xx) {
  6915.  
  6916. /* SET SEND/RECEIVE protocol parameters. */
  6917.  
  6918. #ifndef NOXFER
  6919. case XYRECV:
  6920. case XYSEND:
  6921.     return(setsr(xx,rmsflg));
  6922. #endif /* NOXFER */
  6923.  
  6924. #ifndef NOLOCAL                /* Session log text/binary selection */
  6925. #ifdef OS2ORUNIX            /* UNIX needs it */
  6926. #define _XYSESS
  6927. #endif /* OS2ORUNIX */
  6928. #ifdef OSK                /* OS-9 too */
  6929. #define _XYSESS
  6930. #endif /* OSK */
  6931.  
  6932. #ifdef _XYSESS
  6933. case XYSESS:                /* SESSION-LOG */
  6934.     if ((x = cmkey(sfttab,nsfttab,"type of file",
  6935. #ifdef OS2
  6936.            "binary",
  6937. #else /* OS2 */
  6938.            "text",
  6939. #endif /* OS2 */
  6940.            xxstring
  6941.            )
  6942.      ) < 0)
  6943.       return(x);
  6944.     if ((y = cmcfm()) < 0) return(y);
  6945.     sessft = x;
  6946.     return(success = 1);
  6947. #undef _XYSESS
  6948. #endif /* _XYSESS */
  6949.  
  6950. case XYSPEE:                /* SET SPEED */
  6951.     lp = line;
  6952.     sprintf(lp,"Transmission rate for %s in bits per second",ttname);
  6953.  
  6954.     zz = -1L;
  6955.     if ((x = cmkey(spdtab,nspd,line,"",xxstring)) < 0) {
  6956.     if (x == -3) printf("?value required\n");
  6957. #ifdef USETCSETSPEED
  6958.     /* In this case, any number can be tried */
  6959.     /* There's a parse error message but the request still goes thru */
  6960.     if (rdigits(atmbuf))
  6961.       zz = atol(atmbuf);
  6962.     else
  6963. #endif /* USETCSETSPEED */
  6964.     return(x);
  6965.     }
  6966.     if ((y = cmcfm()) < 0) return(y);
  6967. #ifdef IKSD
  6968.     if (inserver) {
  6969.         printf("?Sorry, command disabled.\r\n");
  6970.         return(success = 0);
  6971.     }
  6972. #endif /* IKSD */
  6973.     if (!local) {
  6974.     printf("?Sorry, you must SET LINE first\n");
  6975.     return(success = 0);
  6976.     } else if (network) {
  6977.     printf("\n?Speed cannot be set for network connections\n");
  6978.     return(success = 0);
  6979.     }
  6980.  
  6981. /*
  6982.   Note: This way of handling speeds is not 16-bit safe for speeds greater
  6983.   than 230400.  The argument to ttsspd() should have been a long.
  6984. */
  6985. #ifdef USETCSETSPEED
  6986.     if (zz > -1L)
  6987.       x = zz / 10L;
  6988. #endif /* USETCSETSPEED */
  6989.       zz = (long) x * 10L;
  6990.     if (zz == 130L) zz = 134L;
  6991.     if (zz == 70L) zz = 75L;        /* (see spdtab[] definition) */
  6992.     if (ttsspd(x) < 0)  {        /* Call ttsspd with cps, not bps! */
  6993.     printf("?Unsupported line speed - %ld\n",zz);
  6994.     return(success = 0);
  6995.     } else {
  6996. #ifdef CK_TAPI
  6997.     if (!tttapi || tapipass)
  6998.       speed = ttgspd();        /* Read it back */
  6999.     else
  7000.       speed = zz;
  7001. #else /* CK_TAPI */
  7002.     speed = ttgspd();        /* Read it back */
  7003. #endif /* CK_TAPI */
  7004.     if (speed != zz)  {        /* Call ttsspd with cps, not bps! */
  7005.         printf("?SET SPEED fails, speed is %ld\n",speed);
  7006.         return(success = 0);
  7007.     }
  7008.     if (pflag && !cmdsrc()) {
  7009.         if (speed == 8880)
  7010.           printf("%s, 75/1200 bps\n",ttname);
  7011.         else if (speed == 134)
  7012.           printf("%s, 134.5 bps\n",ttname);
  7013.         else
  7014.           printf("%s, %ld bps\n",ttname,speed);
  7015.     }
  7016.     return(success = 1);
  7017.     }
  7018. #endif /* NOLOCAL */
  7019.  
  7020. #ifndef NOXFER
  7021.   case XYXFER:                /* SET TRANSFER */
  7022.     if ((y = cmkey(rmsflg ? rtstab : tstab, /* (or REMOTE SET TRANSFER) */
  7023.            rmsflg ? nrts : nts,
  7024.            "","character-set",xxstring)) < 0) return(y);
  7025.     switch (y) {
  7026. #ifdef XFRCAN
  7027.       case XYX_CAN:            /* CANCELLATION */
  7028.     if ((z = cmkey(onoff,2,"","",xxstring)) < 0) return(z);
  7029.     if (z == 0) {            /* OFF */
  7030.         if ((y = cmcfm()) < 0) return(y);
  7031.         xfrcan = 0;
  7032.     } else {
  7033.         if ((y = cmnum("ASCII code for cancellation character","3",10,&x,
  7034.                xxstring)) < 0)
  7035.           return(y);
  7036.         if (x > 31 && x != 127) {
  7037.         printf("Cancel character must be in ASCII control range\n");
  7038.         return(-9);
  7039.         }
  7040.         if ((y = cmnum("How many required to cause cancellation",
  7041.                "2",10,&z, xxstring)) < 0)
  7042.           return(y);
  7043.         if (z < 2) {
  7044.         printf("Number must be 2 or greater\n");
  7045.         return(-9);
  7046.         }
  7047.         if ((y = cmcfm()) < 0) return(y);
  7048.         xfrcan = 1;            /* CANCELLATION ON */
  7049.         xfrchr = x;            /* Using this character */
  7050.         xfrnum = z;            /* Needing this many of them */
  7051.     }
  7052.     return(success = 1);
  7053. #endif /* XFRCAN */
  7054.  
  7055. #ifndef NOCSETS
  7056.       case XYX_CSE:            /* CHARACTER-SET */
  7057.     if ((y = cmkey(tcstab,ntcs,"","transparent",xxstring)) < 0) return(y);
  7058.     if ((x = cmcfm()) < 0) return(x);
  7059.     if (rmsflg) {
  7060.         sstate = setgen('S', "405", tcsinfo[y].designator, "");
  7061.         return((int) sstate);
  7062.     } else {
  7063.         extern int s_cset, fcharset, axcset[];
  7064.         tslevel = (y == TC_TRANSP) ? 0 : 1; /* transfer syntax level */
  7065.         tcharset = y;        /* transfer character set */
  7066.         if (s_cset == XMODE_A)    /* If SEND CHARACTER-SET is AUTO */
  7067.           if (y > -1 && y <= MAXTCSETS)
  7068.         if (axcset[y] > -1 && axcset[y] > MAXFCSETS)
  7069.           fcharset = axcset[y]; /* Auto-pick file charset */
  7070.         setxlatype(tcharset,fcharset); /* Translation type */
  7071.         return(success = 1);
  7072.     }
  7073. #endif /* NOCSETS */
  7074.  
  7075.       case XYX_LSH:            /* LOCKING-SHIFT */
  7076.       if ((y = cmkey(lstab,nls,"","on",xxstring)) < 0)
  7077.         return(y);
  7078.       if ((x = cmcfm()) < 0) return(x);
  7079.       lscapr = (y == 1) ? 1 : 0;    /* ON: requested = 1 */
  7080.       lscapu = (y == 2) ? 2 : 0;    /* FORCED:  used = 1 */
  7081.       return(success = 1);
  7082.  
  7083. #ifdef CK_XYZ
  7084.       case XYX_PRO:            /* Protocol */
  7085. #ifndef OS2
  7086.     if (inserver) {
  7087.         printf("?Sorry, only Kermit protocol is available\n");
  7088.         return(-9);
  7089.     }
  7090. #endif /* OS2 */
  7091.     return(setproto());
  7092. #endif /* CK_XYZ */
  7093.  
  7094.       case XYX_MOD:            /* Mode */
  7095.     if ((y = cmkey(xfrmtab,2,"","automatic",xxstring)) < 0)
  7096.       return(y);
  7097.     if ((x = cmcfm()) < 0) return(x);
  7098.     if (rmsflg) {
  7099.         sstate = setgen('S', "410", y == XMODE_A ? "0" : "1", "");
  7100.         return((int)sstate);
  7101.     }
  7102.     g_xfermode = y;
  7103.     xfermode = y;
  7104.     return(success = 1);
  7105.  
  7106. #ifndef NOLOCAL
  7107.       case XYX_DIS:            /* Display */
  7108.     return(doxdis());
  7109. #endif /* NOLOCAL */
  7110.  
  7111.       case XYX_SLO:            /* Slow-start */
  7112.         return(seton(&slostart));
  7113.  
  7114. #ifndef NOSPL
  7115.       case XYX_CRC:            /* CRC */
  7116.         return(seton(&docrc));
  7117. #endif /* NOSPL */
  7118.  
  7119.       case XYX_BEL:            /* Bell */
  7120.         return(seton(&xfrbel));
  7121.  
  7122. #ifdef PIPESEND
  7123.       case XYX_PIP:            /* Pipes */
  7124. #ifndef NOPUSH
  7125.     if (nopush) {
  7126. #endif /* NOPUSH */
  7127.         printf("Sorry, access to pipes is disabled\n");
  7128.         return(-9);
  7129. #ifndef NOPUSH
  7130.     } else
  7131. #endif /* NOPUSH */
  7132.       return(seton(&usepipes));
  7133. #endif /* PIPESEND */
  7134.  
  7135.       case XYX_INT:            /* Interruption */
  7136.         return(seton(&xfrint));
  7137.  
  7138.       default:
  7139.     return(-2);
  7140.     }
  7141. #endif /* NOXFER */
  7142. }
  7143.  
  7144. switch (xx) {
  7145.  
  7146. #ifndef NOXMIT
  7147.   case XYXMIT:                /* SET TRANSMIT */
  7148.     return(setxmit());
  7149. #endif /* NOXMIT */
  7150.  
  7151. #ifndef NOXFER
  7152. #ifndef NOCSETS
  7153.   case XYUNCS:                /* UNKNOWN-CHARACTER-SET */
  7154.     if ((y = cmkey(ifdtab,2,"","discard",xxstring)) < 0) return(y);
  7155.     if ((x = cmcfm()) < 0) return(x);
  7156.     unkcs = y;
  7157.     return(success = 1);
  7158. #endif /* NOCSETS */
  7159. #endif /* NOXFER */
  7160.  
  7161. #ifndef NOPUSH
  7162. #ifdef UNIX
  7163. case XYWILD:                /* WILDCARD-EXPANSION */
  7164.     if ((y = cmkey(wildtab,2,"who expands wildcards","kermit",xxstring)) < 0)
  7165.       return(y);
  7166.     if ((z = cmkey(wdottab,
  7167.            2,
  7168.            "whether to match filenames that start with \".\"",
  7169.            "/no-match-dot-files",
  7170.            xxstring)
  7171.      ) < 0)
  7172.       return(z);
  7173.     if ((x = cmcfm()) < 0) return(x);
  7174.     if (nopush) {
  7175.     if (y > 0) {
  7176.         printf("Shell expansion is disabled\n");
  7177.         return(success = 0);
  7178.     }
  7179.     }
  7180.     wildxpand = y;
  7181.     matchdot = z;
  7182.     return(success = 1);
  7183. #endif /* UNIX */
  7184. #endif /* NOPUSH */
  7185.  
  7186. #ifndef NOXFER
  7187.   case XYWIND:                /* WINDOW-SLOTS */
  7188.     if (protocol == PROTO_K) {
  7189.     y = cmnum("Window size for Kermit protocol, 1 to 32",
  7190.           "1", 10, &x, xxstring);
  7191.     y = setnum(&z,x,y,MAXWS);    /* == 32 */
  7192.     }
  7193. #ifdef CK_XYZ
  7194.     else if (protocol == PROTO_Z) {
  7195.     y = cmnum("Window size for ZMODEM protocol, 0 to 65535",
  7196.           "0", 10, &x, xxstring);
  7197.     y = setnum(&z,x,y,65535);
  7198.     }
  7199. #endif /* CK_XYZ */
  7200.     else {
  7201.     y = cmnum("Window size for current protocol",
  7202.           "", 10, &x, xxstring);
  7203.     y = setnum(&z,x,y,65472);    /* Doesn't matter - we won't use it */
  7204.     }
  7205.     if (y < 0) return(y);
  7206.     if (protocol == PROTO_K) {
  7207.     if (z < 1)
  7208.       z = 1;
  7209.     }
  7210. #ifdef CK_XYZ
  7211.     else if (protocol == PROTO_Z) {
  7212.         /* Zmodem windowing is closer to Kermit packet length */
  7213.         /* than Kermit window size.  If Window size is zero   */
  7214.         /* an end of frame and CRC is sent only at the end of */
  7215.         /* the file (default).  Otherwise, an End of Frame    */
  7216.         /* and CRC are sent after Window Size number of bytes */
  7217.         if (z < 0)            /* Disable windowing  */
  7218.             z = 0;
  7219.     } else {
  7220.     printf("?SET WINDOW does not apply to %s protocol\n",
  7221.            ptab[protocol].p_name
  7222.            );
  7223.     }
  7224. #endif /* CK_XYZ */
  7225.  
  7226. #ifdef COMMENT
  7227.     /* This is taken care of automatically now in protocol negotiation */
  7228.     if (maxtry < z) {
  7229.     printf("?Window slots must be less than retry limit\n");
  7230.     return(success = 0);
  7231.     }
  7232. #endif /* COMMENT */
  7233.     if (protocol == PROTO_K && rmsflg) { /* Set remote window size */
  7234.     wslotr = z;            /* Set local window size too */
  7235.     ptab[protocol].winsize = wslotr;
  7236.     sstate = setgen('S', "406", ckitoa(z), "");
  7237.     return((int) sstate);
  7238.     }
  7239.     wslotr = z;                /* Set requested window size here */
  7240.     ptab[protocol].winsize = wslotr;    /* and in protocol-specific table */
  7241.     if (protocol == PROTO_K) {        /* And for Kermit only... */
  7242.     swcapr = (wslotr > 1) ? 1 : 0;    /* set window bit in capas word */
  7243.     if (wslotr > 1) {        /* Window size > 1? */
  7244.         y = adjpkl(urpsiz,wslotr,bigrbsiz); /* Maybe adjust packet size */
  7245.         if (y != urpsiz) {        /* Did it change? */
  7246.         urpsiz = y;
  7247.         if (msgflg)
  7248.           printf(
  7249. " Adjusting receive packet-length to %d for %d window slots\n",
  7250.              urpsiz,
  7251.              wslotr
  7252.              );
  7253.         }
  7254.     }
  7255.     }
  7256.     return(success = 1);
  7257. #endif /* NOXFER */
  7258. }
  7259.  
  7260. switch (xx) {
  7261.  
  7262. #ifndef NOSPL
  7263.   case XYOUTP:                /* OUTPUT command parameters */
  7264.     if ((y = cmkey(outptab,noutptab,"OUTPUT command parameter","pacing",
  7265.            xxstring)) < 0)
  7266.       return(y);
  7267.     switch(y) {                /* Which parameter */
  7268.       case OUT_PAC:            /* PACING */
  7269.     y = cmnum("Milliseconds to pause between each OUTPUT character","100",
  7270.           10,&x,xxstring);
  7271.     y = setnum(&z,x,y,16383);    /* Verify and get confirmation */
  7272.     if (y < 0) return(y);
  7273.     if (z < 0) z = 0;        /* (save some space) */
  7274.     pacing = z;
  7275.     return(success = 1);
  7276.       case OUT_ESC:            /* Special-escapes */
  7277.     return(seton(&outesc));
  7278.       default:                /* (shouldn't happen) */
  7279.     return(-2);
  7280.     }
  7281. #endif /* NOSPL */
  7282.  
  7283. #ifdef CK_SPEED
  7284.   case XYQCTL: {
  7285.     short *p;
  7286.     int zz;
  7287.     if ((z = cmkey(ctltab,2, "control-character prefixing option",""
  7288.            ,xxstring)) < 0)
  7289.       return(z);
  7290.     /* Make space for a temporary copy of the prefixing table */
  7291.  
  7292.     p = (short *)malloc(256 * sizeof(short));
  7293.     if (!p) {
  7294.     printf("?Internal error - malloc failure\n");
  7295.     return(-9);
  7296.     }
  7297.     for (i = 0; i < 256; i++) p[i] = ctlp[i]; /* Copy current table */
  7298.  
  7299.     switch (z) {
  7300.       case 0:                /* UNPREFIXED control character */
  7301.       case 1:                /* PREFIXED control character */
  7302.     while (1) {            /* Collect a list of numbers */
  7303. #ifndef NOSPL
  7304.         x_ifnum = 1;        /* Turn off complaints from eval() */
  7305. #endif /* NOSPL */
  7306.         if ((x = cmnum((z == 0) ?
  7307. "\n Numeric ASCII value of control character that needs NO prefix,\n\
  7308.  or the word \"all\", or carriage return to complete the list" :
  7309. "\n Numeric ASCII value of control character that MUST BE prefixed,\n\
  7310.  or the word \"all\", or carriage return to complete the list",
  7311.                "",10,&y,xxstring
  7312.                )) < 0) {
  7313. #ifndef NOSPL
  7314.         x_ifnum = 0;
  7315. #endif /* NOSPL */
  7316.         if (x == -3) {
  7317.             if ((x = cmcfm()) < 0) return(x);
  7318.             break;
  7319.         }
  7320.         if (x == -2) {
  7321.             if (p) { free(p); p = NULL; }
  7322.             debug(F110,"SET CONTROL atmbuf",atmbuf,0);
  7323.             if (!ckstrcmp(atmbuf,"all",3,0) ||
  7324.             !ckstrcmp(atmbuf,"al",2,0) ||
  7325.             !ckstrcmp(atmbuf,"a",1,0)) {
  7326.             if ((x = cmcfm()) < 0) /* Get confirmation */
  7327.               return(x);
  7328.             if (z)
  7329.               prefixing = PX_ALL;
  7330. #ifndef UNPREFIXZERO
  7331.             /* Set all values, but don't touch 0 */
  7332.             for (y = 1; y < 32; y++) ctlp[y] = (short) z;
  7333. #else
  7334.             /* Zero too */
  7335.             for (y = 0; y < 32; y++) ctlp[y] = (short) z;
  7336. #endif /* UNPREFIXZERO */
  7337.             for (y = 127; y < 160; y++) ctlp[y] = (short) z;
  7338.             ctlp[255] = (short) z;
  7339.             /* Watch out for XON and XOFF */
  7340.             if (flow == FLO_XONX && z == 0) {
  7341.                 if (msgflg) {
  7342.                 printf(
  7343. " XON/XOFF characters 17, 19, 145, 147 not affected.\n");
  7344.                 printf(
  7345. #ifdef CK_RTSCTS
  7346. " SET FLOW NONE or RTS/CTS to transmit these characters unprefixed.\n"
  7347. #else
  7348. " SET FLOW NONE to transmit these characters unprefixed.\n"
  7349. #endif /* CK_RTSCTS */
  7350.                        );
  7351.                 }
  7352.                 ctlp[XON] =
  7353.                   ctlp[XOFF] =
  7354.                 ctlp[XON+128] =
  7355.                   ctlp[XOFF+128] = 1;
  7356.             }
  7357. #ifdef TNCODE
  7358.             /* Watch out for TELNET IAC */
  7359.             if (network && (ttnproto == NP_TELNET) && z == 0) {
  7360.                 ctlp[255] = 1;
  7361.                 if (parity == 'e' || parity == 'm') ctlp[127] = 1;
  7362.                 ctlp[13] = 1;
  7363.                 if (msgflg)
  7364.                   printf(
  7365.                    " TELNET IAC = 255, CR = 13, not affected.\n");
  7366.             }
  7367. #endif /* TNCODE */
  7368. #ifndef UNPREFIXZERO
  7369. #ifdef OS2
  7370.             if (z == 0 && protocol != PROTO_K)
  7371.               ctlp[0] = 0;
  7372. #endif /* OS2 */
  7373. #endif /* UNPREFIXZERO */
  7374.             return(success = 1);
  7375.             } else {
  7376.             printf("?Please specify a number or the word ALL\n");
  7377.             return(-9);
  7378.             }
  7379.         } else {
  7380.             if (p) free(p);
  7381.             return(x);
  7382.         }
  7383.         }
  7384. #ifndef NOSPL
  7385.         x_ifnum = 0;
  7386. #endif /* NOSPL */
  7387. #ifdef UNPREFIXZERO
  7388.         zz = 0;
  7389. #else
  7390. #ifndef OS2
  7391.         zz = 1 - z;
  7392. #else
  7393.         zz = 0;            /* Allow 0 (but only for Zmodem) */
  7394. #endif /* OS2 */
  7395. #endif /* UNPREFIXZERO */
  7396.  
  7397.         /* printf("x = %d, y = %d, z = %d, zz = %d\n", x,y,z,zz); */
  7398.  
  7399.         if ((y >  31 && y < 127) ||    /* A specific numeric value */
  7400.         (y > 159 && y < 255) ||    /* Check that it is a valid */
  7401.         (y < zz) ||        /* control code. */
  7402.         (y > 255)) {
  7403.         printf("?Values allowed are: %d-31, 127-159, 255\n",zz);
  7404.         if (p) free(p);
  7405.         return(-9);
  7406.         }
  7407.         x = y & 127;        /* Get 7-bit value */
  7408.         if (z == 0) {        /* If they are saying it is safe... */
  7409.         if (((flow == FLO_XONX) && /* If flow control is Xon/Xoff */
  7410.           (x == XON || x == XOFF)) /* XON & XOFF chars not safe. */
  7411.          ) {
  7412.             if (msgflg)
  7413.               printf("Sorry, not while Xon/Xoff is in effect.\n");
  7414.             if (p) free(p);
  7415.             return(-9);
  7416.         }
  7417. #ifdef TNCODE
  7418.         else if (network && (ttnproto == NP_TELNET)
  7419.              && (y == CR || (unsigned) y == (unsigned) 255)) {
  7420.             if (msgflg)
  7421.               printf("Sorry, not on a TELNET connection.\n");
  7422.             if (p) free(p);
  7423.             return(-9);
  7424.         }
  7425. #endif /* TNCODE */
  7426.         }
  7427.         p[y] = (char) z;        /* All OK, set flag */
  7428.     }                /* End of while loop */
  7429. /*
  7430.   Get here only if they have made no mistakes.  Copy temporary table back to
  7431.   permanent one, then free temporary table and return successfully.
  7432. */
  7433.     for (i = 0; i < 256; i++) ctlp[i] = p[i];
  7434.     if (p) free(p);
  7435.     return(success = 1);
  7436.       default:
  7437.     return(-2);
  7438.     }
  7439.   }
  7440. #endif /* CK_SPEED */
  7441. }
  7442.  
  7443. switch (xx) {
  7444.  
  7445. #ifndef NOXFER
  7446.   case XYREPT:
  7447.     if ((y = cmkey(rpttab,2,"repeat-count compression parameter","",xxstring))
  7448.     < 0)
  7449.       return(y);
  7450.     switch(y) {
  7451.       case 0:
  7452.     return(success = seton(&rptena)); /* REPEAT COUNTS = ON, OFF */
  7453.       case 1:                /* REPEAT MININUM number */
  7454.     printf("(not implemented yet, nothing happens)\n");
  7455.     return(-9);
  7456.       case 2:                /* REPEAT PREFIX char */
  7457.     if ((x = cmnum("ASCII value","",10,&z,xxstring)) < 0)
  7458.       return(x);
  7459.     if ((x = cmcfm()) < 0) return(x);
  7460.     if ((z > 32 && z < 63) || (z > 95 && z < 127)) {
  7461.         if (y == 1) rptmin = (CHAR) z; else myrptq = (CHAR) z;
  7462.         return(success = 1);
  7463.     } else {
  7464.         printf("?Illegal value for prefix character\n");
  7465.         return(-9);
  7466.     }
  7467.     }
  7468. #endif /* NOXFER */
  7469.  
  7470. #ifndef NOSPL
  7471.   case XYALRM: {
  7472. #ifndef COMMENT
  7473.       int yy;
  7474.       long zz;
  7475.       zz = -1L;
  7476.       yy = x_ifnum;
  7477.       x_ifnum = 1;            /* Turn off internal complaints */
  7478.       y = cmnum("Seconds from now, or time of day as hh:mm:ss",
  7479.         "0" ,10, &x, xxstring);
  7480.       x_ifnum = yy;
  7481.       if (y < 0) {
  7482.       if (y == -2) {        /* Invalid number or expression */
  7483.           zz = tod2sec(atmbuf);    /* Convert to secs since midnight */
  7484.           if (zz < 0L) {
  7485.           printf("?Number, expression, or time of day required\n");
  7486.           return(-9);
  7487.           } else {
  7488.           char now[32];        /* Current time */
  7489.           char *p;
  7490.           long tnow;
  7491.           p = now;
  7492.           ztime(&p);
  7493.           tnow = atol(p+11) * 3600L + atol(p+14) * 60L + atol(p+17);
  7494.           if (zz < tnow)    /* User's time before now */
  7495.             zz += 86400L;    /* So make it tomorrow */
  7496.           zz -= tnow;        /* Seconds from now. */
  7497.           }
  7498.       } else
  7499.         return(y);
  7500.       }
  7501.       if (x < 0) {
  7502.       printf("?Alarm time is in the past.\n");
  7503.       return(-9);
  7504.       }
  7505.       if ((y = cmcfm()) < 0) return(y);
  7506.       if (zz > -1L) {            /* Time of day given? */
  7507.       x = zz;
  7508.       if (zz != (long) x) {
  7509.           printf(
  7510. "Sorry, arithmetic overflow - hh:mm:ss not usable on this platform.\n"
  7511.              );
  7512.           return(-9);
  7513.       }
  7514.       }
  7515.       return(setalarm((long)x));
  7516.   }
  7517. #else
  7518. /*
  7519.   This is to allow long values where int and long are not the same, e.g.
  7520.   on 16-bit systems.  But something is wrong with it.
  7521. */
  7522.     if ((y = cmtxt("seconds from now", "0", &s, xxstring)) < 0)
  7523.       return(y);
  7524.     if (rdigits(s)) {
  7525.     return(setalarm(atol(s)));
  7526.     } else {
  7527.     printf("%s - not a number\n",s);
  7528.     return(-9);
  7529.     }
  7530. #endif /* COMMENT */
  7531. #endif /* NOSPL */
  7532.  
  7533. #ifndef NOXFER
  7534. case XYPROTO:
  7535.     return(setproto());
  7536. #endif /* NOXFER */
  7537.  
  7538. #ifdef CK_SPEED
  7539. case XYPREFIX: {
  7540. #ifdef COMMENT
  7541.     extern int clearrq;
  7542. #endif /* COMMENT */
  7543.     if ((z = cmkey(pfxtab, 4, "control-character prefixing option",
  7544.            "", xxstring)) < 0)
  7545.       return(z);
  7546.     if ((x = cmcfm()) < 0) return(x);
  7547.     setprefix(z);
  7548. #ifdef COMMENT
  7549.     if (hints && (z == PX_ALL || z == PX_CAU) && clearrq) {
  7550.     printf("Hint: use SET CLEAR-CHANNEL OFF to disable negotiation of\n");
  7551.     printf("      SET PREFIXING NONE during file transfers on reliable\n");
  7552.     printf("      connections.\n");
  7553.     }
  7554. #endif /* COMMENT */
  7555.     return(success = 1);
  7556.   }
  7557. #endif /* CK_SPEED */
  7558.  
  7559. #ifndef NOSPL
  7560. case XYLOGIN:
  7561.    if ((z = cmkey(logintab, 3, "value for login script","userid",
  7562.           xxstring)) < 0)
  7563.       return(z);
  7564.     x = cmdgquo();
  7565.     if (z == LOGI_PSW)
  7566.       cmdsquo(0);
  7567.     if ((y = cmtxt("text","", &s, NULL)) < 0) {
  7568.     cmdsquo(x);
  7569.     return(y);
  7570.     }
  7571.     cmdsquo(x);
  7572. #ifdef IKSD
  7573.     if (inserver)
  7574.         return(success = 0);
  7575. #endif /* IKSD */
  7576.     if ((int)strlen(s) > 63) {
  7577.     printf("Sorry, too long\n");
  7578.     return(-9);
  7579.     }
  7580.     s = brstrip(s);
  7581.     switch(z) {
  7582.       case LOGI_UID:
  7583.     ckstrncpy(uidbuf,s,UIDBUFLEN);
  7584.         sl_uid_saved = 0;
  7585.     break;
  7586.       case LOGI_PSW:
  7587.     ckstrncpy(pwbuf,s,PWBUFL);
  7588.         pwflg = 1;
  7589. #ifdef OS2
  7590.         pwcrypt = 1;
  7591. #else /* OS2 */
  7592.         pwcrypt = 0;
  7593. #endif /* OS2 */
  7594.     break;
  7595.       case LOGI_PRM:
  7596.     ckstrncpy(prmbuf,s,PWBUFL);
  7597.     }
  7598.     return(success = 1);
  7599. #endif /* NOSPL */
  7600. }
  7601.  
  7602. switch (xx) {
  7603.  
  7604.   case XYSTARTUP:
  7605.     if ((y = cmkey(ifdtab,2,"","discard",xxstring)) < 0) return(y);
  7606.     if ((x = cmcfm()) < 0) return(x);
  7607.     DeleteStartupFile = (y != 0) ? 0 : 1;
  7608.     return(success = 1);
  7609.  
  7610. case XYTMPDIR:
  7611.     x = cmdir("Name of temporary directory","",&s,xxstring);
  7612.     if (x == -3)
  7613.       s = "";
  7614.     else if (x < 0)
  7615.       return(x);
  7616.     if ((x = cmcfm()) < 0) return(x);
  7617.     makestr(&tempdir,s);
  7618.     return(tempdir ? 1 : 0);
  7619.  
  7620. #ifndef NOXFER
  7621. case XYDEST:                /* DESTINATION */
  7622.     return(setdest());
  7623. #endif /* NOXFER */
  7624.  
  7625. #ifndef NOPUSH
  7626. #ifndef NOFRILLS
  7627.  
  7628. /* Editor, Browser, and FTP Client */
  7629.  
  7630. case XYEDIT:                /* EDITOR */
  7631. #ifdef IKSD
  7632.     if (inserver) {
  7633.         printf("?Sorry, command disabled.\r\n");
  7634.         return(success = 0);
  7635.     }
  7636. #endif /* IKSD */
  7637. #ifdef CK_APC
  7638.     /* Don't let this be set remotely */
  7639.     if (apcactive == APC_LOCAL ||
  7640.         apcactive == APC_REMOTE && apcstatus != APC_UNCH)
  7641.       return(success = 0);
  7642. #endif /* CK_APC */
  7643.  
  7644. #ifdef OS2ORUNIX
  7645.     {
  7646.     char *p = getenv("PATH");
  7647.     char *e;
  7648.     e = editor[0] ? (char *) editor : getenv("EDITOR");
  7649.     if (!e) e = "";
  7650.     if (p)
  7651.       x = cmifip("Name of preferred editor",e,&s,&y,0,p,xxstring);
  7652.     else
  7653.       x = cmifi("Full path of preferred editor",e,&s,&y,xxstring);
  7654.     if (x < 0 && x != -3)
  7655.       return(x);
  7656.     }
  7657. #else
  7658. #ifdef VMS
  7659.     if ((y = cmtxt("DCL command for editing", "edit", &s, NULL)) < 0) {
  7660.     if (x != -3)
  7661.       return(x);
  7662.     }
  7663. #else
  7664.     if ((x = cmifi("Full path of preferred editor","",&s,&y,xxstring)) < 0) {
  7665.     if (x != -3)
  7666.       return(x);
  7667.     }
  7668. #endif /* VMS */
  7669. #endif /* OS2ORUNIX */
  7670. #ifdef VMS
  7671.     ckstrncpy(editor,s,CKMAXPATH);
  7672.     editopts[0] = NUL;
  7673. #else
  7674.     if (y != 0) {
  7675.     printf("?A single file please\n");
  7676.     return(-2);
  7677.     }
  7678.     strcpy(line,s);
  7679.     if ((x = cmtxt("editor command-line options","",&s,NULL)) < 0)
  7680.       return(x);
  7681.     ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  7682.     if ((z = cmcfm()) < 0) return(z);
  7683.     if (line[0]) {
  7684.     zfnqfp(line,CKMAXPATH,editor);
  7685.     ckstrncpy(editopts,tmpbuf,128);
  7686.     } else {
  7687.         editor[0] = NUL;
  7688.         editopts[0] = NUL;
  7689.     }
  7690. #endif /* VMS */
  7691.     return(success = 1);
  7692.  
  7693. #ifdef BROWSER
  7694. case XYFTP:                /* SET FTP-CLIENT */
  7695. case XYBROWSE:                /* SET BROWSER */
  7696.     {
  7697.     char *p = getenv("PATH");
  7698.     char *app = (char *) browser, *opts = (char *) browsopts;
  7699.     extern char ftpapp[], ftpopts[];
  7700.     if (xx == XYFTP) {
  7701.         app = (char *)ftpapp;
  7702.         opts = (char *)ftpopts;
  7703.     }
  7704. #ifdef IKSD
  7705.         if (inserver) {
  7706.             printf("?Sorry, command disabled.\r\n");
  7707.             return(success = 0);
  7708.         }
  7709. #endif /* IKSD */
  7710. #ifdef CK_APC
  7711.     /* Don't let this be set remotely */
  7712.     if (apcactive == APC_LOCAL ||
  7713.         apcactive == APC_REMOTE && apcstatus != APC_UNCH)
  7714.       return(success = 0);
  7715. #endif /* CK_APC */
  7716. #ifdef OS2ORUNIX
  7717.     if (p)
  7718.       x = cmifip(xx == XYBROWSE ?
  7719.              "Name of preferred browser" :
  7720.              "Name of preferred ftp client",
  7721. #ifdef OS2
  7722.              xx == XYFTP ? "ftp.exe" : ""
  7723. #else
  7724.              xx == XYFTP ? "ftp" : ""
  7725. #endif /* OS2 */
  7726.              ,&s,&y,0,p,xxstring
  7727.              );
  7728.     else
  7729.       x = cmifi(xx == XYBROWSE ?
  7730.             "Full path of preferred browser" :
  7731.             "Full path of preferred ftp client",
  7732.             "",&s,&y,xxstring
  7733.             );
  7734.     if (x < 0 && x != -3)
  7735.       return(x);
  7736. #else
  7737. #ifdef VMS
  7738.     if ((x = cmtxt("DCL command to start your preferred Web browser",
  7739.                "", &s, NULL)) < 0) {
  7740.         if (x != -3)
  7741.           return(x);
  7742.     }
  7743. #else
  7744.     if ((x = cmifi("Full path of preferred browser","",&s,&y,xxstring)
  7745.          ) < 0) {
  7746.         if (x != -3)
  7747.           return(x);
  7748.     }
  7749. #endif /* VMS */
  7750. #endif /* OS2ORUNIX */
  7751. #ifdef VMS
  7752.     ckstrncpy(app,s,CKMAXPATH);
  7753.     *opts = NUL;
  7754. #else
  7755.     if (y != 0) {
  7756.         printf("?A single file please\n");
  7757.         return(-2);
  7758.     }
  7759.     strcpy(line,s);
  7760.     if ((x = cmtxt(xx == XYBROWSE ?
  7761.                "browser command-line options" :
  7762.                "ftp client command-line options",
  7763.                "",&s,NULL)
  7764.          ) < 0)
  7765.       return(x);
  7766.     ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  7767.     if ((z = cmcfm()) < 0) return(z);
  7768.     if (line[0]) {
  7769.         zfnqfp(line,CKMAXPATH,app);
  7770.         ckstrncpy(opts, tmpbuf, 128);
  7771.     } else {
  7772.         *app = NUL;
  7773.         *opts = NUL;
  7774.     }
  7775. #endif /* VMS */
  7776.     return(success = 1);
  7777.     }
  7778. #endif /* BROWSER */
  7779. #endif /* NOFRILLS */
  7780. #endif /* NOPUSH */
  7781.  
  7782. #ifdef CK_CTRLZ
  7783.   case XYEOF: {                /* SET EOF */
  7784.       extern int eofmethod; extern struct keytab eoftab[];
  7785.       if ((x = cmkey(eoftab,3,"end-of-file detection method","",
  7786.              xxstring)) < 0)
  7787.     return(x);
  7788.       if ((y = cmcfm()) < 0)
  7789.     return(y);
  7790.       eofmethod = x;
  7791.       return(success = 1);
  7792.   }
  7793. #endif /* CK_CTRLZ */
  7794.  
  7795. #ifdef SESLIMIT
  7796.   case XYLIMIT: {            /* Session-Limit (length of session in seconds) */
  7797.       extern int seslimit;
  7798.       y = cmnum("Maximum length of session, seconds","0",10,&x,xxstring);
  7799. #ifdef IKSD
  7800.       if (inserver &&
  7801. #ifdef IKSDCONF
  7802.       iksdcf
  7803. #else
  7804.       1
  7805. #endif /* IKSDCONF */
  7806.       ) {
  7807.           if ((z = cmcfm()) < 0)
  7808.         return(z);
  7809.           printf("?Sorry, command disabled.\r\n");
  7810.           return(success = 0);
  7811.       }
  7812. #endif /* IKSD */
  7813.  
  7814.       return(setnum(&seslimit,x,y,86400));
  7815.   }
  7816. #endif /* SESLIMIT */
  7817.  
  7818.   case XYRELY: {            /* SET RELIABLE */
  7819.       extern int reliable, setreliable;
  7820.       if ((x = cmkey(ooatab,3,"","automatic",xxstring)) < 0)
  7821.     return(x);
  7822.       if ((y = cmcfm()) < 0) return(y);
  7823.       reliable = x;
  7824.       setreliable = (x != SET_AUTO);
  7825.       debug(F101,"set reliable","",reliable);
  7826.       return(success = 1);
  7827.   }
  7828.  
  7829. #ifdef STREAMING
  7830.   case XYSTREAM: {            /* SET STREAMING */
  7831.       extern int streamrq;
  7832.       if ((x = cmkey(ooatab,3,"","automatic",xxstring)) < 0)
  7833.     return(x);
  7834.       if ((y = cmcfm()) < 0) return(y);
  7835.       streamrq = x;
  7836.       return(success = 1);
  7837.   }
  7838. #endif /* STREAMING */
  7839.  
  7840. #ifdef CKSYSLOG
  7841.  case XYSYSL: {
  7842.      if ((x = cmkey(syslogtab,nsyslog,"","",xxstring)) < 0)
  7843.        return(x);
  7844.      if ((y = cmcfm()) < 0) return(y);
  7845. #ifdef IKSD
  7846.      if (inserver &&
  7847. #ifdef IKSDCONF
  7848.      iksdcf
  7849. #else
  7850.      1
  7851. #endif /* IKSDCONF */
  7852.           ) {
  7853.      printf("?Sorry, command disabled.\n");
  7854.      return(success = 0);
  7855.      }
  7856. #endif /* IKSD */
  7857. #ifdef CK_APC
  7858.      /* Don't let this be set remotely */
  7859.      if (apcactive == APC_LOCAL ||
  7860.          apcactive == APC_REMOTE && apcstatus != APC_UNCH)
  7861.        return(success = 0);
  7862. #endif /* CK_APC */
  7863.      ckxsyslog = x;
  7864.      return(success = 1);
  7865. }
  7866. #endif /* CKSYSLOG */
  7867.  
  7868. #ifdef TLOG
  7869.   case XYTLOG: {            /* SET TRANSACTION-LOG */
  7870.       extern int tlogsep;
  7871.       if ((x = cmkey(vbtab,nvb,"","verbose",xxstring)) < 0)
  7872.     return(x);
  7873.       if (x == 0) {
  7874.       if ((y = cmtxt("field separator",",",&s,NULL)) < 0) return(y);
  7875.       s = brstrip(s);
  7876.       if (*s) {
  7877.           if (s[1]) {
  7878.           printf("?A single character, please.\n");
  7879.           return(-9);
  7880.           } else if ((*s >= '0' && *s <= '9') ||
  7881.           (*s >= 'A' && *s <= 'Z') ||
  7882.           (*s >= 'a' && *s <= 'z')) {
  7883.           printf("?A non-alphanumeric character, please.\n");
  7884.           return(-9);
  7885.           } else
  7886.         tlogsep = *s;
  7887.       }
  7888.       } else {
  7889.       if ((y = cmcfm()) < 0) return(y);
  7890.       }
  7891. #ifdef IKSD
  7892.      if (inserver && isguest) {
  7893.      printf("?Sorry, command disabled.\n");
  7894.      return(success = 0);
  7895.      }
  7896. #endif /* IKSD */
  7897. #ifdef CK_APC
  7898.      /* Don't let this be set remotely */
  7899.      if (apcactive == APC_LOCAL ||
  7900.          apcactive == APC_REMOTE && apcstatus != APC_UNCH)
  7901.        return(success = 0);
  7902. #endif /* CK_APC */
  7903.       tlogfmt = x;
  7904.       return(success = 1);
  7905.   }
  7906. #endif /* TLOG */
  7907.  
  7908.   case XYCLEAR: {            /* SET CLEARCHANNEL */
  7909.       extern int clearrq;
  7910.       if ((x = cmkey(ooatab,3,"","automatic",xxstring)) < 0)
  7911.     return(x);
  7912.       if ((y = cmcfm()) < 0) return(y);
  7913.       clearrq = x;
  7914.       return(success = 1);
  7915.   }
  7916.  
  7917. #ifdef CK_AUTHENTICATION
  7918.   case XYAUTH: {            /* SET AUTHENTICATION */
  7919. #ifdef CK_KERBEROS
  7920.       int kv = 0;
  7921.       extern struct krb_op_data krb_op;
  7922. #endif /* CK_KERBEROS */
  7923.       char * p = NULL;
  7924.       if ((x = cmkey(setauth,nsetauth,"authentication type","",xxstring)) < 0)
  7925.     return(x);
  7926.       switch (x) {
  7927. #ifdef CK_KERBEROS
  7928.     case AUTH_KRB4: kv = 4; break;    /* Don't assume values are the same */
  7929.     case AUTH_KRB5: kv = 5; break;
  7930. #endif /* CK_KERBEROS */
  7931. #ifdef CK_SRP
  7932.       case AUTH_SRP: break;
  7933. #endif /* CK_SRP */
  7934. #ifdef CK_SSL
  7935.     case AUTH_SSL:
  7936.     case AUTH_TLS:
  7937.       break;
  7938. #endif /* CK_SSL */
  7939.     default:
  7940.       printf("?Authorization type not supported yet - \"%s\"\n",atmbuf);
  7941.       return(-9);
  7942.       }
  7943. #ifdef IKSD
  7944.       if (inserver &&
  7945. #ifdef IKSDCONF
  7946.       iksdcf
  7947. #else
  7948.       1
  7949. #endif /* IKSDCONF */
  7950.           ) {
  7951.       if ((y = cmcfm()) < 0) return(y);
  7952.       printf("?Sorry, command disabled.\n");
  7953.       return(success = 0);
  7954.       }
  7955. #endif /* IKSD */
  7956. #ifdef CK_APC
  7957.       /* Don't let this be set remotely */
  7958.       if (apcactive == APC_LOCAL ||
  7959.           apcactive == APC_REMOTE && apcstatus != APC_UNCH) {
  7960.       if ((y = cmcfm()) < 0) return(y);
  7961.       return(success = 0);
  7962.       }
  7963. #endif /* CK_APC */
  7964.  
  7965.       switch(x) {
  7966. #ifdef CK_KERBEROS
  7967.     case AUTH_KRB4:
  7968.     case AUTH_KRB5: {
  7969.         if ((x = cmkey(kv == 4 ? k4tab : k5tab,
  7970.                kv == 4 ? nk4tab : nk5tab,
  7971.                "Kerberos parameter","",xxstring)) < 0) {
  7972.         return(x);
  7973.         }
  7974.         s = "";
  7975.         switch (x) {
  7976. #ifdef KRB4
  7977.           case XYKRBDBG:
  7978.         if (kv == 4) {
  7979.             if ((y = seton(&k4debug)) < 0)
  7980.               return(y);
  7981. #ifdef NT
  7982.             ck_krb4_debug(k4debug);
  7983. #endif /* NT */
  7984.         } else {
  7985.             return(-9);
  7986.         }
  7987.         break;
  7988. #endif /* KRB4 */
  7989.           case XYKRBLIF:
  7990.         if ((y = cmnum("TGT lifetime","600",10,&z,xxstring)) < 0)
  7991.           return(y);
  7992.         break;
  7993.           case XYKRBPRE:
  7994.         if (kv == 4) {
  7995.             if ((y = seton(&krb4_d_preauth)) < 0)
  7996.               return(y);
  7997.         } else {
  7998.             return(-9);
  7999.         }
  8000.         break;
  8001.           case XYKRBINS:
  8002.         if ((y = cmtxt("Instance name","",&s,xxstring)) < 0)
  8003.           return(y);
  8004.         break;
  8005.           case XYKRBFWD:
  8006.         if (kv == 5) {
  8007.             if ((y = seton(&krb5_d_forwardable)) < 0)
  8008.               return(y);
  8009.         } else {
  8010.             return(-9);
  8011.         }
  8012.         break;
  8013.           case XYKRBPRX:
  8014.         if (kv == 5) {
  8015.             if ((y = seton(&krb5_d_proxiable)) < 0)
  8016.               return(y);
  8017.         } else {
  8018.             return(-9);
  8019.         }
  8020.         break;
  8021.           case XYKRBRNW:
  8022.         if ((y = cmnum("TGT renewable lifetime",
  8023.                    "0",10,&z,xxstring)) < 0)
  8024.           return(y);
  8025.         break;
  8026.           case XYKRBADR:
  8027.         if (kv == 5) {
  8028.             if ((y = seton(&krb5_checkaddrs)) < 0)
  8029.               return(y);
  8030.         } else {
  8031.             if ((y = seton(&krb4_checkaddrs)) < 0)
  8032.               return(y);
  8033.         }
  8034.         break;
  8035.           case XYKRBGET:
  8036.         if (kv == 5) {
  8037.             if ((y = seton(&krb5_autoget)) < 0)
  8038.               return(y);
  8039.         } else {
  8040.             if ((y = seton(&krb4_autoget)) < 0)
  8041.               return(y);
  8042.         }
  8043.         break;
  8044.           case XYKRBDEL:
  8045.         if ((z = cmkey(kdestab,nkdestab,
  8046.                    "Auto Destroy Tickets","never",xxstring)) < 0)
  8047.                   return(z);
  8048.         break;
  8049.           case XYKRBPR:
  8050.         if ((y = cmtxt("User ID",uidbuf,&s,xxstring)) < 0)
  8051.           return(y);
  8052.         break;
  8053.           case XYKRBRL:
  8054.         if ((y = cmtxt("Name of realm","",&s,xxstring)) < 0)
  8055.           return(y);
  8056.         break;
  8057.           case XYKRBCC:
  8058.         if ((y = cmofi("Filename","",&s,xxstring)) < 0)
  8059.           return(y);
  8060.         break;
  8061.           case XYKRBSRV:
  8062.         if ((y = cmtxt("Name of service to use in ticket",
  8063.                    (kv == 4 ? "rcmd" : "host"),
  8064.                    &s,
  8065.                    xxstring
  8066.                    )) < 0)
  8067.           return(y);
  8068.         break;
  8069.           case XYKRBK5K4:
  8070.         if (kv == 5) {
  8071.             if ((y = seton(&krb5_d_getk4)) < 0)
  8072.               return(y);
  8073.         } else {
  8074.             return(-9);
  8075.         }
  8076.         break;
  8077.           case XYKRBPRM:        /* Prompt */
  8078.         if ((z = cmkey(krbprmtab,2,"","",xxstring)) < 0)
  8079.           return(z);
  8080.         if ((y = cmtxt((z == KRB_PW_PRM) ?
  8081.   "Text of prompt;\nmay contain \"%s\" to be replaced by principal name" :
  8082.   "Text of prompt",
  8083.                    "",
  8084.                    &s,
  8085.                    xxstring
  8086.                    )
  8087.              ) < 0)
  8088.           return(y);
  8089.         break;
  8090.         }
  8091.         strcpy(line,s);
  8092.         s = line;
  8093.         if ((y = cmcfm()) < 0)
  8094.           return(y);
  8095. #ifdef IKSD
  8096.             if (inserver &&
  8097. #ifdef IKSDCONF
  8098.         iksdcf
  8099. #else /* IKSDCONF */
  8100.         1
  8101. #endif /* IKSDCONF */
  8102.         )
  8103.           return(success = 0);
  8104. #endif /* IKSD */
  8105.  
  8106.         switch (x) {        /* Copy value to right place */
  8107.           case XYKRBLIF:        /* Lifetime */
  8108.         if (kv == 4)
  8109.           krb4_d_lifetime = z;
  8110.         else
  8111.           krb5_d_lifetime = z;
  8112.         break;
  8113.           case XYKRBRNW:
  8114.         if (kv == 5)
  8115.           krb5_d_renewable = z;
  8116.         break;
  8117.           case XYKRBPR:        /* Principal */
  8118.         s = brstrip(s);            /* Strip braces around. */
  8119.         if (kv == 4)
  8120.           makestr(&krb4_d_principal,s);
  8121.         else
  8122.           makestr(&krb5_d_principal,s);
  8123.         break;
  8124.           case XYKRBINS:        /* Instance */
  8125.         if (kv == 4)
  8126.           makestr(&krb4_d_instance,s);
  8127.                 else
  8128.                   makestr(&krb5_d_instance,s);
  8129.         break;
  8130.           case XYKRBRL:        /* Realm */
  8131.         if (kv == 4)
  8132.           makestr(&krb4_d_realm,s);
  8133.         else
  8134.           makestr(&krb5_d_realm,s);
  8135.         break;
  8136.           case XYKRBCC:        /* Credentials cache */
  8137.         makestr(&krb5_d_cc,s);
  8138.         break;
  8139.           case XYKRBSRV:        /* Service Name */
  8140.         if (kv == 4)
  8141.           makestr(&krb4_d_srv,s);
  8142.         else
  8143.           makestr(&krb5_d_srv,s);
  8144.         break;
  8145.           case XYKRBDEL:
  8146.         if (kv == 5)
  8147.           krb5_autodel = z;
  8148.         else
  8149.           krb4_autodel = z;
  8150.         break;
  8151.           case XYKRBPRM:        /* Prompt */
  8152.         if (s == "") s = NULL;
  8153.         if (s) {
  8154.             s = brstrip(s);
  8155.             if (s == "") s = NULL;
  8156.         }
  8157.         switch (z) {
  8158.           case KRB_PW_PRM: {    /* Password */
  8159.               /* Check that there are no more than */
  8160.               /* two % fields and % must followed by 's'. */
  8161.               int i,n,len;
  8162.               len = strlen(s);
  8163.               for (i = 0, n = 0; i < len; i++) {
  8164.               if (s[i] == '%') {
  8165.                   if (s[i+1] != '%') {
  8166.                   if (s[i+1] != 's') {
  8167.                       printf(
  8168.                        "Only %%s fields are permitted.\n");
  8169.                       return(-9);
  8170.                   }
  8171.                   if (++n > 2) {
  8172.                       printf(
  8173.                        "Only two %%s fields are permitted.\n");
  8174.                       return(-9);
  8175.                   }
  8176.                   }
  8177.                   i++;
  8178.               }
  8179.               }
  8180.               if (kv == 5)
  8181.             makestr(&k5pwprompt,s);
  8182.               else
  8183.             makestr(&k4pwprompt,s);
  8184.               break;
  8185.           }
  8186.           case KRB_PR_PRM: {    /* Principal */
  8187.               /* Check to make sure there are no % fields */
  8188.               int i,len;
  8189.               len = strlen(s);
  8190.               for (i = 0; i < len; i++) {
  8191.               if (s[i] == '%') {
  8192.                   if (s[i+1] != '%') {
  8193.                   printf(
  8194.                   "%% fields are not used in this command.\n");
  8195.                   return(-9);
  8196.                   }
  8197.                   i++;
  8198.               }
  8199.               }
  8200.               if (kv == 5)
  8201.             makestr(&k5prprompt,s);
  8202.               else
  8203.             makestr(&k4prprompt,s);
  8204.               break;
  8205.           }
  8206.         }
  8207.         }
  8208.         break;
  8209.     }
  8210. #endif /* CK_KERBEROS */
  8211. #ifdef CK_SRP
  8212.     case AUTH_SRP: {
  8213.         if ((x = cmkey(srptab, nsrptab,
  8214.                "SRP parameter","",xxstring)) < 0) {
  8215.         return(x);
  8216.         }
  8217.         s = "";
  8218.         switch (x) {
  8219.           case XYSRPPRM:        /* Prompt */
  8220.         if ((z = cmkey(srpprmtab,1,"","",xxstring)) < 0)
  8221.           return(z);
  8222.         if ((y = cmtxt(
  8223.   "Text of prompt;\nmay contain one \"%s\" to be replaced by the username",
  8224.                    "",
  8225.                    &s,
  8226.                    xxstring
  8227.                    )
  8228.              ) < 0)
  8229.           return(y);
  8230.         break;
  8231.         }
  8232.         strcpy(line,s);
  8233.         s = line;
  8234.         if ((y = cmcfm()) < 0)
  8235.           return(y);
  8236.         switch (x) {        /* Copy value to right place */
  8237.           case XYSRPPRM:        /* Prompt */
  8238.         if (s == "") s = NULL;
  8239.         if (s) {
  8240.             s = brstrip(s);
  8241.             if (s == "") s = NULL;
  8242.         }
  8243.         switch (z) {
  8244.           case SRP_PW_PRM: {    /* Password */
  8245.               /* Check %s fields */
  8246.               int i,n,len;
  8247.               len = strlen(s);
  8248.               for (i = 0, n = 0; i < len; i++) {
  8249.               if (s[i] == '%') {
  8250.                   if (s[i+1] != '%') {
  8251.                   if (s[i+1] != 's') {
  8252.                       printf(
  8253.                        "Only %%s fields are permitted.\n");
  8254.                       return(-9);
  8255.                   }
  8256.                   if (++n > 1) {
  8257.                       printf(
  8258.                        "Only one %%s field is permitted.\n");
  8259.                       return(-9);
  8260.                   }
  8261.                   }
  8262.                   i++;
  8263.               }
  8264.               }
  8265.               makestr(&srppwprompt,s);
  8266.               break;
  8267.           }
  8268.         }
  8269.         }
  8270.         break;
  8271.     }
  8272. #endif /* CK_SRP */
  8273. #ifdef CK_SSL
  8274.     case AUTH_SSL:
  8275.     case AUTH_TLS: {
  8276.         if ((z = cmkey(ssltab, nssltab,
  8277.                (x == AUTH_SSL ? "SSL parameter" : "TLS parameter"),
  8278.                "",xxstring)) < 0)
  8279.           return(z);
  8280.         s = "";
  8281.         switch (z) {
  8282.           case XYSSLRCFL:        /* SSL/TLS RSA Certs file */
  8283.           case XYSSLRKFL:        /* SSL/TLS RSA Key File */
  8284.           case XYSSLDCFL:        /* SSL/TLS DSA Certs file */
  8285.               case XYSSLDKFL:        /* SSL/TLS DH Key File */
  8286.               case XYSSLDPFL:           /* SSL/TLS DH Param File */
  8287.               case XYSSLCRL:            /* SSL/TLS CRL File */
  8288.               case XYSSLVRFF:           /* SSL/TLS Verify File */
  8289.         if ((y = cmifi("Filename","",&s,&x,xxstring)) < 0)
  8290.           return(y);
  8291.         if (x) {
  8292.             printf("?Wildcards not allowed\n");
  8293.             return(-9);
  8294.         }
  8295.         strcpy(line,s);
  8296.         s = line;
  8297.         if ((y = cmcfm()) < 0)
  8298.           return(y);
  8299.         switch (z) {
  8300.           case XYSSLRCFL:    /* SSL/TLS RSA Certs file */
  8301.             if (!s[0] && ssl_rsa_cert_file) {
  8302.             free(ssl_rsa_cert_file);
  8303.             ssl_rsa_cert_file = NULL;
  8304.             } else {
  8305.             makestr(&ssl_rsa_cert_file,s);
  8306.             if (!ssl_rsa_key_file)
  8307.               makestr(&ssl_rsa_key_file,s);
  8308.             }
  8309.             break;
  8310.           case XYSSLRKFL:    /* SSL/TLS RSA Key File */
  8311.             if (!s[0] && ssl_rsa_key_file) {
  8312.             free(ssl_rsa_key_file);
  8313.             ssl_rsa_key_file = NULL;
  8314.             } else {
  8315.             makestr(&ssl_rsa_key_file,s);
  8316.             }
  8317.             break;
  8318.           case XYSSLDCFL:    /* SSL/TLS DSA Certs file */
  8319.                     if (!s[0] && ssl_dsa_cert_file) {
  8320.                         free(ssl_dsa_cert_file);
  8321.                         ssl_dsa_cert_file = NULL;
  8322.                     } else {
  8323.                         makestr(&ssl_dsa_cert_file,s);
  8324.                         if (!ssl_dh_key_file)
  8325.               makestr(&ssl_dh_key_file,s);
  8326.                     }
  8327.                     break;
  8328.           case XYSSLDKFL:    /* SSL/TLS DH Key File */
  8329.                     if (!s[0] && ssl_dh_key_file) {
  8330.                         free(ssl_dh_key_file);
  8331.                         ssl_dh_key_file = NULL;
  8332.                     } else {
  8333.                         makestr(&ssl_dh_key_file,s);
  8334.                     }
  8335.                     break;
  8336.                   case XYSSLDPFL:    /* SSL/TLS DH Param File */
  8337.             if (!s[0] && ssl_dh_param_file) {
  8338.               free(ssl_dh_param_file);
  8339.               ssl_dh_param_file = NULL;
  8340.             } else {
  8341.               makestr(&ssl_dh_param_file,s);
  8342.             }
  8343.             break;
  8344.                   case XYSSLCRL:    /* SSL/TLS CRL File */
  8345.                       if (!s[0] && ssl_crl_file) {
  8346.                           free(ssl_crl_file);
  8347.                           ssl_crl_file = NULL;
  8348.                       } else {
  8349.                           makestr(&ssl_crl_file,s);
  8350.                       }
  8351.                       break;
  8352.                   case XYSSLVRFF:    /* SSL/TLS Verify File */
  8353.                       if (!s[0] && ssl_crl_file) {
  8354.                           free(ssl_verify_file);
  8355.                           ssl_verify_file = NULL;
  8356.                       } else {
  8357.                           makestr(&ssl_verify_file,s);
  8358.                       }
  8359.                       break;
  8360.         }
  8361.         break;
  8362.  
  8363.               case XYSSLCRLD:
  8364.               case XYSSLVRFD:
  8365.         if ((y = cmdir("Directory","",&s,xxstring)) < 0)
  8366.           return(y);
  8367.         strcpy(line,s);
  8368.         s = line;
  8369.         if ((y = cmcfm()) < 0)
  8370.           return(y);
  8371.                 switch(z) {
  8372.           case XYSSLCRLD:
  8373.             if (!s[0] && ssl_crl_dir) {
  8374.             free(ssl_crl_dir);
  8375.             ssl_crl_dir = NULL;
  8376.             } else {
  8377.             makestr(&ssl_crl_dir,s);
  8378.             }
  8379.             break;
  8380.           case XYSSLVRFD:
  8381.             if (!s[0] && ssl_verify_dir) {
  8382.             free(ssl_verify_dir);
  8383.             ssl_verify_dir = NULL;
  8384.             } else {
  8385.             makestr(&ssl_verify_dir,s);
  8386.             }
  8387.             break;
  8388.                 }
  8389.         break;
  8390.           case XYSSLCOK:        /* SSL/TLS Certs-Ok flag */
  8391.         if ((y = seton(&ssl_certsok_flag)) < 0)
  8392.           return(y);
  8393.         break;
  8394.           case XYSSLDBG:        /* SSL/TLS Debug flag */
  8395.         if ((y = seton(&ssl_debug_flag)) < 0)
  8396.           return(y);
  8397.         break;
  8398.           case XYSSLON:        /* SSL/TLS Only flag */
  8399.         switch (x) {
  8400.           case AUTH_SSL:
  8401.             if ((y = seton(&ssl_only_flag)) < 0)
  8402.               return(y);
  8403.             break;
  8404.           case AUTH_TLS:
  8405.             if ((y = seton(&tls_only_flag)) < 0)
  8406.               return(y);
  8407.             break;
  8408.         }
  8409.         break;
  8410.           case XYSSLVRB:        /* SSL/TLS Verbose flag */
  8411.         if ((y = seton(&ssl_verbose_flag)) < 0)
  8412.           return(y);
  8413.         break;
  8414.           case XYSSLVRF:        /* SSL/TLS Verify flag */
  8415.         if ((x = cmkey(sslvertab, nsslvertab,
  8416.                    "SSL/TLS verify mode",
  8417.                    "peer-cert",xxstring)) < 0)
  8418.           return(x);
  8419.         if ((y = cmcfm()) < 0)
  8420.           return(y);
  8421.         ssl_verify_flag = x;
  8422.         break;
  8423.           case XYSSLDUM:
  8424.         if ((y = seton(&ssl_dummy_flag)) < 0)
  8425.           return(y);
  8426.         break;
  8427.           case XYSSLCL: {        /* SSL/TLS Cipher List */
  8428. #ifdef COMMENT
  8429.           /* This code is used to generate a colon delimited */
  8430.           /* list of the ciphers currently in use to be used */
  8431.           /* as the default for cmtxt().  However, a better  */
  8432.           /* default is simply the magic keyword "ALL".      */
  8433.           CHAR def[1024] = "";
  8434.           if (ssl_con != NULL) {
  8435.               CHAR * p = NULL, *q = def;
  8436.               int i, len;
  8437.  
  8438.               for (i = 0; ; i++) {
  8439.               p = (CHAR *) SSL_get_cipher_list(ssl_con,i);
  8440.               if (p == NULL)
  8441.                 break;
  8442.               len = strlen(p);
  8443.               if (q+len+1 >= def+1024)
  8444.                 break;
  8445.               if (i != 0)
  8446.                 *q++ = ':';
  8447.               strcpy(q,p);
  8448.               q += len;
  8449.               }
  8450.           }
  8451. #endif /* COMMENT */
  8452.                   char * p = getenv("SSL_CIPHER");
  8453.                   if (!p)
  8454.             p = "ALL";
  8455.           if ((y = cmtxt(
  8456.                     "Colon-delimited list of ciphers or ALL (case sensitive)",
  8457.                  p,
  8458.                  &s,
  8459.                  xxstring
  8460.                  )
  8461.                ) < 0)
  8462.             return(y);
  8463.           makestr(&ssl_cipher_list,s);
  8464.           if (ssl_con == NULL) {
  8465.               SSL_library_init();
  8466.               ssl_ctx = (SSL_CTX *)
  8467.             SSL_CTX_new((SSL_METHOD *)TLSv1_method());
  8468.               if (ssl_ctx != NULL)
  8469.             ssl_con= (SSL *) SSL_new(ssl_ctx);
  8470.           }
  8471.           if (ssl_con) {
  8472.               SSL_set_cipher_list(ssl_con,ssl_cipher_list);
  8473.           }
  8474.           break;
  8475.           }
  8476.         }
  8477.         break;
  8478.     }
  8479. #endif /* CK_SSL */
  8480.     default:
  8481.           break;
  8482.       }
  8483.       return(success = 1);
  8484.   }
  8485. #endif /* CK_AUTHENTICATION */
  8486.  
  8487. #ifndef NOSPL
  8488. case XYFUNC:
  8489.      if ((x = cmkey(functab,nfunctab,"","diagnostics",xxstring)) < 0)
  8490.        return(x);
  8491.      switch (x) {
  8492.        case FUNC_DI: return(seton(&fndiags));
  8493.        case FUNC_ER: return(seton(&fnerror));
  8494.        default:      return(-2);
  8495.      }
  8496. #endif /* NOSPL */
  8497.  
  8498. case XYSLEEP:                /* SET SLEEP / PAUSE */
  8499.     if ((x = cmkey(sleeptab,1,"","cancellation",xxstring)) < 0)
  8500.       return(x);
  8501.     return(seton(&sleepcan));
  8502.  
  8503. case XYCD:                /* SET CD */
  8504.     if ((x = cmkey(cdtab,ncdtab,"","",xxstring)) < 0)
  8505.       return(x);
  8506.     switch (x) {
  8507.       case XYCD_M:            /* SET CD MESSAGE */
  8508.     if ((x = cmkey(cdmsg,ncdmsg,"","",xxstring)) < 0)
  8509.       return(x);
  8510.     if (x == 2) {            /* CD MESSAGE FILE */
  8511.         if ((x = cmtxt("Name of file","",&s,NULL)) < 0)
  8512.           return(x);
  8513.         if (!*s) {
  8514.         s = NULL;
  8515. #ifndef NOXFER
  8516.         srvcdmsg = 0;
  8517. #endif /* NOXFER */
  8518.         }
  8519.         makestr(&cdmsgstr,s);
  8520.         makelist(cdmsgstr,cdmsgfile,8);
  8521.         return(success = 1);
  8522.     }
  8523.  
  8524.     if ((y = cmcfm()) < 0) return(y); /* CD-MESSAGE ON/OFF */
  8525. #ifndef NOXFER
  8526.     if (x > 0)
  8527.       srvcdmsg |= 2;
  8528.     else
  8529.       srvcdmsg &= 1;
  8530. #endif /* NOXFER */
  8531.     return(success = 1);
  8532.  
  8533.       case XYCD_P: {            /* SET CD PATH */
  8534.       extern char * ckcdpath;
  8535.       if ((x = cmtxt("CD PATH string","",&s,xxstring)) < 0)
  8536.         return(x);
  8537.       makestr(&ckcdpath,s);
  8538.       return(success = 1);
  8539.       }
  8540.     }
  8541.  
  8542. #ifndef NOLOCAL
  8543. #ifdef HWPARITY
  8544.     case XYSTOP:            /* STOP-BITS */
  8545.         if ((x = cmkey(stoptbl,2,"Stop bits for serial device","",
  8546.                xxstring)) < 0)
  8547.       return(x);
  8548.     if ((y = cmcfm()) < 0)
  8549.       return(y);
  8550.     if (x > 0 && x < 3) {
  8551.         stopbits = x;
  8552.         return(success = 1);
  8553.     } else
  8554.       return(-2);
  8555. #endif /* HWPARITY */
  8556.  
  8557.       case XYDISC: {
  8558.       extern int clsondisc;
  8559.       return(seton(&clsondisc));
  8560.       }
  8561.  
  8562.       case XYSERIAL: {
  8563.       /* char c; */
  8564.       extern int cmask;
  8565.       if ((x = cmkey(sertbl,nsertbl,
  8566.              "Serial device character size, parity, and stop bits",
  8567.              "8N1", xxstring)) < 0)
  8568.         return(x);
  8569.       strcpy(line,atmbuf);        /* Copy associated keyword string */
  8570.       s = line;
  8571.       if ((y = cmcfm()) < 0)
  8572.         return(y);
  8573.       strcpy(line,sernam[x]);
  8574.       s = line;
  8575.       if (s[0] != '8' && s[0] != '7') /* Char size */
  8576.         return(-2);
  8577.       else
  8578.         z = s[0] - '0';
  8579.       if (isupper(s[1]))        /* Parity */
  8580.         s[1] = tolower(s[1]);
  8581.       if (s[2] != '1' && s[2] != '2') /* Stop bits */
  8582.         return(-2);
  8583.       else
  8584.         stopbits = s[2] - '0';
  8585.       if (z == 8) {            /* 8 bits + parity (or not) */
  8586.           parity = 0;        /* Set parity */
  8587.           hwparity = (s[1] == 'n') ? 0 : s[1];
  8588.           cmask = 0xff;        /* Also set TERM BYTESIZE to 8 */
  8589.       } else {            /* 7 bits plus parity */
  8590.           parity = (s[1] == 'n') ? 0 : s[1];
  8591.           hwparity = 0;
  8592.           cmask = 0x7f;        /* Also set TERM BYTESIZE to 7 */
  8593.       }
  8594.       return(success = 1);
  8595.       }
  8596.  
  8597.       case XYOPTS: {            /* SET OPTIONS */
  8598.       extern int setdiropts();
  8599.       extern int settypopts();
  8600. #ifdef CKPURGE
  8601.       extern int setpurgopts();
  8602. #endif /* CKPURGE */
  8603.       if ((x = cmkey(optstab,noptstab,"for command","", xxstring)) < 0)
  8604.         return(x);
  8605.       switch (x) {
  8606. #ifndef NOFRILLS
  8607.         case XXDEL:
  8608.           return(setdelopts());
  8609. #endif /* NOFRILLS */
  8610.         case XXDIR:
  8611.           return(setdiropts());
  8612.         case XXTYP:
  8613.           return(settypopts());
  8614. #ifdef CKPURGE
  8615.         case XXPURGE:
  8616.           return(setpurgopts());
  8617. #endif /* CKPURGE */
  8618.         default:
  8619.           return(-2);
  8620.       }
  8621.       }
  8622. #endif /* NOLOCAL */
  8623. #ifndef NOXFER
  8624.       case XYQ8FLG: {
  8625.       extern int q8flag;
  8626.       return(seton(&q8flag));
  8627.       }
  8628.       case XYTIMER: {
  8629.       extern int asktimer;
  8630.       y = cmnum("Time limit for ASK command, seconds","0",10,&x,xxstring);
  8631. #ifdef QNX16
  8632.       return(setnum(&asktimer,x,y,32767));
  8633. #else
  8634.       return(setnum(&asktimer,x,y,86400));
  8635. #endif /* QNX16 */
  8636.       }
  8637.       case XYFACKB: {
  8638.       extern int fackbug;
  8639.       return(seton(&fackbug));
  8640.       }
  8641. #endif /* NOXFER */
  8642.  
  8643.       case XYHINTS:
  8644.         return(seton(&hints));
  8645.  
  8646. #ifndef NOSPL
  8647.       case XYEVAL: {
  8648.       extern int oldeval;
  8649.       if ((x = cmkey(oldnew,2,"","", xxstring)) < 0)
  8650.         return(x);
  8651.       if ((y = cmcfm()) < 0)
  8652.         return(y);
  8653.       oldeval = x;
  8654.       return(success = 1);
  8655.       }
  8656. #endif /* NOSPL */
  8657.  
  8658. #ifndef NOXFER
  8659.       case XYFACKP: {
  8660.       extern int fackpath;
  8661.       return(seton(&fackpath));
  8662.       }
  8663. #endif /* NOXFER */
  8664.  
  8665.       case XYQNXPL: {
  8666.       extern int qnxportlock;
  8667.       return(seton(&qnxportlock));
  8668.       }
  8669.  
  8670.       default:
  8671.      if ((x = cmcfm()) < 0) return(x);
  8672.      printf("Not implemented - %s\n",cmdbuf);
  8673.      return(success = 0);
  8674.     }
  8675. }
  8676.  
  8677. /*
  8678.   H U P O K  --  Is Hangup OK?
  8679.  
  8680.   Issues a warning and gets OK from user depending on whether a connection
  8681.   seems to be open and what the SET EXIT WARNING setting is.  Returns:
  8682.     0 if not OK to hang up or exit (i.e. user said No);
  8683.     nonzero if OK.
  8684.   Argument x is used to differentiate the EXIT command from SET LINE / HOST.
  8685. */
  8686. int
  8687. hupok(x) int x; {            /* Returns 1 if OK, 0 if not OK */
  8688.     int y, z = 1;
  8689. #ifdef VMS
  8690.     extern int batch;
  8691.  
  8692.     if (batch)                /* No warnings in batch */
  8693.       return(1);
  8694. #else
  8695. #ifdef UNIX
  8696.     if (backgrd)            /* No warnings in background */
  8697.       return(1);
  8698. #endif /* UNIX */
  8699. #endif /* VMS */
  8700.  
  8701.     debug(F101,"hupok local","",local);
  8702.  
  8703.     if (!local)                /* No warnings in remote mode */
  8704.       return(1);
  8705.  
  8706.     debug(F101,"hupok x","",x);
  8707.     debug(F101,"hupok xitwarn","",xitwarn);
  8708.     debug(F101,"hupok network","",network);
  8709.     debug(F101,"hupok haveline","",haveline);
  8710.  
  8711.     if ((local && xitwarn) ||        /* Is a connection open? */
  8712.         (!x && xitwarn == 2)) {        /* Or Always give warning on EXIT */
  8713.     int needwarn = 0;
  8714.  
  8715.     if (network) {
  8716.         if (ttchk() >= 0)
  8717.           needwarn = 1;
  8718.         /* A connection seems to be open but it can't possibly be */
  8719.         if (!haveline)
  8720.           needwarn = 0;
  8721.         if (needwarn) {
  8722.         if (strcmp(ttname,"*"))
  8723.           printf(
  8724. " A network connection to %s might still be active.\n",
  8725.              ttname
  8726.              );
  8727.         else
  8728.           printf(
  8729.            " An incoming network connection might still be active.\n"
  8730.              );
  8731.         }
  8732.     } else {            /* Serial connection */
  8733.         if (carrier == CAR_OFF)    /* SET CARRIER OFF */
  8734.           needwarn = 0;        /* so we don't care about carrier. */
  8735.         else if ((y = ttgmdm()) >= 0) /* else, get modem signals */
  8736.           needwarn = (y & BM_DCD);    /* Check for carrier */
  8737.         else            /* If we can't get modem signals... */
  8738.           needwarn = (ttchk() >= 0);
  8739.         /* A connection seems to be open but it can't possibly be */
  8740.         if (!haveline)
  8741.           needwarn = 0;
  8742.         if (needwarn)
  8743.           printf(
  8744.              " A serial connection might still be active on %s.\n",
  8745.              ttname
  8746.              );
  8747.     }
  8748.  
  8749. /* If a warning was issued, get user's permission to EXIT. */
  8750.  
  8751.     if (needwarn || !x && xitwarn == 2 && local) {
  8752.         z = getyesno(x ? "OK to close? " : "OK to exit? ",0);
  8753.         debug(F101,"hupok getyesno","",z);
  8754.         if (z < -3) z = 0;
  8755.     }
  8756.     }
  8757.     return(z);
  8758. }
  8759.  
  8760. #ifndef NOSHOW
  8761. VOID
  8762. shoctl() {                /* SHOW CONTROL-PREFIXING */
  8763. #ifdef CK_SPEED
  8764.     int i;
  8765. #ifdef OS2
  8766.     int zero;
  8767. #endif /* OS2 */
  8768.     printf(
  8769. "\ncontrol quote = %d, applied to (0 = unprefixed, 1 = prefixed):\n\n",
  8770.        myctlq);
  8771. #ifdef OS2
  8772. #ifndef UNPREFIXZERO
  8773.     zero = ctlp[0];
  8774.     if (protocol == PROTO_K)        /* Zero can't be unprefixed */
  8775.       ctlp[0] = 1;            /* for Kermit */
  8776. #endif /* UNPREFIXZERO */
  8777. #endif /* OS2 */
  8778.     for (i = 0; i < 16; i++) {
  8779.     printf("  %3d: %d   %3d: %d ",i,ctlp[i], i+16, ctlp[i+16]);
  8780.     if (i == 15)
  8781.       printf("  127: %d",ctlp[127]);
  8782.     else
  8783.       printf("        ");
  8784.     printf("  %3d: %d   %3d: %d ",i+128,ctlp[i+128], i+144, ctlp[i+144]);
  8785.     if (i == 15)  printf("  255: %d",ctlp[255]);
  8786.     printf("\n");
  8787.     }
  8788.     printf("\n");
  8789. #ifndef UNPREFIXZERO
  8790. #ifdef OS2
  8791.     ctlp[0] = zero;
  8792. #endif /* OS2 */
  8793. #endif /* UNPREFIXZERO */
  8794.  
  8795. #endif /* CK_SPEED */
  8796. }
  8797.  
  8798. #ifndef NOXFER
  8799. VOID
  8800. shodbl() {                /* SHOW DOUBLE/IGNORE */
  8801. #ifdef CKXXCHAR
  8802.     int i, n = 0;
  8803.     printf("\nSET SEND DOUBLE characters:\n");
  8804.     for (i = 0; i < 255; i++) {
  8805.     if (dblt[i] & 2) {
  8806.         n++;
  8807.         printf(" %d", i);
  8808.     }
  8809.     }
  8810.     if (n == 0)
  8811.       printf(" (none)");
  8812.     n = 0;
  8813.     printf("\nSET RECEIVE IGNORE characters:\n");
  8814.     for (i = 0; i < 255; i++) {
  8815.     if (dblt[i] & 1) {
  8816.         n++;
  8817.         printf(" %d", i);
  8818.     }
  8819.     }
  8820.     if (n == 0)
  8821.       printf(" (none)");
  8822.     printf("\n\n");
  8823. #endif /* CKXXCHAR */
  8824. }
  8825. #endif /* NOXFER */
  8826. #endif /* NOSHOW */
  8827.  
  8828. #ifndef NOPUSH
  8829. #ifdef CK_REXX
  8830. /*
  8831.   Rexx command.  Note, this is not OS/2-specific, because Rexx also runs
  8832.   on other systems where C-Kermit also runs, like the Amiga.
  8833. */
  8834. #define REXBUFL 100            /* Change this if neccessary */
  8835. char rexxbuf[REXBUFL] = { '\0' };    /* Rexx's return value (string) */
  8836.  
  8837. int
  8838. dorexx() {
  8839.     int x, y;
  8840.     char *rexxcmd;
  8841.  
  8842.     if ((x = cmtxt("Rexx command","",&rexxcmd,xxstring)) < 0)
  8843.       return(x);
  8844.  
  8845. #ifdef IKSD
  8846.     if (inserver) {
  8847.         printf("?Sorry, command disabled.\r\n");
  8848.         return(success = 0);
  8849.     }
  8850. #endif /* IKSD */
  8851. #ifdef CK_APC
  8852.     /* Don't let this be set remotely */
  8853.     if (apcactive == APC_LOCAL ||
  8854.         apcactive == APC_REMOTE && apcstatus != APC_UNCH)
  8855.       return(success = 0);
  8856. #endif /* CK_APC */
  8857.  
  8858.     strcpy(line,rexxcmd);
  8859.     rexxcmd = line;
  8860. #ifdef OS2
  8861.     return(os2rexx(rexxcmd,rexxbuf,REXBUFL));
  8862. #else /* !OS2 */
  8863.     printf("Sorry, nothing happens.\n");
  8864.     return(success = 0);
  8865. #endif /* OS2 */
  8866. }
  8867. #endif /* CK_REXX */
  8868. #endif /* NOPUSH */
  8869. #endif /* NOICP */
  8870.