1 #ifdef SSHTEST
2 #define SSHBUILTIN
3 #endif /* SSHTEST */
4
5 #include "ckcsym.h" /* Symbol definitions */
6
7 /* C K U U S 3 -- "User Interface" for C-Kermit, part 3 */
8
9 /*
10 Authors:
11 Frank da Cruz <fdc@columbia.edu>,
12 The Kermit Project, New York City
13 Jeffrey E Altman <jaltman@secure-endpoints.com>
14 Secure Endpoints Inc., New York City
15
16 Copyright (C) 1985, 2020,
17 Trustees of Columbia University in the City of New York.
18 All rights reserved. See the C-Kermit COPYING.TXT file or the
19 copyright text in the ckcmai.c module for disclaimer and permissions.
20 */
21
22 /* SET command (but much material has been split off into ckuus7.c). */
23
24 /*
25 Kermit-specific includes.
26 Definitions here supersede those from system include files.
27 */
28 #include "ckcdeb.h" /* Debugging & compiler things */
29 #include "ckcasc.h" /* ASCII character symbols */
30 #include "ckcker.h" /* Kermit application definitions */
31 #include "ckcxla.h" /* Character set translation */
32 #include "ckcnet.h" /* Network symbols */
33
34 char pwbuf[PWBUFL+1] = { NUL, NUL };
35 int pwflg = 0;
36 int pwcrypt = 0;
37
38 #ifndef NOICP
39
40 #ifdef CK_AUTHENTICATION
41 #include "ckuath.h"
42 #endif /* CK_AUTHENTICATION */
43 #ifdef CK_SSL
44 #include "ck_ssl.h"
45 #endif /* CK_SSL */
46 #include "ckuusr.h" /* User interface symbols */
47 #ifdef OS2
48 #include "ckcuni.h"
49 #ifdef SSHBUILTIN
50 #include "ckossh.h"
51 #endif /* SSHBUILTIN */
52 #ifdef CK_NETBIOS
53 #include <os2.h>
54 #ifdef COMMENT /* Would you believe */
55 #undef COMMENT /* <os2.h> defines this ? */
56 #endif /* COMMENT */
57 #include "ckonbi.h"
58 extern UCHAR NetBiosAdapter;
59 #endif /* CK_NETBIOS */
60 #include "ckocon.h"
61 #include "ckokey.h"
62 #ifndef NOTERM
63 extern unsigned char colorcmd; /* Command-screen colors */
64 extern struct keytab ttyclrtab[];
65 extern int nclrs;
66 extern int tt_cols[], tt_rows[], tt_szchng[], tt_status[];
67 #endif /* NOTERM */
68 _PROTOTYP(int setprty, (void));
69 extern char startupdir[], exedir[];
70 extern int tt_modechg;
71 #ifdef NT
72 #include <windows.h>
73 #include <tapi.h>
74 #include "ckntap.h" /* Microsoft TAPI */
75 #endif /* NT */
76 #endif /* OS2 */
77
78 #ifndef OS2
79 extern char * exedir;
80 #endif /* OS2 */
81
82 #ifdef CK_RECALL
83 extern int cm_retry;
84 #endif /* CK_RECALL */
85
86 #ifdef NEWFTP
87 extern int ftpisopen();
88 #endif /* NEWFTP */
89
90 extern int cmdint;
91 extern int srvidl;
92
93 #ifdef CKFLOAT
94 extern CKFLOAT floatval; /* (see isfloat()) */
95 #endif /* CKFLOAT */
96
97 #ifndef NOPUSH
98 #ifndef NOFRILLS
99 #ifdef VMS
100 char editor[CKMAXPATH + 1] = "edit";
101 #else
102 char editor[CKMAXPATH + 1] = { NUL, NUL };
103 #endif /* VMS */
104 char editopts[128] = { NUL, NUL };
105 char editfile[CKMAXPATH + 1] = { NUL, NUL };
106 #ifdef BROWSER
107 char browser[CKMAXPATH + 1] = { NUL, NUL };
108 char browsopts[128] = { NUL, NUL };
109 char browsurl[4096] = { NUL, NUL };
110 #endif /* BROWSER */
111 #endif /* NOFRILLS */
112 #endif /* NOPUSH */
113
114 #ifndef NOFRILLS
115 #ifndef NORENAME
116 _PROTOTYP(int setrename, (void));
117 #endif /* NORENAME */
118 #endif /* NOFRILLS */
119
120 /* Variables */
121
122 int exitmsg = 1;
123 int cmd_quoting = 1;
124 int cmd_err = 1;
125 extern int hints, xcmdsrc;
126
127 #ifdef CK_KERBEROS
128 char * k4pwprompt = NULL; /* Kerberos 4 password prompt */
129 char * k4prprompt = NULL; /* Kerberos 4 principal prompt */
130 char * k5pwprompt = NULL; /* Kerberos 5 password prompt */
131 char * k5prprompt = NULL; /* Kerberos 5 principal prompt */
132 #endif /* CK_KERBEROS */
133 #ifdef CK_SRP
134 char * srppwprompt = NULL;
135 #endif /* CK_SRP */
136
137 extern char * ckprompt, * ikprompt; /* Default prompt */
138 extern xx_strp xxstring;
139
140 extern char * cdmsgfile[], * cdmsgstr;
141
142 extern int
143 local, server, success, dest, sleepcan, inserver, flow, autoflow, binary,
144 parity, escape, what, turn, duplex, backgrd, hwparity, stopbits, turnch,
145 mdmtyp, network, quiet, nettype, carrier, debses, debtim, cdtimo, nlangs,
146 bgset, pflag, msgflg, cmdmsk, xsuspend, techo, pacing, xitwarn, xitsta,
147 outesc, cmd_cols, cmd_rows, ckxech, xaskmore, haveline, didsetlin, isguest,
148 mdmsav, clearrq, saveask, debmsg;
149
150 extern int reliable, setreliable, matchdot, matchfifo, dir_dots;
151
152 #ifndef NOSERVER
153 extern int en_pri;
154 #endif /* NOSERVER */
155
156 #ifdef IKSDCONF
157 extern int iksdcf;
158 #endif /* IKSDCONF */
159 #ifdef TCPSOCKET
160 extern int tn_exit;
161 #endif /* TCPSOCKET */
162 #ifdef TNCODE
163 char * tn_pr_uid = NULL;
164 #endif /* TNCODE */
165 extern int exitonclose;
166
167 #ifndef NOKVERBS
168 extern int nkverbs;
169 extern struct keytab kverbs[];
170 #endif /* NOKVERBS */
171
172 extern int ttnproto; /* Network protocol */
173
174 extern char *ccntab[]; /* Names of control chars */
175
176 #ifdef CK_APC
177 extern int apcactive, apcstatus;
178 #endif /* CK_APC */
179
180 #ifndef NOSCRIPT
181 extern int secho; /* Whether SCRIPT cmd should echo */
182 #endif /* NOSCRIPT */
183
184 #ifdef DCMDBUF
185 extern char *atmbuf, *atxbuf;
186 #else
187 extern char atmbuf[], atxbuf[];
188 #endif /* DCMDBUF */
189 extern int cmflgs;
190
191 extern char psave[];
192 extern char uidbuf[];
193 extern int sl_uid_saved;
194 int DeleteStartupFile = 0;
195
196 extern int cmdlvl; /* Overall command level */
197
198 #ifndef NOSPL
199 _PROTOTYP( static int parsdir, (int) );
200 char prmbuf[PWBUFL+1] = { NUL, NUL };
201 int fndiags = 1; /* Function diagnostics on/off */
202 int fnerror = 1; /* Function error treatment */
203
204 #ifdef DCMDBUF
205 extern int *count, *takerr, *merror, *inpcas;
206 #else
207 extern int count[], takerr[], merror[], inpcas[];
208 #endif /* DCMDBUF */
209 extern int mecho; /* Macro echo */
210 extern long ck_alarm;
211 extern char alrm_date[], alrm_time[];
212 #else
213 extern int takerr[];
214 #endif /* NOSPL */
215
216 extern int x_ifnum;
217 extern int bigsbsiz, bigrbsiz; /* Packet buffers */
218
219 extern long speed; /* Terminal speed */
220
221 extern char ttname[]; /* Communication device name */
222 extern char myhost[] ;
223 extern char inidir[]; /* Ini File directory */
224
225 #ifndef NOSETKEY
226 extern KEY *keymap; /* Character map for SET KEY (1:1) */
227 extern MACRO *macrotab; /* Macro map for SET KEY (1:string) */
228 #endif /* NOSETKEY */
229 #ifdef OS2
230 int wideresult; /* For wide OS/2 scan codes/cmnum() */
231 #endif /* OS2 */
232
233 #ifndef NOLOCAL
234 #ifdef OS2
235 extern int tt_scrsize[]; /* Scrollback buffer Sizes */
236 #endif /* OS2 */
237 #endif /* NOLOCAL */
238
239 /* Printer settings */
240
241 extern char * printername; /* NULL if printer not redirected */
242 extern int printpipe;
243 extern int noprinter;
244 #ifdef PRINTSWI
245 int printtimo = 0;
246 char * printterm = NULL;
247 char * printsep = NULL;
248 int printertype = 0;
249 #ifdef BPRINT
250 int printbidi = 0; /* SET BPRINTER (bidirectional) */
251 long pportspeed = 0L; /* Bidirection printer port speed, */
252 int pportparity = 0; /* parity, */
253 int pportflow = FLO_KEEP; /* and flow control */
254 #endif /* BPRINT */
255 #ifdef OS2
256 extern int txt2ps; /* Text2PS conversion? */
257 extern int ps_width, ps_length; /* Text2PS dimensions */
258 #endif /* OS2 */
259 #endif /* PRINTSWI */
260
261 #ifdef OS2
262 extern int tcp_avail; /* Nonzero if TCP/IP is available */
263 #ifdef DECNET
264 extern int dnet_avail; /* Ditto for DECnet */
265 #endif /* DECNET */
266 #ifdef SUPERLAT
267 extern int slat_avail;
268 #endif /* SUPERLAT */
269 #endif /* OS2 */
270
271 static struct keytab logintab[] = {
272 { "password", LOGI_PSW, CM_INV },
273 { "prompt", LOGI_PRM, CM_INV },
274 { "userid", LOGI_UID, 0 }
275 };
276
277 #ifndef NOCSETS
278 /* system-independent character sets, defined in ckcxla.[ch] */
279 extern struct csinfo tcsinfo[];
280 extern struct langinfo langs[];
281
282 /* Other character-set related variables */
283 extern int tcharset, tslevel, language;
284 #endif /* NOCSETS */
285
286 /* File-transfer variable declarations */
287
288 #ifndef NOXFER
289 #ifdef CK_AUTODL
290 extern int cmdadl;
291 #endif /* CK_AUTODL */
292
293 #ifndef NOSERVER
294 extern int ngetpath;
295 extern char * getpath[];
296 #endif /* NOSERVER */
297
298 extern struct ck_p ptab[];
299
300 extern CHAR sstate; /* Protocol start state */
301 extern CHAR myctlq; /* Control-character prefix */
302 extern CHAR myrptq; /* Repeat-count prefix */
303
304 extern int protocol, size, spsiz, spmax, urpsiz, srvtim, srvcdmsg, slostart,
305 srvdis, xfermode, ckdelay, keep, maxtry, unkcs, bctr, bctf, ebqflg, swcapr,
306 wslotr, lscapr, lscapu, spsizr, rptena, rptmin, docrc, xfrcan, xfrchr,
307 xfrnum, xfrbel, xfrint, srvping, g_xfermode, xfrxla;
308
309 #ifdef PIPESEND
310 extern int usepipes;
311 #endif /* PIPESEND */
312
313 #ifdef CKXXCHAR /* DOUBLE / IGNORE char table */
314 extern int dblflag, ignflag, dblchar;
315 extern short dblt[];
316 #endif /* CKXXCHAR */
317
318 #ifdef CK_SPEED
319 extern short ctlp[]; /* Control-prefix table */
320 extern int prefixing;
321 static struct keytab pfxtab[] = {
322 "all", PX_ALL, 0,
323 "cautious", PX_CAU, 0,
324 "minimal", PX_WIL, 0,
325 "none", PX_NON, 0
326 };
327 #endif /* CK_SPEED */
328 #endif /* NOXFER */
329
330 /* Declarations from cmd package */
331
332 #ifdef DCMDBUF
333 extern char *cmdbuf; /* Command buffer */
334 extern char *line;
335 extern char *tmpbuf;
336 #else
337 extern char cmdbuf[]; /* Command buffer */
338 extern char line[]; /* Character buffer for anything */
339 extern char tmpbuf[];
340 #endif /* DCMDBUF */
341
342 /* From main ckuser module... */
343
344 extern char *tp, *lp; /* Temporary buffer */
345
346 extern int tlevel; /* Take Command file level */
347
348 #ifndef NOLOCAL
349 extern int sessft; /* Session-log file type */
350 extern int slogts; /* Session-log timestamps on/off */
351 extern int slognul; /* Lines null-terminated */
352 #endif /* NOLOCAL */
353
354 char * tempdir = NULL; /* Temporary directory */
355
356 #ifdef VMS
357 int vms_msgs = 1; /* SET MESSAGES */
358 extern int batch;
359 #endif /* VMS */
360
361 /* Keyword tables for SET commands */
362
363 #ifdef CK_SPEED
364 struct keytab ctltab[] = {
365 "prefixed", 1, 0, /* Note, the values are important. */
366 "unprefixed", 0, 0
367 };
368 #endif /* CK_SPEED */
369
370 static struct keytab oldnew[] = {
371 "new", 0, 0,
372 "old", 1, 0
373 };
374
375 #define MCH_FIFO 1
376 #define MCH_DOTF 2
377 struct keytab matchtab[] = {
378 { "dotfile", MCH_DOTF, 0 },
379 { "fifo", MCH_FIFO, 0 }
380 };
381 int nmatchtab = (sizeof(matchtab) / sizeof(struct keytab));
382
383 #ifndef NOSPL
384 static struct keytab functab[] = {
385 "diagnostics", FUNC_DI, 0,
386 "error", FUNC_ER, 0
387 };
388 static int nfunctab = (sizeof(functab) / sizeof(struct keytab));
389
390 struct keytab outptab[] = { /* SET OUTPUT parameters */
391 "pacing", 0, 0, /* only one so far... */
392 "special-escapes", 1, 0
393 };
394 int noutptab = (sizeof(outptab) / sizeof(struct keytab)); /* How many */
395 #endif /* NOSPL */
396
397 struct keytab chktab[] = { /* Block check types */
398 "1", 1, 0, /* 1 = 6-bit checksum */
399 "2", 2, 0, /* 2 = 12-bit checksum */
400 "3", 3, 0, /* 3 = 16-bit CRC */
401 "4", 4, 0, /* Same as B */
402 "5", 5, 0, /* Same as F */
403 "blank-free-2", 4, CM_INV, /* B = 12-bit checksum, no blanks */
404 "force-3", 5, CM_INV /* F = Force CRC on ALL packets */
405 };
406 static int nchkt = (sizeof(chktab) / sizeof(struct keytab));
407
408 struct keytab rpttab[] = { /* SET REPEAT */
409 "counts", 0, 0, /* On or Off */
410 #ifdef COMMENT
411 "minimum", 1, 0, /* Threshhold */
412 #endif /* COMMENT */
413 "prefix", 2, 0 /* Repeat-prefix character value */
414 };
415
416 #ifndef NOLOCAL
417 /* For SET [ MODEM ] CARRIER, and also for SET DIAL CONNECT */
418
419 struct keytab crrtab[] = {
420 "automatic", CAR_AUT, 0, /* 2 */
421 "off", CAR_OFF, 0, /* 0 */
422 "on", CAR_ON, 0 /* 1 */
423 };
424 int ncrr = 3;
425 #endif /* NOLOCAL */
426
427 struct keytab ooatab[] = { /* On/Off/Auto table */
428 "automatic", SET_AUTO, 0, /* 2 */
429 "off", SET_OFF, 0, /* 0 */
430 "on", SET_ON, 0 /* 1 */
431 };
432
433 struct keytab ooetab[] = { /* On/Off/Stderr table 2010/03/12 */
434 "off", SET_OFF, 0, /* for SET DEBUG MESSAGES */
435 "on", SET_ON, 0, /* 2013-03-13 and SET EXIT MESSAGE */
436 "s", 2, CM_ABR|CM_INV,
437 "st", 2, CM_ABR|CM_INV,
438 "std", 2, CM_ABR|CM_INV,
439 "stderr", 2, 0,
440 "stdout", SET_ON, CM_INV
441 };
442 static int nooetab = (sizeof(ooetab) / sizeof(struct keytab));
443
444 struct keytab ooktab[] = { /* On/Off/Ask table */
445 "ask", 2, 0, /* 2 */
446 "off", SET_OFF, 0, /* 0 */
447 "on", SET_ON, 0 /* 1 */
448 };
449
450 struct keytab qvtab[] = { /* Quiet/Verbose table */
451 "quiet", 1, 0,
452 "verbose", 0, 0
453 };
454 int nqvt = 2;
455
456 /* For SET DEBUG */
457
458 #define DEB_OFF 0
459 #define DEB_ON 1
460 #define DEB_SES 2
461 #define DEB_TIM 3
462 #define DEB_LEN 4
463 #define DEB_MSG 5
464
465 struct keytab dbgtab[] = {
466 "linelength", DEB_LEN, CM_INV,
467 "m", DEB_MSG, CM_ABR|CM_INV,
468 "message", DEB_MSG, 0,
469 "msg", DEB_MSG, CM_INV,
470 "off", DEB_OFF, 0,
471 "on", DEB_ON, 0,
472 "session", DEB_SES, 0,
473 "timestamps", DEB_TIM, 0
474 };
475 int ndbg = (sizeof(dbgtab) / sizeof(struct keytab));
476
477 #ifndef NOLOCAL
478 /* Transmission speeds */
479
480 #ifdef TTSPDLIST /* Speed table constructed at runtime . . . */
481
482 struct keytab * spdtab = NULL;
483 int nspd = 0;
484
485 #else
486 /*
487 Note, the values are encoded in cps rather than bps because 19200 and higher
488 are too big for some ints. All but 75bps are multiples of ten. Result of
489 lookup in this table must be multiplied by 10 to get actual speed in bps.
490 If this number is 70, it must be changed to 75. If it is 888, this means
491 75/1200 split speed.
492
493 The values are generic, rather than specific to UNIX. We can't use B75,
494 B1200, B9600, etc, because non-UNIX versions of C-Kermit will not
495 necessarily have these symbols defined. The BPS_xxx symbols are
496 Kermit-specific, and are defined in ckcdeb.h or on the CC command line.
497
498 Like all other keytabs, this one must be in "alphabetical" order,
499 rather than numeric order.
500 */
501 struct keytab spdtab[] = {
502 "0", 0, CM_INV,
503 "110", 11, 0,
504 #ifdef BPS_115K
505 "115200",11520, 0,
506 #endif /* BPS_115K */
507 "1200", 120, 0,
508 #ifdef BPS_134
509 "134.5", 134, 0,
510 #endif /* BPS_134 */
511 #ifdef BPS_14K
512 "14400", 1440, 0,
513 #endif /* BPS_14K */
514 #ifdef BPS_150
515 "150", 15, 0,
516 #endif /* BPS_150 */
517 #ifdef BPS_1800
518 "1800", 180, 0,
519 #endif /* BPS_150 */
520 #ifdef BPS_19K
521 "19200", 1920, 0,
522 #endif /* BPS_19K */
523 #ifdef BPS_200
524 "200", 20, 0,
525 #endif /* BPS_200 */
526 #ifdef BPS_230K
527 "230400", 23040, 0,
528 #endif /* BPS_230K */
529 "2400", 240, 0,
530 #ifdef BPS_28K
531 "28800", 2880, 0,
532 #endif /* BPS_28K */
533 "300", 30, 0,
534 #ifdef BPS_3600
535 "3600", 360, 0,
536 #endif /* BPS_3600 */
537 #ifdef BPS_38K
538 "38400", 3840, 0,
539 #endif /* BPS_38K */
540 #ifdef BPS_460K
541 "460800", 46080, 0, /* Need 32 bits for this... */
542 #endif /* BPS_460K */
543 "4800", 480, 0,
544 #ifdef BPS_50
545 "50", 5, 0,
546 #endif /* BPS_50 */
547 #ifdef BPS_57K
548 "57600", 5760, 0,
549 #endif /* BPS_57K */
550 "600", 60, 0,
551 #ifdef BPS_7200
552 "7200", 720, 0,
553 #endif /* BPS_7200 */
554 #ifdef BPS_75
555 "75", 7, 0,
556 #endif /* BPS_75 */
557 #ifdef BPS_7512
558 "75/1200",888, 0, /* Code "888" for split speed */
559 #endif /* BPS_7512 */
560 #ifdef BPS_76K
561 "76800", 7680, 0,
562 #endif /* BPS_76K */
563 #ifdef BPS_921K
564 "921600", 92160,0, /* Need 32 bits for this... */
565 #endif /* BPS_921K */
566 "9600", 960, 0
567 };
568 int nspd = (sizeof(spdtab) / sizeof(struct keytab)); /* How many speeds */
569 #endif /* TTSPDLIST */
570
571 #ifdef TN_COMPORT
572 struct keytab tnspdtab[] = { /* RFC 2217 TELNET COMPORT Option */
573 "115200", 11520, 0, /* (add any other defined speeds) */
574 "1200", 120, 0,
575 "14400", 1440, 0,
576 "19200", 1920, 0,
577 "230400", 23040, 0,
578 "2400", 240, 0,
579 "28800", 2880, 0,
580 "300", 30, 0,
581 "38400", 3840, 0,
582 "460800", 46080, 0,
583 "4800", 480, 0,
584 "57600", 5760, 0,
585 "600", 60, 0,
586 "9600", 960, 0
587 };
588 int ntnspd = (sizeof(tnspdtab) / sizeof(struct keytab)); /* How many speeds */
589 #endif /* TN_COMPORT */
590 #endif /* NOLOCAL */
591
592 #ifndef NOCSETS
593 extern struct keytab lngtab[]; /* Languages for SET LANGUAGE */
594 extern int nlng;
595 #endif /* NOCSETS */
596
597 #ifndef NOLOCAL
598 /* Duplex keyword table */
599
600 struct keytab dpxtab[] = {
601 "full", 0, 0,
602 "half", 1, 0
603 };
604 #endif /* NOLOCAL */
605
606 /* Flow Control */
607
608 struct keytab cxtypesw[] = {
609 #ifdef DECNET
610 "/decnet", CXT_DECNET, 0,
611 #endif /* DECNET */
612 "/direct-serial", CXT_DIRECT, 0,
613 #ifdef DECNET
614 "/lat", CXT_LAT, 0,
615 #else
616 #ifdef SUPERLAT
617 "/lat", CXT_LAT, 0,
618 #endif /* SUPERLAT */
619 #endif /* DECNET */
620 "/modem", CXT_MODEM, 0,
621 #ifdef NPIPE
622 "/named-pipe", CXT_NPIPE, 0,
623 #endif /* NPIPE */
624 #ifdef NETBIOS
625 "/netbios", CXT_NETBIOS, 0,
626 #endif /* NETBIOS */
627 "/remote", CXT_REMOTE, 0,
628 #ifdef TCPSOCKET
629 "/tcpip", CXT_TCPIP, 0,
630 #endif /* TCPSOCKET */
631 #ifdef ANYX25
632 "/x.25", CXT_X25, 0,
633 #endif /* ANYX25 */
634 "", 0, 0
635 };
636 int ncxtypesw = (sizeof(cxtypesw) / sizeof(struct keytab));
637
638 #ifdef TN_COMPORT
639 struct keytab tnflotab[] = { /* SET FLOW-CONTROL keyword table */
640 "dtr/cd", FLO_DTRC, 0, /* for RFC 2217 Telnet COMPORT */
641 "dtr/cts", FLO_DTRT, 0,
642 "keep", FLO_KEEP, 0,
643 "none", FLO_NONE, 0,
644 "rts/cts", FLO_RTSC, 0,
645 "xon/xoff", FLO_XONX, 0
646 };
647 int ntnflo = (sizeof(tnflotab) / sizeof(struct keytab));
648 #endif /* TN_COMPORT */
649
650 struct keytab flotab[] = { /* SET FLOW-CONTROL keyword table */
651 "automatic", FLO_AUTO, CM_INV, /* Not needed any more */
652 #ifdef CK_DTRCD
653 "dtr/cd", FLO_DTRC, 0,
654 #endif /* CK_DTRCD */
655 #ifdef CK_DTRCTS
656 "dtr/cts", FLO_DTRT, 0,
657 #endif /* CK_DTRCTS */
658 "keep", FLO_KEEP, 0,
659 "none", FLO_NONE, 0,
660 #ifdef CK_RTSCTS
661 "rts/cts", FLO_RTSC, 0,
662 #endif /* CK_RTSCTS */
663 #ifndef Plan9
664 "xon/xoff", FLO_XONX, 0,
665 #endif /* Plan9 */
666 "", 0, 0
667 };
668 int nflo = (sizeof(flotab) / sizeof(struct keytab)) - 1;
669
670 /* Handshake characters */
671
672 struct keytab hshtab[] = {
673 "bell", 007, 0,
674 "code", 998, 0,
675 "cr", 015, 0,
676 "esc", 033, 0,
677 "lf", 012, 0,
678 "none", 999, 0, /* (can't use negative numbers) */
679 "xoff", 023, 0,
680 "xon", 021, 0
681 };
682 int nhsh = (sizeof(hshtab) / sizeof(struct keytab));
683
684 #ifndef NOLOCAL
685 static struct keytab sfttab[] = { /* File types for SET SESSION-LOG */
686 "ascii", XYFT_T, CM_INV,
687 "binary", XYFT_B, 0,
688 "debug", XYFT_D, 0,
689 "null-padded-lines", 998, 0,
690 "text", XYFT_T, 0,
691 "timestamped-text", 999, 0
692 };
693 static int nsfttab = (sizeof(sfttab) / sizeof(struct keytab));
694 #endif /* NOLOCAL */
695
696 #ifndef NODIAL
697
698 #ifdef NETCONN /* Networks directory depends */
699 int nnetdir = 0; /* on DIAL code -- fix later... */
700 char *netdir[MAXDDIR+2];
701 #endif /* NETCONN */
702
703 _PROTOTYP( static int setdial, (int) );
704 _PROTOTYP( static int setdcd, (void) );
705 _PROTOTYP( static int cklogin, (void) );
706
707 #ifndef MINIDIAL
708 #ifdef OLDTBCODE
709 extern int tbmodel; /* Telebit model ID */
710 #endif /* OLDTBCODE */
711 #endif /* MINIDIAL */
712
713 extern MDMINF *modemp[]; /* Pointers to modem info structs */
714 extern struct keytab mdmtab[]; /* Modem types (in module ckudia.c) */
715 extern int nmdm; /* Number of them */
716
717 _PROTOTYP(static int dialstr,(char **, char *));
718
719 extern int dialhng, dialtmo, dialksp, dialdpy, dialmhu, dialec, dialdc;
720 extern int dialrtr, dialint, dialudt, dialsrt, dialrstr, mdmwaitd;
721 extern int mdmspd, dialfc, dialmth, dialesc, dialfld, dialidt, dialpace;
722 extern int mdmspk, mdmvol, dialtest;
723
724 int dialcvt = 2; /* DIAL CONVERT-DIRECTORY */
725 int dialcnf = 0; /* DIAL CONFIRMATION */
726 int dialcon = 2; /* DIAL CONNECT */
727 int dialcq = 0; /* DIAL CONNECT AUTO quiet/verbose */
728 extern long dialmax, dialcapas;
729 int usermdm = 0;
730 extern int ndialdir;
731 extern char *dialini, *dialmstr, *dialmprmt, *dialdir[], *dialcmd, *dialnpr,
732 *dialdcon, *dialdcoff, *dialecon, *dialecoff, *dialhcmd, *dialx3,
733 *dialhwfc, *dialswfc, *dialnofc, *dialtone, *dialpulse, *dialname, *diallac;
734 extern char *diallcc, *dialixp, *dialixs, *dialldp, *diallds, *dialtfp,
735 *dialpxi, *dialpxo, *dialsfx, *dialaaon, *dialaaoff;
736 extern char *diallcp, *diallcs, *dialini2, *dialmac;
737 extern char *dialspoff, *dialspon, *dialvol1, *dialvol2, *dialvol3;
738
739 char *dialtocc[MAXTPCC] = { NULL, NULL };
740 int ndialtocc = 0;
741 char *dialpucc[MAXTPCC] = { NULL, NULL };
742 int ndialpucc = 0;
743
744 char *dialtfc[MAXTOLLFREE] = {
745 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
746 };
747 int ntollfree = 0;
748
749 char *dialpxx[MAXPBXEXCH] = {
750 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
751 };
752 int ndialpxx = 0;
753
754 char *diallcac[MAXLOCALAC] = {
755 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
756 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
757 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
758 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
759 };
760 int nlocalac = 0;
761
762 static struct keytab drstrtab[] = {
763 "international", 5, 0,
764 "local", 2, 0,
765 "long-distance", 4, 0,
766 "none", 6, 0
767 };
768
769 static struct keytab dcnvtab[] = {
770 "ask", 2, 0,
771 "off", 0, 0,
772 "on", 1, 0
773 };
774
775 struct keytab setmdm[] = {
776 "capabilities", XYDCAP, 0,
777 "carrier-watch", XYDMCD, 0,
778 "command", XYDSTR, 0,
779 "compression", XYDDC, CM_INV,
780 "data-compression", XYDDC, 0,
781 "dial-command", XYDDIA, 0,
782 "error-correction", XYDEC, 0,
783 "escape-character", XYDESC, 0,
784 "flow-control", XYDFC, 0,
785 "hangup-method", XYDMHU, 0,
786 #ifndef NOXFER
787 "kermit-spoof", XYDKSP, 0,
788 #endif /* NOXFER */
789 "maximum-speed", XYDMAX, 0,
790 "name", XYDNAM, 0,
791 "speaker", XYDSPK, 0,
792 "speed-matching", XYDSPD, 0,
793 "type", XYDTYP, 0,
794 "volume", XYDVOL, 0
795 };
796 int nsetmdm = (sizeof(setmdm) / sizeof(struct keytab));
797
798 struct keytab voltab[] = {
799 "high", 3, 0,
800 "low", 1, 0,
801 "medium", 2, 0
802 };
803
804 struct keytab mdmcap[] = {
805 "at-commands", CKD_AT, 0,
806 "compression", CKD_DC, 0,
807 "dc", CKD_DC, CM_INV,
808 "ec", CKD_EC, CM_INV,
809 "error-correction", CKD_EC, 0,
810 "hardware-flow", CKD_HW, 0,
811 "hwfc", CKD_HW, CM_INV,
812 "itu", CKD_V25, CM_INV,
813 "kermit-spoof", CKD_KS, 0,
814 "ks", CKD_KS, CM_INV,
815 "sb", CKD_SB, CM_INV,
816 "software-flow", CKD_SW, 0,
817 "speed-buffering", CKD_SB, 0,
818 "swfc", CKD_SW, CM_INV,
819 "tb", CKD_TB, CM_INV,
820 "telebit", CKD_TB, 0,
821 "v25bis-commands", CKD_V25, 0
822 };
823 int nmdmcap = (sizeof(mdmcap) / sizeof(struct keytab));
824
825 #ifdef COMMENT /* SET ANSWER not implemented yet */
826 static struct keytab answertab[] = {
827 { "caller-id", XYA_CID, 0 };
828 { "rings", XYA_RNG, 0 };
829 { "", 0, 0 }
830 };
831 static int nanswertab = (sizeof(answertab) / sizeof(struct keytab)) - 1;
832 #endif /* COMMENT */
833
834 struct keytab dialtab[] = { /* SET DIAL table */
835 "area-code", XYDLAC, 0, /* Also still includes items */
836 "compression", XYDDC, CM_INV, /* that were moved to SET MODEM, */
837 "confirmation", XYDCNF, 0, /* but they are CM_INVisible... */
838 "connect", XYDCON, 0,
839 "convert-directory",XYDCVT, 0,
840 "country-code", XYDLCC, 0,
841 "dial-command", XYDDIA, CM_INV,
842 "directory", XYDDIR, 0,
843 "display", XYDDPY, 0,
844 "escape-character", XYDESC, CM_INV,
845 "error-correction", XYDEC, CM_INV,
846 "flow-control", XYDFC, CM_INV,
847 "force-long-distance", XYDFLD, 0,
848 "hangup", XYDHUP, 0,
849 "ignore-dialtone", XYDIDT, 0,
850 "interval", XYDINT, 0,
851 "in", XYDINI, CM_INV|CM_ABR,
852 "init-string", XYDINI, CM_INV,
853 "intl-prefix", XYDIXP, 0,
854 "intl-suffix", XYDIXS, 0,
855 #ifndef NOXFER
856 "kermit-spoof", XYDKSP, CM_INV,
857 #endif /* NOXFER */
858 "lc-area-codes", XYDLLAC, 0,
859 "lc-prefix", XYDLCP, 0,
860 "lc-suffix", XYDLCS, 0,
861 "ld-prefix", XYDLDP, 0,
862 "ld-suffix", XYDLDS, 0,
863 "local-area-code", XYDLAC, CM_INV,
864 "local-prefix", XYDLCP, CM_INV,
865 "local-suffix", XYDLCS, CM_INV,
866 "m", XYDMTH, CM_INV|CM_ABR,
867 #ifndef NOSPL
868 "macro", XYDMAC, 0, /* 195 */
869 #endif /* NOSPL */
870 #ifdef MDMHUP
871 "me", XYDMTH, CM_INV|CM_ABR,
872 #endif /* MDMHUP */
873 "method", XYDMTH, 0,
874 "mnp-enable", XYDMNP, CM_INV, /* obsolete but still accepted */
875 #ifdef MDMHUP
876 "modem-hangup", XYDMHU, CM_INV,
877 #endif /* MDMHUP */
878 "pacing", XYDPAC, 0,
879 "pbx-exchange", XYDPXX, 0,
880 "pbx-inside-prefix",XYDPXI, 0,
881 "pbx-outside-prefix",XYDPXO, 0,
882 "prefix", XYDNPR, 0,
883 "pulse-countries", XYDPUCC, 0,
884 "restrict", XYDRSTR, 0,
885 "retries", XYDRTM, 0,
886 "sort", XYDSRT, 0,
887 "speed-matching", XYDSPD, CM_INV,
888 "string", XYDSTR, CM_INV,
889 "suffix", XYDSFX, 0,
890 "test", XYDTEST, 0,
891 "timeout", XYDTMO, 0,
892 "tf-area-code", XYDTFC, CM_INV,
893 "tf-prefix", XYDTFP, CM_INV,
894 "toll-free-area-code",XYDTFC,0,
895 "toll-free-prefix", XYDTFP, 0,
896 "tone-countries", XYDTOCC, 0
897 };
898 int ndial = (sizeof(dialtab) / sizeof(struct keytab));
899
900 #ifdef MDMHUP
901 struct keytab mdmhang[] = {
902 "dtr", 0, 0,
903 "modem-command", 1, 0,
904 "rs232-signal", 0, 0,
905 "v24-signal", 0, CM_INV
906 };
907 #endif /* MDMHUP */
908
909 static struct keytab mdmcmd[] = {
910 "autoanswer", XYDS_AN, 0, /* autoanswer */
911 "compression", XYDS_DC, 0, /* data compression */
912 "dial-mode-prompt", XYDS_MP, 0, /* dial mode prompt */
913 "dial-mode-string", XYDS_MS, 0, /* dial mode string */
914 "error-correction", XYDS_EC, 0, /* error correction */
915 "hangup-command", XYDS_HU, 0, /* hangup command */
916 "hardware-flow", XYDS_HW, 0, /* hwfc */
917 "ignore-dialtone", XYDS_ID, 0, /* ignore dialtone */
918 "init-string", XYDS_IN, 0, /* init string */
919 "no-flow-control", XYDS_NF, 0, /* no flow control */
920 "predial-init", XYDS_I2, 0, /* last-minute setup commands */
921 "pulse", XYDS_DP, 0, /* pulse */
922 "software-flow", XYDS_SW, 0, /* swfc */
923 "speaker", XYDS_SP, 0, /* Speaker */
924 "tone", XYDS_DT, 0, /* tone */
925 "volume", XYDS_VO, 0 /* Volume */
926 };
927 static int nmdmcmd = (sizeof(mdmcmd) / sizeof(struct keytab));
928
929 struct keytab dial_fc[] = {
930 "auto", FLO_AUTO, 0,
931 "none", FLO_NONE, 0,
932 "rts/cts", FLO_RTSC, 0,
933 "xon/xoff", FLO_XONX, 0
934 };
935
936 struct keytab dial_m[] = { /* DIAL METHOD */
937 "auto", XYDM_A, 0,
938 "default", XYDM_D, 0,
939 "pulse", XYDM_P, 0,
940 "tone", XYDM_T, 0
941 };
942 int ndial_m = (sizeof(dial_m)/sizeof(struct keytab));
943 #endif /* NODIAL */
944
945 #ifdef CK_TAPI
946 struct keytab tapitab[] = { /* Top-Level Microsoft TAPI */
947 "configure-line", XYTAPI_CFG, 0,
948 "dialing-properties", XYTAPI_DIAL, 0
949 };
950 int ntapitab = (sizeof(tapitab)/sizeof(struct keytab));
951
952 struct keytab settapitab[] = { /* SET Microsoft TAPI */
953 "inactivity-timeout", XYTAPI_INA, 0,
954 "line", XYTAPI_LIN, 0,
955 "location", XYTAPI_LOC, 0,
956 "manual-dialing", XYTAPI_MAN, 0,
957 "modem-dialing", XYTAPI_PASS, 0,
958 "modem-lights", XYTAPI_LGHT, 0,
959 "phone-number-conversions", XYTAPI_CON, 0,
960 "port", XYTAPI_LIN, CM_INV,
961 "post-dial-terminal", XYTAPI_PST, 0,
962 "pre-dial-terminal", XYTAPI_PRE, 0,
963 "use-windows-configuration", XYTAPI_USE, 0,
964 "wait-for-credit-card-tone", XYTAPI_BNG, 0
965 };
966 int nsettapitab = (sizeof(settapitab)/sizeof(struct keytab));
967
968 struct keytab * tapiloctab = NULL; /* Microsoft TAPI Locations */
969 int ntapiloc = 0;
970 extern struct keytab * tapilinetab; /* Microsoft TAPI Line Devices */
971 extern int ntapiline;
972 extern int tttapi; /* TAPI in use */
973 extern int tapipass; /* TAPI Passthrough mode */
974 extern int tapiconv; /* TAPI Conversion mode */
975 extern int tapilights;
976 extern int tapipreterm;
977 extern int tapipostterm;
978 extern int tapimanual;
979 extern int tapiinactivity;
980 extern int tapibong;
981 extern int tapiusecfg;
982 #endif /* CK_TAPI */
983
984 #ifndef NOPUSH
985 extern int nopush;
986 extern int wildena;
987 #ifdef UNIX
988 struct keytab wildtab[] = { /* SET WILDCARD-EXPANSION */
989 #ifdef UNIX
990 "kermit", WILD_KER, 0, /* By Kermit */
991 #endif /* UNIX */
992 "off", WILD_OFF, 0, /* Disabled */
993 "on", WILD_ON, 0, /* Enabled */
994 #ifdef UNIX
995 "shell", WILD_SHE, 0, /* By Shell */
996 #endif /* UNIX */
997 "", 0, 0
998 };
999 int nwild = (sizeof(wildtab) / sizeof(struct keytab)) - 1;
1000
1001 struct keytab wdottab[] = { /* cont'd */
1002 "/match-dot-files", 1, 0,
1003 "/no-match-dot-files", 0, 0
1004 };
1005 extern int wildxpand;
1006 #endif /* UNIX */
1007 #endif /* NOPUSH */
1008
1009 #ifdef NETCONN
1010 extern struct keytab netcmd[], netkey[];
1011 extern int nnets, nnetkey;
1012 #ifdef TCPSOCKET
1013 extern struct keytab tcpopt[];
1014 extern int ntcpopt;
1015 #endif /* TCPSOCKET */
1016 #ifdef NPIPE
1017 char pipename[PIPENAML+1] = { NUL, NUL };
1018 #endif /* NPIPE */
1019 #ifdef CK_NETBIOS
1020 extern unsigned char NetBiosName[];
1021 #endif /* CK_NETBIOS */
1022 #endif /* NETCONN */
1023
1024 #ifdef ANYX25
1025 struct keytab x25tab[] = {
1026 "call-user-data", XYUDAT, 0,
1027 "closed-user-group", XYCLOS, 0,
1028 "reverse-charge", XYREVC, 0
1029 };
1030 int nx25 = (sizeof(x25tab) / sizeof(struct keytab));
1031
1032 #ifndef IBMX25
1033 struct keytab padx3tab[] = {
1034 "break-action", PAD_BREAK_ACTION, 0,
1035 "break-character", PAD_BREAK_CHARACTER, 0,
1036 "character-delete", PAD_CHAR_DELETE_CHAR, 0,
1037 "cr-padding", PAD_PADDING_AFTER_CR, 0,
1038 "discard-output", PAD_SUPPRESSION_OF_DATA, 0,
1039 "echo", PAD_ECHO, 0,
1040 "editing", PAD_EDITING, 0,
1041 "escape", PAD_ESCAPE, 0,
1042 "forward", PAD_DATA_FORWARD_CHAR, 0,
1043 "lf-padding", PAD_PADDING_AFTER_LF, 0,
1044 "lf-insert", PAD_LF_AFTER_CR, 0,
1045 "line-delete", PAD_BUFFER_DELETE_CHAR, 0,
1046 "line-display", PAD_BUFFER_DISPLAY_CHAR, 0,
1047 "line-fold", PAD_LINE_FOLDING, 0,
1048 "pad-flow-control", PAD_FLOW_CONTROL_BY_PAD, 0,
1049 "service-signals", PAD_SUPPRESSION_OF_SIGNALS, 0,
1050 "timeout", PAD_DATA_FORWARD_TIMEOUT, 0,
1051 /* Speed is read-only */
1052 "transmission-rate", PAD_LINE_SPEED, 0,
1053 "user-flow-control", PAD_FLOW_CONTROL_BY_USER, 0
1054 };
1055 int npadx3 = (sizeof(padx3tab) / sizeof(struct keytab));
1056 #endif /* IBMX25 */
1057 #endif /* ANYX25 */
1058
1059 #ifdef TLOG
1060 static struct keytab vbtab[] = {
1061 "brief", 0, 0,
1062 #ifdef OS2ORUNIX
1063 "ftp", 2, 0,
1064 #else
1065 #ifdef VMS
1066 "ftp", 2, 0,
1067 #endif /* def VMS */
1068 #endif /* OS2ORUNIX */
1069 "verbose", 1, 0
1070 };
1071 int nvb = (sizeof(vbtab) / sizeof(struct keytab));
1072 #endif /* TLOG */
1073
1074 #ifdef CKSYSLOG
1075 static struct keytab syslogtab[] = {
1076 "all", SYSLG_CX, 0,
1077 "commands", SYSLG_CM, 0,
1078 "connection", SYSLG_AC, 0,
1079 "debug", SYSLG_DB, 0,
1080 "dial", SYSLG_DI, 0,
1081 "file-access", SYSLG_FA, 0,
1082 "file-create", SYSLG_FC, 0,
1083 "login", SYSLG_LI, 0,
1084 "none", SYSLG_NO, 0,
1085 "protocol", SYSLG_PR, 0
1086 };
1087 int nsyslog = (sizeof(syslogtab) / sizeof(struct keytab));
1088 #endif /* CKSYSLOG */
1089
1090 /* Parity keyword table */
1091
1092 struct keytab partbl[] = {
1093 "even", 'e', 0,
1094 #ifdef HWPARITY
1095 "hardware",'H', 0,
1096 #endif /* HWPARITY */
1097 "mark", 'm', 0,
1098 "none", 0 , 0,
1099 "odd", 'o', 0,
1100 "space", 's', 0
1101 };
1102 int npar = (sizeof(partbl) / sizeof(struct keytab));
1103
1104 #ifdef HWPARITY
1105 struct keytab hwpartbl[] = {
1106 /* Add mark and space if needed and possible */
1107 "even", 'e', 0,
1108 #ifdef OS2
1109 "mark", 'm', 0,
1110 #endif /* OS2 */
1111 "odd", 'o', 0,
1112 #ifdef OS2
1113 "space", 's', 0,
1114 #endif /* OS2 */
1115 "", 0, 0
1116 };
1117 int nhwpar = (sizeof(hwpartbl) / sizeof(struct keytab)) - 1;
1118 #endif /* HWPARITY */
1119
1120 /* On/Off table */
1121
1122 struct keytab onoff[] = {
1123 "off", 0, 0,
1124 "on", 1, 0
1125 };
1126
1127 #define XYCD_M 0 /* CD MESSAGE */
1128 #define XYCD_P 1 /* CD PATH */
1129 #define XYCD_H 2 /* CD HOME */
1130
1131 struct keytab cdtab[] = {
1132 "home", XYCD_H, 0,
1133 "message", XYCD_M, 0,
1134 "path", XYCD_P, 0
1135 };
1136 int ncdtab = (sizeof(cdtab) / sizeof(struct keytab));
1137
1138 struct keytab cdmsg[] = {
1139 "file", 2, 0,
1140 "off", 0, 0,
1141 "on", 1, 0
1142 };
1143 int ncdmsg = (sizeof(cdmsg) / sizeof(struct keytab));
1144
1145 static
1146 struct keytab xittab[] = { /* SET EXIT */
1147 "hangup", 3, 0, /* ...HANGUP */
1148 "message", 4, 0, /* ...MESSAGE */
1149 "on-disconnect", 2, 0, /* ...ON-DISCONNECT */
1150 "status", 0, 0, /* ...STATUS */
1151 "warning", 1, 0 /* ...WARNING */
1152 };
1153 int nexit = (sizeof(xittab) / sizeof(struct keytab));
1154
1155 struct keytab xitwtab[] = { /* SET EXIT WARNING */
1156 "always", 2, 0, /* even when not connected */
1157 "off", 0, 0, /* no warning */
1158 "on", 1, 0 /* when connected */
1159 };
1160 int nexitw = (sizeof(xitwtab) / sizeof(struct keytab));
1161
1162 struct keytab rltab[] = {
1163 "local", 1, 0, /* ECHO values */
1164 "off", 0, CM_INV,
1165 "on", 1, CM_INV,
1166 "remote", 0, 0
1167 };
1168 int nrlt = (sizeof(rltab) / sizeof(struct keytab));
1169
1170 /* Incomplete File Disposition table */
1171
1172 struct keytab ifdtab[] = {
1173 "discard", SET_OFF, 0,
1174 "keep", SET_ON, 0
1175 };
1176
1177 struct keytab ifdatab[] = {
1178 "auto", SET_AUTO, 0,
1179 "discard", SET_OFF, 0,
1180 "keep", SET_ON, 0
1181 };
1182
1183 char * ifdnam[] = { "discard", "keep", "auto" };
1184
1185 /* SET TAKE parameters table */
1186 static
1187 struct keytab taktab[] = {
1188 "echo", 0, 0,
1189 "error", 1, 0,
1190 "off", 2, CM_INV, /* For compatibility */
1191 "on", 3, CM_INV /* with MS-DOS Kermit... */
1192 };
1193
1194 #ifndef NOSPL
1195 #ifdef COMMENT
1196 /* not used */
1197 static
1198 struct keytab suftab[] = { /* (what to do with) STARTUP-FILE */
1199 "delete", 1, 0,
1200 "keep", 0, 0
1201 };
1202 #endif /* COMMENT */
1203
1204 /* SET MACRO parameters table */
1205 static
1206 struct keytab smactab[] = {
1207 "echo", 0, 0,
1208 "error", 1, 0
1209 };
1210 #endif /* NOSPL */
1211
1212 #ifndef NOSCRIPT
1213 static
1214 struct keytab scrtab[] = {
1215 "echo", 0, 0
1216 };
1217 #endif /* NOSCRIPT */
1218
1219 /* SET COMMAND table */
1220
1221 /* SET COMMAND items... */
1222
1223 #define SCMD_BSZ 0 /* BYTESIZE */
1224 #define SCMD_RCL 1 /* RECALL */
1225 #define SCMD_RTR 2 /* RETRY */
1226 #define SCMD_QUO 3 /* QUOTING */
1227 #define SCMD_COL 4 /* COLOR */
1228 #define SCMD_HIG 5 /* HEIGHT */
1229 #define SCMD_WID 6 /* WIDTH */
1230 #define SCMD_CUR 7 /* CURSOR-POSITION */
1231 #define SCMD_SCR 8 /* SCROLLBACK */
1232 #define SCMD_MOR 9 /* MORE-PROMPTING */
1233 #define SCMD_INT 10 /* INTERRUPTION */
1234 #define SCMD_ADL 11 /* AUTODOWNLOAD */
1235 #define SCMD_STA 12 /* STATUSLINE */
1236 #define SCMD_DBQ 13 /* DOUBLEQUOTING */
1237 #define SCMD_CBR 14 /* CBREAK */
1238 #define SCMD_BFL 15 /* BUFFER-SIZE (not used) */
1239 #define SCMD_ERR 16 /* ERROR */
1240 #define SCMD_VAR 17 /* VARIABLE-EVALUATION */
1241
1242 static struct keytab scmdtab[] = {
1243 #ifdef CK_AUTODL
1244 "autodownload", SCMD_ADL, 0,
1245 #endif /* CK_AUTODL */
1246 #ifdef COMMENT
1247 /*
1248 To implement this requires that we change CMDBL and ATMBL
1249 from compile-time symbols to runtime variables. Not a big deal,
1250 but not trivial either.
1251 */
1252 "buffer-size", SCMD_BFL, 0,
1253 #endif /* COMMENT */
1254 "bytesize", SCMD_BSZ, 0,
1255 "cbreak", SCMD_CBR, CM_INV,
1256 #ifdef OS2
1257 "color", SCMD_COL, 0,
1258 "cursor-position", SCMD_CUR, 0,
1259 #endif /* OS2 */
1260 #ifdef DOUBLEQUOTING
1261 "doublequoting", SCMD_DBQ, 0,
1262 #endif /* DOUBLEQUOTING */
1263 "error-display", SCMD_ERR, 0,
1264 "height", SCMD_HIG, 0,
1265 "interruption", SCMD_INT, 0,
1266 "more-prompting", SCMD_MOR, 0,
1267 "quoting", SCMD_QUO, 0,
1268 #ifdef CK_RECALL
1269 "recall-buffer-size", SCMD_RCL, 0,
1270 #endif /* CK_RECALL */
1271 #ifdef CK_RECALL
1272 "retry", SCMD_RTR, 0,
1273 #endif /* CK_RECALL */
1274 #ifdef OS2
1275 #ifdef ONETERMUPD
1276 "scrollback", SCMD_SCR, 0,
1277 "statusline", SCMD_STA, 0,
1278 #endif /* ONETERMUPD */
1279 #endif /* OS2 */
1280 "variable-evaluation", SCMD_VAR,0,
1281 "width", SCMD_WID, 0
1282 };
1283 static int nbytt = (sizeof(scmdtab) / sizeof(struct keytab));
1284
1285 #ifndef NOSERVER
1286 /* Server parameters table */
1287 static struct keytab srvtab[] = {
1288 "cd-message", XYSERC, 0,
1289 "display", XYSERD, 0,
1290 "get-path", XYSERP, 0,
1291 "idle-timeout", XYSERI, 0,
1292 "keepalive", XYSERK, 0,
1293 "login", XYSERL, 0,
1294 "timeout", XYSERT, 0
1295 };
1296 static int nsrvt = (sizeof(srvtab) / sizeof(struct keytab));
1297 #endif /* NOSERVER */
1298
1299 static struct keytab sleeptab[] = { /* SET SLEEP table */
1300 "cancellation", 0, 0
1301 };
1302
1303 static struct keytab tstab[] = { /* SET TRANSFER/XFER table */
1304 "bell", XYX_BEL, 0,
1305 #ifdef XFRCAN
1306 "cancellation", XYX_CAN, 0,
1307 #endif /* XFRCAN */
1308 #ifndef NOCSETS
1309 "character-set", XYX_CSE, 0,
1310 #endif /* NOCSETS */
1311 #ifndef NOSPL
1312 "crc-calculation", XYX_CRC, 0,
1313 #endif /* NOSPL */
1314 "display", XYX_DIS, 0,
1315 "interruption", XYX_INT, 0,
1316 "locking-shift", XYX_LSH, 0,
1317 "message", XYX_MSG, 0,
1318 "mode", XYX_MOD, 0,
1319 "msg", XYX_MSG, CM_INV,
1320 #ifdef PIPESEND
1321 "pipes", XYX_PIP, 0,
1322 #endif /* PIPESEND */
1323 #ifdef CK_XYZ
1324 "protocol", XYX_PRO, 0,
1325 #endif /* CK_XYZ */
1326 "report", XYX_RPT, 0,
1327 "slow-start", XYX_SLO, 0,
1328 #ifndef NOCSETS
1329 "translation", XYX_XLA, 0,
1330 #else
1331 "translation", XYX_XLA, CM_INV,
1332 #endif /* NOCSETS */
1333 "xlation", XYX_XLA, CM_INV,
1334 "", 0, 0
1335 };
1336 static int nts = (sizeof(tstab) / sizeof(struct keytab)) - 1;
1337
1338 static struct keytab rtstab[] = { /* REMOTE SET TRANSFER/XFER table */
1339 #ifndef NOCSETS
1340 "character-set", XYX_CSE, 0,
1341 #endif /* NOCSETS */
1342 "mode", XYX_MOD, 0
1343 };
1344 static int nrts = (sizeof(rtstab) / sizeof(struct keytab));
1345
1346 struct keytab xfrmtab[] = { /* TRANSFER MODE table */
1347 "automatic", XMODE_A, 0,
1348 "manual", XMODE_M, 0
1349 };
1350
1351 #ifdef LOCUS
1352 extern int locus, autolocus;
1353
1354 static struct keytab locustab[] = {
1355 #ifdef KUI
1356 { "ask", 3, 0 }, /* Presently implemented in GUI only */
1357 #endif /* KUI */
1358 { "auto", 2, 0 },
1359 { "local", 1, 0 },
1360 { "remote", 0, 0 }
1361 };
1362 static int nlocustab = (sizeof(locustab) / sizeof(struct keytab));
1363
1364 #endif /* LOCUS */
1365
1366 #ifndef NOCSETS
1367 /* SET TRANSFER CHARACTER-SET table */
1368
1369 extern struct keytab tcstab[];
1370 extern int ntcs;
1371 #endif /* NOCSETS */
1372
1373 /* SET TRANSFER LOCKING-SHIFT table */
1374 struct keytab lstab[] = {
1375 "forced", 2, 0,
1376 "off", 0, 0,
1377 "on", 1, 0
1378 };
1379 int nls = (sizeof(lstab) / sizeof(struct keytab));
1380
1381 /* SET TELNET tables */
1382 #ifdef TNCODE
1383 extern int tn_nlm, tn_b_nlm, tn_b_meu, tn_b_ume, tn_b_xfer, tn_sb_bug;
1384 extern int tn_no_encrypt_xfer, tn_auth_krb5_des_bug;
1385 extern int tn_wait_flg, tn_duplex, tn_delay_sb, tn_sfu;
1386 extern int sl_tn_saved;
1387 extern int tn_infinite;
1388 extern int tn_rem_echo;
1389 extern int tn_deb;
1390 extern int tn_auth_how;
1391 extern int tn_auth_enc;
1392 #ifdef CK_FORWARD_X
1393 extern char * tn_fwdx_xauthority;
1394 #endif /* CK_FORWARD_X */
1395 #ifdef CK_AUTHENTICATION
1396 static struct keytab setauth[] = {
1397 #ifdef CK_KERBEROS
1398 "k4", AUTH_KRB4, CM_INV,
1399 "k5", AUTH_KRB5, CM_INV,
1400 "kerberos4", AUTH_KRB4, 0,
1401 "kerberos5", AUTH_KRB5, 0,
1402 "kerberos_iv",AUTH_KRB4, CM_INV,
1403 "kerberos_v", AUTH_KRB5, CM_INV,
1404 "krb4", AUTH_KRB4, CM_INV,
1405 "krb5", AUTH_KRB5, CM_INV,
1406 #endif /* CK_KERBEROS */
1407 #ifdef CK_SRP
1408 "srp", AUTH_SRP, 0,
1409 #endif /* CK_SRP */
1410 #ifdef CK_SSL
1411 "ssl", AUTH_SSL, 0,
1412 "tls", AUTH_TLS, 0,
1413 #endif /* CK_SSL */
1414 "", 0, 0
1415 };
1416 static int nsetauth = sizeof(setauth)/sizeof(struct keytab) - 1;
1417 #ifdef CK_KERBEROS
1418 extern char * krb5_d_principal; /* Default principal */
1419 extern char * krb5_d_instance;
1420 extern char * krb5_d_realm; /* Default realm */
1421 extern char * krb5_d_cc; /* Default credentials cache */
1422 extern char * krb5_d_srv; /* Default service name */
1423 extern int krb5_d_lifetime; /* Default lifetime */
1424 extern int krb5_d_forwardable;
1425 extern int krb5_d_proxiable;
1426 extern int krb5_d_renewable;
1427 extern int krb5_autoget;
1428 extern int krb5_autodel;
1429 extern int krb5_d_getk4;
1430 extern int krb5_checkaddrs; /* Check TGT Addrs */
1431 extern int krb5_d_no_addresses;
1432 extern char * krb5_d_addrs[];
1433 extern char * k5_keytab; /* Keytab file */
1434
1435 extern struct krb4_init_data krb4_init;
1436 extern char * krb4_d_principal; /* Default principal */
1437 extern char * krb4_d_realm; /* Default realm */
1438 extern char * krb4_d_srv; /* Default service name */
1439 extern int krb4_d_lifetime; /* Default lifetime */
1440 extern int krb4_d_preauth;
1441 extern char * krb4_d_instance;
1442 extern int krb4_autoget;
1443 extern int krb4_autodel;
1444 extern int krb4_checkaddrs; /* Check TGT Addrs */
1445 extern char * k4_keytab; /* Keytab file */
1446 #ifdef KRB4
1447 extern int k4debug;
1448 #endif /* KRB4 */
1449 static struct keytab krbver[] = {
1450 "4", 4, 0,
1451 "5", 5, 0,
1452 "iv", 4, CM_INV,
1453 "v", 5, CM_INV
1454 };
1455 static int nkrbver = sizeof(krbver)/sizeof(struct keytab);
1456
1457 static struct keytab kdestab[] = {
1458 "never", KRB_DEL_NO, 0,
1459 "no", KRB_DEL_NO, CM_INV,
1460 "on-close", KRB_DEL_CL, 0,
1461 "on-exit", KRB_DEL_EX, 0
1462 };
1463 static int nkdestab = sizeof(kdestab)/sizeof(struct keytab);
1464
1465 static struct keytab k4tab[] = {
1466 "autodel", XYKRBDEL, CM_INV,
1467 "autodestroy", XYKRBDEL, 0,
1468 "autoget", XYKRBGET, 0,
1469 "check-address", XYKRBADR, 0,
1470 "debug", XYKRBDBG, CM_INV,
1471 "instance", XYKRBINS, 0,
1472 "keytab", XYKRBKTB, 0,
1473 "lifetime", XYKRBLIF, 0,
1474 "preauth", XYKRBPRE, 0,
1475 "principal", XYKRBPR, 0,
1476 "prompt", XYKRBPRM, 0,
1477 "realm", XYKRBRL, 0,
1478 "service-name", XYKRBSRV, 0
1479 };
1480 static int nk4tab = sizeof(k4tab)/sizeof(struct keytab);
1481
1482 static struct keytab k5tab[] = {
1483 "addresses", XYKRBADD, 0,
1484 "autodelete", XYKRBDEL, CM_INV,
1485 "autodestroy", XYKRBDEL, 0,
1486 "autoget", XYKRBGET, 0,
1487 "cc", XYKRBCC, CM_INV,
1488 "check-address", XYKRBADR, 0,
1489 "credentials-cache", XYKRBCC, 0,
1490 "forwardable", XYKRBFWD, 0,
1491 "get-k4-tgt", XYKRBK5K4,0,
1492 "instance", XYKRBINS, 0,
1493 "keytab", XYKRBKTB, 0,
1494 "lifetime", XYKRBLIF, 0,
1495 "no-addresses", XYKRBNAD, 0,
1496 "principal", XYKRBPR, 0,
1497 "prompt", XYKRBPRM, 0,
1498 "proxiable", XYKRBPRX, 0,
1499 "realm", XYKRBRL, 0,
1500 "renewable", XYKRBRNW, 0,
1501 "service-name", XYKRBSRV, 0
1502 };
1503 static int nk5tab = sizeof(k5tab)/sizeof(struct keytab);
1504
1505 #define KRB_PW_PRM 1
1506 #define KRB_PR_PRM 2
1507
1508 static struct keytab krbprmtab[] = {
1509 "password", KRB_PW_PRM, 0,
1510 "principal", KRB_PR_PRM, 0
1511 };
1512
1513 #endif /* CK_KERBEROS */
1514 #ifdef CK_SRP
1515 static struct keytab srptab[] = {
1516 "prompt", XYSRPPRM, 0
1517 };
1518 static int nsrptab = sizeof(srptab)/sizeof(struct keytab);
1519 #define SRP_PW_PRM 1
1520
1521 static struct keytab srpprmtab[] = {
1522 "password", SRP_PW_PRM, 0
1523 };
1524 #endif /* CK_SRP */
1525 #ifdef CK_SSL
1526 static struct keytab ssltab[] = {
1527 "certs-ok", XYSSLCOK, CM_INV,
1528 "cipher-list", XYSSLCL, 0,
1529 "crl-dir", XYSSLCRLD, 0,
1530 "crl-file", XYSSLCRL, 0,
1531 "debug", XYSSLDBG, 0,
1532 "dh-key-file", XYSSLDKFL, CM_INV,
1533 "dh-param-file", XYSSLDPFL, 0,
1534 "dsa-cert-chain-file", XYSSLDCCF, 0,
1535 "dsa-cert-file", XYSSLDCFL, 0,
1536 "dsa-key-file", XYSSLDKFL, 0,
1537 "dummy", XYSSLDUM, CM_INV,
1538 "only", XYSSLON, CM_INV,
1539 "random-file", XYSSLRND, 0,
1540 "rsa-cert-chain-file", XYSSLRCCF, 0,
1541 "rsa-cert-file", XYSSLRCFL, 0,
1542 "rsa-key-file", XYSSLRKFL, 0,
1543 "verbose", XYSSLVRB, 0,
1544 "verify", XYSSLVRF, 0,
1545 "verify-dir", XYSSLVRFD, 0,
1546 "verify-file", XYSSLVRFF, 0
1547 };
1548 static int nssltab = sizeof(ssltab)/sizeof(struct keytab);
1549 static struct keytab sslvertab[] = {
1550 "fail-if-no-peer-cert", SSL_VERIFY_PEER |
1551 SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0,
1552 "no", SSL_VERIFY_NONE, 0,
1553 "none", SSL_VERIFY_NONE, CM_INV,
1554 "off", SSL_VERIFY_NONE, CM_INV,
1555 "on", SSL_VERIFY_PEER, CM_INV,
1556 "peer-cert", SSL_VERIFY_PEER, 0
1557 };
1558 static int nsslvertab = sizeof(sslvertab)/sizeof(struct keytab);
1559 #endif /* CK_SSL */
1560 #endif /* CK_AUTHENTICATION */
1561 #ifdef CK_ENCRYPTION
1562 int cx_type = CX_AUTO;
1563 extern int sl_cx_type;
1564 #endif /* CK_ENCRYPTION */
1565 extern char *tcp_address;
1566 #ifndef NOHTTP
1567 extern char * tcp_http_proxy;
1568 extern char * tcp_http_proxy_user;
1569 extern char * tcp_http_proxy_pwd;
1570 extern char * tcp_http_proxy_agent;
1571 #endif /* NOHTTP */
1572 #ifdef NT
1573 #ifdef CK_SOCKS
1574 extern char *tcp_socks_svr;
1575 extern char *tcp_socks_user;
1576 #ifdef CK_SOCKS_NS
1577 extern char *tcp_socks_ns;
1578 #endif /* CK_SOCKS_NS */
1579 #endif /* CK_SOCKS */
1580 #endif /* NT */
1581
1582 #define UPW_USER 1
1583 #define UPW_PASS 2
1584 #define UPW_AGENT 3
1585
1586 static struct keytab userpass[] = {
1587 { "/agent", UPW_AGENT, CM_ARG },
1588 { "/password", UPW_PASS, CM_ARG },
1589 { "/user", UPW_USER, CM_ARG },
1590 };
1591 static int nuserpass = sizeof(userpass)/sizeof(struct keytab);
1592
1593 static struct keytab tnnegtab[] = { /* TELNET NEGOTIATION table */
1594 "accepted", TN_NG_AC, 0,
1595 "refused", TN_NG_RF, 0,
1596 "req", TN_NG_RQ, CM_INV|CM_ABR,
1597 "requ", TN_NG_RQ, CM_INV|CM_ABR,
1598 "reque", TN_NG_RQ, CM_INV|CM_ABR,
1599 "reques", TN_NG_RQ, CM_INV|CM_ABR,
1600 "request", TN_NG_RQ, CM_INV|CM_ABR,
1601 "requeste", TN_NG_RQ, CM_INV|CM_ABR,
1602 "requested", TN_NG_RQ, 0,
1603 "required", TN_NG_MU, 0
1604 };
1605 static int ntnnegtab = sizeof(tnnegtab)/sizeof(struct keytab);
1606
1607 #ifdef CK_ENCRYPTION
1608 static struct keytab typkwd[] = {
1609 "/type", 0, CM_ARG
1610 };
1611
1612 static struct keytab tnenctab[] = { /* TELNET ENCRYPTION table */
1613 "accepted", TN_NG_AC, CM_INV,
1614 "refused", TN_NG_RF, CM_INV,
1615 "req", TN_NG_RQ, CM_INV|CM_ABR,
1616 "requ", TN_NG_RQ, CM_INV|CM_ABR,
1617 "reque", TN_NG_RQ, CM_INV|CM_ABR,
1618 "reques", TN_NG_RQ, CM_INV|CM_ABR,
1619 "request", TN_NG_RQ, CM_INV|CM_ABR,
1620 "requeste", TN_NG_RQ, CM_INV|CM_ABR,
1621 "requested", TN_NG_RQ, CM_INV,
1622 "required", TN_NG_MU, CM_INV,
1623 "start", TN_EN_START, CM_INV,
1624 "stop", TN_EN_STOP, CM_INV,
1625 "type", TN_EN_TYP, 0
1626 };
1627 static int ntnenc = sizeof(tnenctab)/sizeof(struct keytab) ;
1628 #endif /* CK_ENCRYPTION */
1629
1630 #ifdef CK_FORWARD_X
1631 static struct keytab tnfwdxtab[] = { /* TELNET FORWARD-X table */
1632 "no-encryption", 1, CM_INV,
1633 "xauthority-file", 0, 0
1634 };
1635 static int ntnfwdx = sizeof(tnfwdxtab)/sizeof(struct keytab) ;
1636 #endif /* CK_FORWARD_X */
1637
1638 static struct keytab tnbugtab[] = { /* TELNET BUG table */
1639 "auth-krb5-des", 4, 0,
1640 "binary-me-means-u-too", 0, 0,
1641 "binary-u-means-me-too", 1, 0,
1642 "infinite-loop-check", 2, 0,
1643 "sb-implies-will-do", 3, 0
1644 };
1645
1646 #ifdef CK_ENVIRONMENT
1647 static struct keytab tnenvtab[] = { /* TELNET ENVIRONMENT table */
1648 "acct", TN_ENV_ACCT, 0,
1649 "display", TN_ENV_DISP, 0,
1650 "job", TN_ENV_JOB, 0,
1651 "location", TN_ENV_LOC, 0,
1652 "off", TN_ENV_OFF, CM_INV,
1653 "on", TN_ENV_ON, CM_INV,
1654 "printer", TN_ENV_PRNT, 0,
1655 "systemtype",TN_ENV_SYS, 0,
1656 "user", TN_ENV_USR, 0,
1657 "uservar", TN_ENV_UVAR, 0,
1658 "", 0, 0
1659 };
1660 static int ntnenv = sizeof(tnenvtab)/sizeof(struct keytab) - 1;
1661 #endif /* CK_ENVIRONMENT */
1662
1663 #ifdef CK_AUTHENTICATION
1664 static struct keytab tnauthtab[] = { /* TELNET AUTHENTICATION table */
1665 "accepted", TN_NG_AC, CM_INV,
1666 "encrypt-flag", TN_AU_ENC, 0,
1667 "forwarding", TN_AU_FWD, 0,
1668 "how-flag", TN_AU_HOW, 0,
1669 "refused", TN_NG_RF, CM_INV,
1670 "req", TN_NG_RQ, CM_INV|CM_ABR,
1671 "requ", TN_NG_RQ, CM_INV|CM_ABR,
1672 "reque", TN_NG_RQ, CM_INV|CM_ABR,
1673 "reques", TN_NG_RQ, CM_INV|CM_ABR,
1674 "request", TN_NG_RQ, CM_INV|CM_ABR,
1675 "requeste", TN_NG_RQ, CM_INV|CM_ABR,
1676 "requested", TN_NG_RQ, CM_INV,
1677 "required", TN_NG_MU, CM_INV,
1678 "type", TN_AU_TYP, 0
1679 };
1680 static int ntnauth = sizeof(tnauthtab)/sizeof(struct keytab) ;
1681
1682 struct keytab autyptab[] = { /* TELNET AUTHENTICATION TYPE table */
1683 "automatic", AUTH_AUTO, 0,
1684 #ifdef CK_KERBEROS
1685 "k4", AUTH_KRB4, CM_INV,
1686 "k5", AUTH_KRB5, CM_INV,
1687 "kerberos4", AUTH_KRB4, 0,
1688 "kerberos5", AUTH_KRB5, 0,
1689 "kerberos_iv",AUTH_KRB4, CM_INV,
1690 "kerberos_v", AUTH_KRB5, CM_INV,
1691 "krb4", AUTH_KRB4, CM_INV,
1692 "krb5", AUTH_KRB5, CM_INV,
1693 #endif /* CK_KERBEROS */
1694 "none", AUTH_NONE, 0,
1695 #ifdef NT
1696 "ntlm", AUTH_NTLM, 0,
1697 #endif /* NT */
1698 #ifdef CK_SRP
1699 "srp", AUTH_SRP, 0,
1700 #endif /* CK_SRP */
1701 #ifdef CK_SSL
1702 "ssl", AUTH_SSL, 0,
1703 #endif /* CK_SSL */
1704 "", 0, 0
1705 };
1706 int nautyp = sizeof(autyptab)/sizeof(struct keytab) - 1;
1707
1708 struct keytab auhowtab[] = { /* TELNET AUTHENTICATION HOW table */
1709 "any", TN_AUTH_HOW_ANY, 0,
1710 "mutual", TN_AUTH_HOW_MUTUAL, 0,
1711 "one-way", TN_AUTH_HOW_ONE_WAY, 0,
1712 "", 0, 0
1713 };
1714 int nauhow = sizeof(auhowtab)/sizeof(struct keytab) - 1;
1715
1716 struct keytab auenctab[] = { /* TELNET AUTHENTICATION ENCRYPT table */
1717 "any", TN_AUTH_ENC_ANY, 0,
1718 "none", TN_AUTH_ENC_NONE, 0,
1719 "telopt", TN_AUTH_ENC_TELOPT, 0,
1720 #ifdef CK_SSL
1721 "tls", TN_AUTH_ENC_TLS, 0,
1722 #endif /* CK_SSL */
1723 "", 0, 0
1724 };
1725 int nauenc = sizeof(auenctab)/sizeof(struct keytab) - 1;
1726 #endif /* CK_AUTHENTICATION */
1727
1728 #define TN_NL_BIN 3
1729 #define TN_NL_NVT 4
1730 static struct keytab tn_nlmtab[] = { /* TELNET NEWLINE-MODE table */
1731 "binary-mode", TN_NL_BIN, 0, /* Binary mode */
1732 "nvt", TN_NL_NVT, 0, /* NVT mode */
1733 "off", TNL_CRNUL, CM_INV, /* CR-NUL (TELNET spec) */
1734 "on", TNL_CRLF, CM_INV, /* CR-LF (TELNET spec) */
1735 "raw", TNL_CR, CM_INV /* CR only (out of spec) */
1736 };
1737 static int ntn_nlm = (sizeof(tn_nlmtab) / sizeof(struct keytab));
1738
1739 static struct keytab tnlmtab[] = { /* TELNET NEWLINE-MODE table */
1740 "cr", TNL_CR, CM_INV, /* CR only (out of spec) */
1741 "cr-lf", TNL_CRLF, CM_INV, /* CR-LF (TELNET spec) */
1742 "cr-nul", TNL_CRNUL, CM_INV, /* CR-NUL (TELNET spec) */
1743 "lf", TNL_LF, CM_INV, /* LF instead of CR-LF */
1744 "off", TNL_CRNUL, 0, /* CR-NUL (TELNET spec) */
1745 "on", TNL_CRLF, 0, /* CR-LF (TELNET spec) */
1746 "raw", TNL_CR, 0 /* CR only (out of spec) */
1747 };
1748 static int ntnlm = (sizeof(tnlmtab) / sizeof(struct keytab));
1749
1750 struct keytab tntab[] = {
1751 #ifdef CK_AUTHENTICATION
1752 "authentication", CK_TN_AU, 0,
1753 #endif /* CK_AUTHENTICATION */
1754 "b", CK_TN_BM, CM_INV|CM_ABR,
1755 "bi", CK_TN_BM, CM_INV|CM_ABR,
1756 "bin", CK_TN_BM, CM_INV|CM_ABR,
1757 "bina", CK_TN_BM, CM_INV|CM_ABR,
1758 "binar", CK_TN_BM, CM_INV|CM_ABR,
1759 "binary", CK_TN_BM, CM_INV|CM_ABR,
1760 "binary-", CK_TN_BM, CM_INV|CM_ABR,
1761 "binary-mode", CK_TN_BM, CM_INV,
1762 "binary-transfer-mode", CK_TN_XF, 0,
1763 "binary-xfer-mode", CK_TN_XF, CM_INV,
1764 "bug", CK_TN_BUG, 0,
1765 "debug", CK_TN_DB, 0,
1766 "delay-sb", CK_TN_DL, 0,
1767 "echo", CK_TN_EC, 0,
1768 #ifdef CK_ENCRYPTION
1769 "encryption", CK_TN_ENC, 0,
1770 #endif /* CK_ENCRYPTION */
1771 #ifdef CK_ENVIRONMENT
1772 "environment", CK_TN_ENV, 0,
1773 #endif /* CK_ENVIRONMENT */
1774 #ifdef CK_FORWARD_X
1775 "forward-x", CK_TN_FX, 0,
1776 #endif /* CK_FORWARD_X */
1777 #ifdef IKS_OPTION
1778 "kermit", CK_TN_IKS, CM_INV,
1779 #endif /* IKS_OPTION */
1780 #ifdef CK_SNDLOC
1781 "location", CK_TN_LOC, 0,
1782 #endif /* CK_SNDLOC */
1783 #ifdef CK_NAWS
1784 "naws", CK_TN_NAWS, CM_INV,
1785 #endif /* CK_NAWS */
1786 "newline-mode", CK_TN_NL, 0,
1787 "no-encrypt-during-xfer", CK_TN_NE, CM_INV,
1788 "prompt-for-userid",CK_TN_PUID,0,
1789 "remote-echo", CK_TN_RE, 0,
1790 #ifdef CK_SSL
1791 "start-tls", CK_TN_TLS, CM_INV,
1792 #endif /* CK_SSL */
1793 #ifdef NT
1794 "sfu-compatibility", CK_TN_SFU, 0,
1795 #else
1796 "sfu-compatibility", CK_TN_SFU, CM_INV,
1797 #endif /* NT */
1798 "terminal-type", CK_TN_TT, 0,
1799 "wait-for-negotiations", CK_TN_WAIT, 0,
1800 #ifdef CK_ENVIRONMENT
1801 "xdisplay-location",CK_TN_XD, CM_INV,
1802 #endif /* CK_ENVIRONMENT */
1803 "", 0, 0
1804 };
1805 int ntn = (sizeof(tntab) / sizeof(struct keytab)) - 1;
1806
1807 struct keytab tnopttab[] = {
1808 #ifdef CK_AUTHENTICATION
1809 "authentication", CK_TN_AU, 0,
1810 #else
1811 "authentication", CK_TN_AU, CM_INV,
1812 #endif /* CK_AUTHENTICATION */
1813 "binary-mode", CK_TN_BM, 0,
1814 #ifdef TN_COMPORT
1815 "c", CK_TN_CPC, CM_INV|CM_ABR,
1816 "co", CK_TN_CPC, CM_INV|CM_ABR,
1817 "com", CK_TN_CPC, CM_INV|CM_ABR,
1818 "com-port-control",CK_TN_CPC, 0,
1819 "comport-control", CK_TN_CPC, CM_INV,
1820 #else /* TN_COMPORT */
1821 "com-port-control",CK_TN_CPC, CM_INV,
1822 "comport-control", CK_TN_CPC, CM_INV,
1823 #endif /* TN_COMPORT */
1824 "echo", CK_TN_EC, 0,
1825 #ifdef CK_ENCRYPTION
1826 "encryption", CK_TN_ENC, 0,
1827 #else
1828 "encryption", CK_TN_ENC, CM_INV,
1829 #endif /* CK_ENCRYPTION */
1830 #ifdef CK_FORWARD_X
1831 "forward-x", CK_TN_FX, 0,
1832 #else /* CK_FORWARD_X */
1833 "forward-x", CK_TN_FX, CM_INV,
1834 #endif /* CK_FORWARD_X */
1835 "ibm-sak", CK_TN_SAK, CM_INV,
1836 #ifdef IKS_OPTION
1837 "kermit", CK_TN_IKS, 0,
1838 #else
1839 "kermit", CK_TN_IKS, CM_INV,
1840 #endif /* IKS_OPTION */
1841 "lflow", CK_TN_FLW, CM_INV,
1842 "logout", CK_TN_LOG, 0,
1843 #ifdef CK_NAWS
1844 "naws", CK_TN_NAWS, 0,
1845 #else
1846 "naws", CK_TN_NAWS, CM_INV,
1847 #endif /* CK_NAWS */
1848 #ifdef CK_ENVIRONMENT
1849 "new-environment", CK_TN_ENV, 0,
1850 #else
1851 "new-environment", CK_TN_ENV, CM_INV,
1852 #endif /* CK_ENVIRONMENT */
1853 "pragma-heartbeat",CK_TN_PHR, CM_INV,
1854 "pragma-logon", CK_TN_PLG, CM_INV,
1855 "pragma-sspi", CK_TN_PSP, CM_INV,
1856 "sak", CK_TN_SAK, CM_INV,
1857 #ifdef CK_SNDLOC
1858 "send-location", CK_TN_LOC, 0,
1859 #else
1860 "send-location", CK_TN_LOC, CM_INV,
1861 #endif /* CK_SNDLOC */
1862 "sga", CK_TN_SGA, CM_INV|CM_ABR,
1863 #ifdef CK_SSL
1864 "start-tls", CK_TN_TLS, 0,
1865 #else
1866 "start-tls", CK_TN_TLS, CM_INV,
1867 #endif /* CK_SSL */
1868 "suppress-go-aheads", CK_TN_SGA, 0,
1869 "terminal-type", CK_TN_TT, 0,
1870 "ttype", CK_TN_TT, CM_INV|CM_ABR,
1871 #ifdef CK_ENVIRONMENT
1872 "xdisplay-location", CK_TN_XD, 0,
1873 #else
1874 "xdisplay-location", CK_TN_XD, CM_INV,
1875 #endif /* CK_ENVIRONMENT */
1876 "", 0, 0
1877 };
1878 int ntnopt = (sizeof(tnopttab) / sizeof(struct keytab)) - 1;
1879
1880 struct keytab tnoptsw[] = {
1881 "/client", CK_TN_CLIENT, 0,
1882 "/server", CK_TN_SERVER, 0
1883 };
1884 int ntnoptsw = (sizeof(tnoptsw) / sizeof(struct keytab));
1885 #endif /* TNCODE */
1886
1887 struct keytab ftrtab[] = { /* Feature table */
1888 #ifndef NOCSETS /* 0 = we have it, 1 = we don't */
1889 "character-sets", 0, 0,
1890 #else
1891 "character-sets", 1, 0,
1892 #endif /* NOCSETS */
1893 #ifndef NOCYRIL
1894 "cyrillic", 0, 0,
1895 #else
1896 "cyrillic", 1, 0,
1897 #endif /* NOCYRIL */
1898
1899 #ifndef NOLOGDIAL
1900 "cx-log", 0, 0,
1901 #else
1902 "cx-log", 1, 0,
1903 #endif /* NOLOGDIAL */
1904
1905 #ifndef NODEBUG
1906 "debug", 0, 0,
1907 #else
1908 "debug", 1, 0,
1909 #endif /* NODEBUG */
1910
1911 #ifndef NODIAL
1912 "dial", 0, 0,
1913 #else
1914 "dial", 1, 0,
1915 #endif /* NODIAL */
1916
1917 #ifdef DYNAMIC
1918 "dynamic-memory", 0, 0,
1919 #else
1920 "dynamic-memory", 1, 0,
1921 #endif /* DYNAMIC */
1922
1923 #ifndef NOXFER
1924 "file-transfer", 0, 0,
1925 #else
1926 "file-transfer", 1, 0,
1927 #endif /* NOXFER */
1928
1929 #ifdef XXFWD
1930 "forward", 0, 0,
1931 #else
1932 "forward", 1, 0,
1933 #endif /* XXFWD */
1934
1935 #ifdef NEWFTP
1936 "ftp", 0, 0,
1937 #else
1938 "ftp", 1, 0,
1939 #endif /* NEWFTP */
1940
1941 #ifdef CK_CURSES
1942 "fullscreen-display", 0, 0,
1943 #else
1944 "fullscreen-display", 1, 0,
1945 #endif /* CK_CURSES */
1946 #ifdef GREEK
1947 "greek", 0, 0,
1948 #else
1949 "greek", 1, 0,
1950 #endif /* GREEK */
1951 #ifdef HEBREW
1952 "hebrew", 0, 0,
1953 #else
1954 "hebrew", 1, 0,
1955 #endif /* HEBREW */
1956 #ifndef NOHELP
1957 "help", 0, 0,
1958 #else
1959 "help", 1, 0,
1960 #endif /* NOHELP */
1961
1962 #ifndef NOIKSD
1963 "iksd", 0, 0,
1964 #else
1965 "iksd", 1, 0,
1966 #endif /* NOIKSD */
1967
1968 #ifndef NOSPL
1969 "if-command", 0, 0,
1970 #else
1971 "if-command", 1, 0,
1972 #endif /* NOSPL */
1973 #ifndef NOJC
1974 #ifdef UNIX
1975 "job-control", 0, 0,
1976 #else
1977 "job-control", 1, 0,
1978 #endif /* UNIX */
1979 #else
1980 "job-control", 1, 0,
1981 #endif /* NOJC */
1982 #ifdef KANJI
1983 "kanji", 0, 0,
1984 #else
1985 "kanji", 1, 0,
1986 #endif /* KANJI */
1987
1988 #ifndef NOXFER
1989 "kermit", 0, 0,
1990 #else
1991 "kermit", 1, 0,
1992 #endif /* NOXFER */
1993
1994 #ifdef CK_KERBEROS
1995 "kerberos", 0, 0,
1996 #else
1997 "kerberos", 1, 0,
1998 #endif /* CK_KERBEROS */
1999
2000 #ifndef NOCSETS
2001 "latin1", 0, 0,
2002 #else
2003 "latin1", 1, 0,
2004 #endif /* NOCSETS */
2005 #ifdef LATIN2
2006 "latin2", 0, 0,
2007 #else
2008 "latin2", 1, 0,
2009 #endif /* LATIN2 */
2010
2011 #ifdef CKLEARN
2012 "learned-scripts", 0, 0,
2013 #else
2014 "learned-scripts", 1, 0,
2015 #endif /* CKLEARN */
2016
2017 #ifdef HAVE_LOCALE
2018 "locale", 0, 0,
2019 #else
2020 "locale", 1, 0,
2021 #endif /* HAVE_LOCALE */
2022
2023 #ifndef NOLOCAL
2024 "making-connections", 0, 0,
2025 #else
2026 "making-connections", 1, 0,
2027 #endif /* NOLOCAL */
2028
2029 #ifdef NETCONN
2030 "network", 0, 0,
2031 #else
2032 "network", 1, 0,
2033 #endif /* NETCONN */
2034
2035 #ifdef NT
2036 #ifdef CK_AUTHENTICATION
2037 "ntlm", 1, 0,
2038 #else /* CK_AUTHENTICATION */
2039 "ntlm", 0, 0,
2040 #endif /* CK_AUTHENTICATION */
2041 #else /* NT */
2042 "ntlm", 0, 0,
2043 #endif /* NT */
2044
2045 #ifdef PIPESEND
2046 "pipes", 0, 0,
2047 #else
2048 #ifdef NETCMD
2049 "pipes", 0, 0,
2050 #endif /* NETCMD */
2051 #endif /* PIPESEND */
2052 #ifndef PIPESEND
2053 #ifndef NETCMD
2054 "pipes", 1, 0,
2055 #endif /* PIPESEND */
2056 #endif /* NETCMD */
2057
2058 #ifdef NETPTY
2059 "pty", 0, 0,
2060 #else
2061 "pty", 1, 0,
2062 #endif /* NETPTY */
2063
2064 #ifndef NOPUSH
2065 "push", 0, 0,
2066 #else
2067 "push", 1, 0,
2068 #endif /* PUSH */
2069
2070 #ifdef CK_REDIR
2071 "redirect", 0, 0,
2072 #else
2073 "redirect", 1, 0,
2074 #endif /* CK_REDIR */
2075
2076 #ifdef CK_RTSCTS
2077 "rts/cts", 0, 0,
2078 #else
2079 "rts/cts", 1, 0,
2080 #endif /* RTS/CTS */
2081
2082 #ifndef NOSCRIPT
2083 "script-command", 0, 0,
2084 #else
2085 "script-command", 1, 0,
2086 #endif /* NOSCRIPT */
2087 #ifndef NOSERVER
2088 "server-mode", 0, 0,
2089 #else
2090 "server-mode", 1, 0,
2091 #endif /* NOSERVER */
2092
2093 #ifndef NOSEXP
2094 "sexpression", 0, 0,
2095 #else
2096 "sexpression", 1, 0,
2097 #endif /* NOSEXP */
2098
2099 #ifdef SFTP_BUILTIN
2100 "sftp", 1, 0,
2101 #else
2102 "sftp", 0, 0,
2103 #endif /* SFTP_BUILTIN */
2104
2105 #ifndef NOSHOW
2106 "show-command", 0, 0,
2107 #else
2108 "show-command", 1, 0,
2109 #endif /* NOSHOW */
2110
2111 #ifdef CK_SRP
2112 "srp", 0, 0,
2113 #else
2114 "srp", 1, 0,
2115 #endif /* CK_SRP */
2116
2117 #ifdef SSHBUILTIN
2118 "ssh", 0, 0,
2119 #else /* SSHBUILTIN */
2120 "ssh", 1, 0,
2121 #endif /* SSHBUILTIN */
2122
2123 #ifdef CK_SSL
2124 "ssl/tls", 0, 0,
2125 #else
2126 "ssl/tls", 1, 0,
2127 #endif /* CK_SSL */
2128
2129 #ifndef NOXMIT
2130 "transmit", 0, 0,
2131 #else
2132 "transmit", 1, 0,
2133 #endif /* NOXMIT */
2134
2135 #ifdef UNICODE
2136 "unicode", 0, 0,
2137 #else
2138 "unicode", 1, 0,
2139 #endif /* UNICODE */
2140
2141 #ifdef CK_XYZ
2142 "xyzmodem", 0, 0,
2143 #else
2144 "xyzmodem", 1, 0,
2145 #endif /* CK_XYZ */
2146
2147 "", 0, 0
2148 };
2149 int nftr = (sizeof(ftrtab) / sizeof(struct keytab)) - 1;
2150
2151 struct keytab desttab[] = { /* SET DESTINATION */
2152 #ifdef CALIBRATE
2153 "calibrate", DEST_N, CM_INV,
2154 #endif /* CALIBRATE */
2155 "disk", DEST_D, 0,
2156 #ifdef CALIBRATE
2157 "nowhere", DEST_N, 0,
2158 #endif /* CALIBRATE */
2159 "printer", DEST_P, 0,
2160 "screen", DEST_S, 0
2161 };
2162 int ndests = (sizeof(desttab) / sizeof(struct keytab));
2163
2164 #ifndef NOSPL /* Used only with script programming items... */
2165
2166 #ifndef NOSERVER /* This is just to avoid some */
2167 #define CK_PARSDIR /* "statement not reached" */
2168 #else /* complaints... */
2169 #ifndef NODIAL
2170 #define CK_PARSDIR
2171 #endif /* NODIAL */
2172 #endif /* NOSERVER */
2173
2174 /*
2175 cx == 0 means dial directory
2176 cx == 1 means network directory
2177 cx == 2 means a directory path list
2178 */
2179 static int
parsdir(cx)2180 parsdir(cx) int cx; {
2181 int i, x, y, dd; /* Workers */
2182 int nxdir;
2183 char *s;
2184 char ** xdir;
2185 char *pp[MAXGETPATH]; /* Temporary name pointers */
2186 #ifdef ZFNQFP
2187 struct zfnfp * fnp;
2188 #ifdef OS2
2189 char * env;
2190 char dirpath[4096];
2191 #else /* OS2 */
2192 char dirpath[1024]; /* For fully qualified filenames */
2193 #endif /* OS2 */
2194 #endif /* ZFNQFP */
2195
2196 int max = 0; /* Maximum number of things to parse */
2197 char c;
2198
2199 #ifndef NODIAL
2200 if (cx == 0) { /* Dialing */
2201 nxdir = ndialdir;
2202 xdir = dialdir;
2203 max = MAXDDIR;
2204 } else
2205 #ifdef NETCONN
2206 if (cx == 1) { /* Network */
2207 nxdir = nnetdir;
2208 xdir = netdir;
2209 max = MAXDDIR;
2210 } else
2211 #endif /* NETCONN */
2212 #endif /* NODIAL */
2213 #ifndef NOSERVER
2214 if (cx == 2) { /* GET path */
2215 nxdir = ngetpath;
2216 xdir = getpath;
2217 max = MAXGETPATH;
2218 } else /* Called with invalid function code */
2219 #endif /* NOSERVER */
2220 return(-2);
2221
2222 for (i = 0; i < MAXGETPATH; i++) /* Init these. */
2223 pp[i] = NULL;
2224
2225 #ifdef CK_PARSDIR
2226 dd = 0; /* Temporary name counter */
2227 while (1) {
2228 if (cx != 2) { /* Dialing or Network Directory */
2229 #ifdef OS2
2230 int len;
2231 char * appdata0 = NULL, * appdata1 = NULL;
2232 #ifdef NT
2233 env = getenv("K95PHONES");
2234 makestr(&appdata0,(char *)GetAppData(0));
2235 makestr(&appdata1,(char *)GetAppData(1));
2236 #else /* NT */
2237 env = getenv("K2PHONES");
2238 #endif /* NT */
2239 if (!env)
2240 env = getenv("K95PHONES");
2241 if (!env)
2242 env = "";
2243
2244 dirpath[0] = '\0';
2245 len = strlen(env) + 2*strlen(startupdir) + 2*strlen(inidir)
2246 + (appdata0?2*strlen(appdata0):0)
2247 + (appdata1?2*strlen(appdata1):0)
2248 + 2*strlen(zhome()) + 2*strlen(exedir) + 8*strlen("PHONES/")
2249 + 12;
2250 if (len < 4096) /* SAFE */
2251 sprintf(dirpath,
2252 "%s%s%s;%s%s;%s%s%s%s%s%s%s%s%s;%s%s;%s;%s%s",
2253 /* Semicolon-separated path list */
2254 env,
2255 (env[0] && env[strlen(env)-1] == ';') ? "" : ";",
2256 startupdir,
2257 startupdir, "PHONES/",
2258 appdata1 ? appdata1 : "",
2259 appdata1 ? "Kermit 95;" : "",
2260 appdata1 ? appdata1 : "",
2261 appdata1 ? "Kermit 95/PHONES/;" : "",
2262 appdata0 ? appdata0 : "",
2263 appdata0 ? "Kermit 95;" : "",
2264 appdata0 ? appdata0 : "",
2265 appdata0 ? "Kermit 95/PHONES/;" : "",
2266 inidir,
2267 inidir, "PHONES/",
2268 zhome(),
2269 zhome(), "PHONES/",
2270 exedir,
2271 exedir, "PHONES/"
2272 );
2273 #ifdef NT
2274 makestr(&appdata0,NULL);
2275 makestr(&appdata1,NULL);
2276 #endif /* NT */
2277 #else
2278 #ifdef UNIX
2279 y = 1024;
2280 s = dirpath;
2281 zzstring("\\v(home)",&s,&y);
2282 #endif /* UNIX */
2283 #endif /* OS2 */
2284 y = cmifip(
2285 "Names of one or more directory files, separated by spaces",
2286 "",&s,&x,0,
2287 #ifdef OS2ORUNIX
2288 dirpath,
2289 #else
2290 NULL,
2291 #endif /* OS2ORUNIX */
2292 xxstring
2293 );
2294 } else { /* List of directory names */
2295 x = 0;
2296 y = cmdir("Directory name","",&s,xxstring);
2297 }
2298 if (y < 0) {
2299 if (y == -3) { /* EOL or user typed <CR> */
2300 if ((y = cmcfm()) < 0) return(y);
2301 for (i = 0; i < max; i++) { /* Clear these */
2302 if (i < nxdir && xdir[i]) {
2303 free(xdir[i]);
2304 }
2305 xdir[i] = (i < dd) ? pp[i] : NULL;
2306 }
2307 #ifndef NODIAL
2308 if (cx == 0)
2309 ndialdir = dd;
2310 #ifdef NETCONN
2311 if (cx == 1)
2312 nnetdir = dd;
2313 #endif /* NETCONN */
2314 #endif /* NODIAL */
2315 #ifndef NOSERVER
2316 if (cx == 2)
2317 ngetpath = dd;
2318 #endif /* NOSERVER */
2319 return(success = 1);
2320
2321 } else { /* Parse error */
2322 for (i = 0; i < dd; i++) { /* Free temp storage */
2323 if (pp[i]) free(pp[i]); /* but don't change */
2324 pp[i] = NULL; /* anything else */
2325 }
2326 return(y);
2327 }
2328 }
2329 if (x) {
2330 printf("?Wildcards not allowed\n");
2331 return(-9);
2332 }
2333 #ifdef CK_TMPDIR
2334 if (cx == 2 && !isdir(s)) {
2335 printf("?Not a directory - %s\n", s);
2336 return(-9);
2337 }
2338 #endif /* CK_TMPDIR */
2339
2340 #ifdef ZFNQFP
2341 if (cx < 2) {
2342 if (!isabsolute(s)) { /* If not relative get full path */
2343 if ((fnp = zfnqfp(s,TMPBUFSIZ - 1,tmpbuf))) {
2344 if (fnp->fpath)
2345 if ((int) strlen(fnp->fpath) > 0)
2346 s = fnp->fpath;
2347 }
2348 }
2349 }
2350 #endif /* ZFNQFP */
2351 c = NUL;
2352 x = strlen(s);
2353 if (x > 0) /* Get last char */
2354 c = s[x-1];
2355 debug(F000,"parsdir s",s,c);
2356 if ((pp[dd] = malloc(strlen(s)+2)) == NULL) {
2357 printf("?Internal error - malloc\n");
2358 for (i = 0; i < dd; i++) { /* Free temp storage */
2359 if (pp[i]) free(pp[i]);
2360 pp[i] = NULL;
2361 }
2362 return(-9);
2363 } else { /* Have storage for name */
2364 strcpy(pp[dd],s); /* Copy string into new storage */
2365 debug(F111,"parsdir pp[dd] 1",pp[dd],dd);
2366 #ifndef NOXFER
2367 if (cx == 2) { /* If we are parsing directories */
2368 char dirsep[2];
2369 extern int myindex; /* Append directory separator if */
2370 extern struct sysdata sysidlist[]; /* it is missing... */
2371 debug(F101,"parsdir myindex","",myindex);
2372 if (myindex > -1)
2373 if (sysidlist[myindex].sid_unixlike)
2374 if (c != sysidlist[myindex].sid_dirsep) {
2375 dirsep[0] = sysidlist[myindex].sid_dirsep;
2376 dirsep[1] = NUL;
2377 strcat(pp[dd], (char *) dirsep); /* safe */
2378 }
2379 }
2380 #endif /* NOXFER */
2381 debug(F111,"parsdir pp[dd] 2",pp[dd],dd);
2382 if (++dd > max) {
2383 printf("?Too many directories - %d max\n", max);
2384 for (i = 0; i < dd; i++) { /* Free temp storage */
2385 if (pp[i]) free(pp[i]);
2386 pp[i] = NULL;
2387 }
2388 }
2389 }
2390 }
2391 #endif /* CK_PARSDIR */
2392 }
2393 #endif /* NOSPL */
2394
2395 #ifndef NOSERVER
2396 static int
cklogin()2397 cklogin() {
2398 int x;
2399 char * s;
2400 char username[LOGINLEN+1];
2401 char password[LOGINLEN+1];
2402 char account[LOGINLEN+1];
2403 extern char * x_user, * x_passwd, * x_acct;
2404 extern int x_login, x_logged;
2405
2406 username[0] = NUL;
2407 password[0] = NUL;
2408 account[0] = NUL;
2409
2410 x = cmfld("username", "", &s, xxstring);
2411 if (x != -3) {
2412 if (x < 0)
2413 return(x);
2414 if ((int)strlen(s) > LOGINLEN) {
2415 printf("\"%s\" - too long, %d max\n", s, LOGINLEN);
2416 return(-9);
2417 }
2418 ckstrncpy(username,s,LOGINLEN+1);
2419 x = cmfld("password", "", &s, xxstring);
2420 if (x != -3) {
2421 if (x < 0)
2422 return(x);
2423 if ((int)strlen(s) > LOGINLEN) {
2424 printf("\"%s\" - too long, %d max\n", s, LOGINLEN);
2425 return(-9);
2426 }
2427 ckstrncpy(password,s,LOGINLEN+1);
2428 x = cmfld("account", "", &s, xxstring);
2429 if (x != -3) {
2430 if (x < 0)
2431 return(x);
2432 if ((int)strlen(s) > LOGINLEN) {
2433 printf("\"%s\" - too long, %d max\n", s, LOGINLEN);
2434 return(-9);
2435 }
2436 ckstrncpy(account,s,LOGINLEN+1);
2437 if ((x = cmcfm()) < 0)
2438 return(x);
2439 }
2440 }
2441 }
2442 makestr(&x_user,username);
2443 makestr(&x_passwd,password);
2444 makestr(&x_acct,account);
2445 x_login = (x_user) ? 1 : 0;
2446 x_logged = 0;
2447 return(1);
2448 }
2449 #endif /* NOSERVER */
2450
2451 #ifndef NOLOCAL
2452 static int
setdcd()2453 setdcd() {
2454 int x, y, z = 0;
2455 if ((y = cmkey(crrtab,ncrr,"","automatic",xxstring)) < 0) return(y);
2456 if (y == CAR_ON) {
2457 x = cmnum("Carrier wait timeout, seconds","0",10,&z,xxstring);
2458 if (x < 0) return(x);
2459 }
2460 if ((x = cmcfm()) < 0) return(x);
2461 carrier = ttscarr(y);
2462 cdtimo = z;
2463 return(1);
2464 }
2465 #endif /* NOLOCAL */
2466
2467 extern struct keytab yesno[];
2468 extern int nyesno;
2469
2470 /* g e t y e s n o */
2471
2472 static struct keytab q0yesno[] = { /* Yes/No/Quit keyword table */
2473 "no", 0, 0,
2474 "ok", 1, 0,
2475 "yes", 1, 0
2476 };
2477 static int nq0yesno = (sizeof(q0yesno) / sizeof(struct keytab));
2478
2479 static struct keytab q1yesno[] = { /* Yes/No/Quit keyword table */
2480 "no", 0, 0,
2481 "ok", 1, 0,
2482 "quit", 2, 0,
2483 "yes", 1, 0
2484 };
2485 static int nq1yesno = (sizeof(q1yesno) / sizeof(struct keytab));
2486
2487 static struct keytab q2yesno[] = { /* Yes/No/Quit keyword table */
2488 "go", 3, 0,
2489 "no", 0, 0,
2490 "ok", 1, 0,
2491 "yes", 1, 0
2492 };
2493 static int nq2yesno = (sizeof(q2yesno) / sizeof(struct keytab));
2494
2495 static struct keytab q3yesno[] = { /* Yes/No/Quit keyword table */
2496 "go", 3, 0,
2497 "no", 0, 0,
2498 "ok", 1, 0,
2499 "quit", 2, 0,
2500 "yes", 1, 0
2501 };
2502 static int nq3yesno = (sizeof(q3yesno) / sizeof(struct keytab));
2503
2504
2505 /* Ask question, get yes/no answer */
2506
2507 int
getyesno(msg,flags)2508 getyesno(msg, flags) char * msg; int flags; {
2509 #ifdef CK_RECALL
2510 extern int on_recall; /* around Password prompting */
2511 #endif /* CK_RECALL */
2512 int y, z;
2513
2514 #ifndef NOLOCAL
2515 #ifdef OS2
2516 extern BYTE vmode;
2517 extern int win95_popup, startflags;
2518 int vmode_sav = vmode;
2519 #endif /* OS2 */
2520 #endif /* NOLOCAL */
2521
2522 #ifdef CK_APC
2523 if ( apcactive != APC_INACTIVE && (apcstatus & APC_NOINP) ) {
2524 return(success = 0);
2525 }
2526 #endif /* CK_APC */
2527
2528 #ifndef NOLOCAL
2529 #ifdef OS2
2530 #ifdef COMMENT
2531 if (win95_popup && !(startflags & 96)
2532 #ifdef IKSD
2533 && !inserver
2534 #endif /* IKSD */
2535 )
2536 return(popup_readyesno(vmode,NULL,msg,flags));
2537 #endif /* COMMENT */
2538 if (vmode == VTERM) {
2539 vmode = VCMD;
2540 VscrnIsDirty(VTERM);
2541 VscrnIsDirty(VCMD);
2542 }
2543 #endif /* OS2 */
2544 #endif /* NOLOCAL */
2545 #ifdef VMS
2546 /*
2547 In VMS, whenever a TAKE file or macro is active, we restore the
2548 original console modes so Ctrl-C/Ctrl-Y can work. But here we
2549 go interactive again, so we have to temporarily put them back.
2550 */
2551 if (!xcmdsrc)
2552 concb((char)escape);
2553 #endif /* VMS */
2554
2555 #ifdef CK_RECALL
2556 on_recall = 0;
2557 #endif /* CK_RECALL */
2558 cmsavp(psave,PROMPTL); /* Save old prompt */
2559 cmsetp(msg); /* Make new prompt */
2560 z = 0; /* Initialize answer to No. */
2561 cmini(ckxech); /* Initialize parser. */
2562 do {
2563 prompt(NULL); /* Issue prompt. */
2564 switch (flags) {
2565 case 0: y = cmkey(q0yesno,nq0yesno,"","",NULL); break;
2566 case 1: y = cmkey(q1yesno,nq1yesno,"","",NULL); break;
2567 case 2: y = cmkey(q2yesno,nq2yesno,"","",NULL); break;
2568 default: y = cmkey(q3yesno,nq3yesno,"","",NULL);
2569 }
2570 if (y < 0) {
2571 if (y == -4) { /* EOF */
2572 z = y;
2573 break;
2574 } else if (y == -3) /* No answer? */
2575 printf(" Please respond; type '?' to see valid answers.\n");
2576 cmini(ckxech);
2577 } else {
2578 z = y; /* Save answer */
2579 y = cmcfm(); /* Get confirmation */
2580 }
2581 } while (y < 0); /* Continue till done */
2582 cmsetp(psave); /* Restore real prompt */
2583 #ifdef VMS
2584 if (cmdlvl > 0) /* In VMS and not at top level, */
2585 conres(); /* restore console again. */
2586 #endif /* VMS */
2587 #ifndef NOLOCAL
2588 #ifdef OS2
2589 if (vmode != vmode_sav) {
2590 vmode = VTERM;
2591 VscrnIsDirty(VCMD);
2592 VscrnIsDirty(VTERM);
2593 }
2594 #endif /* OS2 */
2595 #endif /* NOLOCAL */
2596 return(z);
2597 }
2598
2599 #ifdef KUI
2600 extern HWND hwndConsole;
2601 _PROTOTYP(int gui_txt_dialog,(char *,char *,int,char *,int,char *,int));
2602 _PROTOTYP(int gui_mtxt_dialog,(char *,int,struct txtbox []));
2603 _PROTOTYP(int gui_position,(int, int));
2604 _PROTOTYP(int gui_resize_mode,(int));
2605 _PROTOTYP(int gui_win_run_mode,(int));
2606 _PROTOTYP(int gui_saveas_dialog,(char *,char *, int, char *, char *, int));
2607 extern int gui_dialog;
2608 #endif /* KUI */
2609
2610 /* u q _ o k -- User Query, get Yes/No or OK Cancel */
2611 /*
2612 Call with:
2613 preface: Explanatory text to print, or NULL.
2614 prompt: Prompt.
2615 mask: Bitmask for legal responses: 1 = OK or Yes; 2 = No or Cancel.
2616 help: Help text (array of strings or NULL) [not used by parser].
2617 dflt: Default response (1 or 2) [not used by parser].
2618 Returns:
2619 -1: Invalid argument(s).
2620 0: User said No or Cancel.
2621 1 User said Yes or OK.
2622 Notes:
2623 preface and prompt should not include final line terminator but may
2624 include embedded ones. Help text is in case GUI dialog needs a Help
2625 button; final element of help-string array is "". dflt is used by GUI
2626 to highlight the default response button.
2627 */
2628 int
2629 #ifdef CK_ANSIC
uq_ok(char * preface,char * prompt,int mask,char ** help,int dflt)2630 uq_ok(char * preface, char * prompt, int mask,char ** help, int dflt)
2631 #else /* CK_ANSIC */
2632 uq_ok(preface,prompt,mask,help,dflt)
2633 char * preface, * prompt, ** help;
2634 int mask, dflt;
2635 #endif /* CK_ANSIC */
2636 /* uq_ok */ {
2637 int rc, len;
2638 char * text=NULL;
2639
2640 if (!prompt)
2641 return(-1);
2642
2643 if ((mask & 3) == 1) { /* OK (GUI only) */
2644 #ifdef KUI
2645 if ( gui_dialog ) {
2646 /* This one is for popup help, alerts, etc */
2647 if (preface) {
2648 len = strlen(preface) + strlen(prompt) + 4;
2649 text = (char *)malloc(len);
2650 ckmakmsg(text,len,preface,"\n",prompt,NULL);
2651 }
2652 rc = MessageBox(hwndConsole,
2653 text ? text : prompt,
2654 prompt,
2655 MB_OK | MB_ICONINFORMATION | MB_TASKMODAL);
2656 ShowWindowAsync(hwndConsole,SW_SHOWNORMAL);
2657 SetForegroundWindow(hwndConsole);
2658 if (text)
2659 free(text);
2660 if (!rc)
2661 return(-1);
2662 else
2663 return(1);
2664 } else
2665 #endif /* KUI */
2666 {
2667 if (preface) /* Just display the text, if any */
2668 printf("%s\n",preface);
2669 if (prompt)
2670 printf("%s\n",prompt);
2671 return(1);
2672 }
2673 } else if ((mask & 3) == 3) { /* Yes/No or OK/Cancel */
2674 #ifdef KUI
2675 if ( gui_dialog ) {
2676 if (preface) {
2677 len = strlen(preface) + strlen(prompt) + 4;
2678 text = (char *)malloc(len);
2679 ckmakmsg(text,len,preface,"\n",prompt,NULL);
2680 }
2681 rc = MessageBox(hwndConsole,
2682 text ? text : prompt,
2683 prompt,
2684 MB_YESNO | MB_ICONINFORMATION | MB_TASKMODAL |
2685 (dflt == 2 ? MB_DEFBUTTON2 : MB_DEFBUTTON1));
2686 ShowWindowAsync(hwndConsole,SW_SHOWNORMAL);
2687 SetForegroundWindow(hwndConsole);
2688 if (text)
2689 free(text);
2690 if (!rc)
2691 return(-1);
2692 else if (rc == IDNO || rc == IDCANCEL)
2693 return(0);
2694 else
2695 return(1);
2696 } else
2697 #endif /* KUI */
2698 {
2699 if (preface)
2700 printf("%s\n",preface);
2701 return(getyesno(prompt,0));
2702 }
2703 } else {
2704 printf("?Internal error: uq_ok()\n");
2705 return(-1);
2706 }
2707 }
2708
2709 /* u q _ t x t -- User Query, get single text response */
2710 /*
2711 Call with:
2712 preface: Explanatory text to print, or NULL.
2713 prompt: Prompt.
2714 echo: 0 = don't echo; 1 = echo; 2 = echo with asterisks.
2715 help: Help text (array of strings or NULL) [not used by parser].
2716 buf: Pointer to result buffer.
2717 buflen: Length of result buffer.
2718 dflt: Default response text or NULL [not used by parser].
2719 timer: Optional Timeout
2720 Returns:
2721 0: User said No or Cancel.
2722 1 User said Yes or OK.
2723 Notes:
2724 preface, prompt, and help as for uq_ok().
2725 */
2726 int
2727 #ifdef CK_ANSIC
uq_txt(char * preface,char * prompt,int echo,char ** help,char * buf,int buflen,char * dflt,int timer)2728 uq_txt(char * preface, char * prompt, int echo, char ** help, char * buf,
2729 int buflen, char *dflt, int timer)
2730 #else /* CK_ANSIC */
2731 uq_txt(preface,prompt,echo,help,buf,buflen,dflt,timer)
2732 char * preface, * prompt, ** help, * buf, * dflt;
2733 int buflen, echo, timer;
2734 #endif /* CK_ANSIC */
2735 {
2736 #ifndef NOLOCAL
2737 #ifdef OS2
2738 extern BYTE vmode;
2739 extern int startflags;
2740 extern int win95_popup;
2741 #endif /* OS2 */
2742 #endif /* NOLOCAL */
2743 int rc;
2744
2745 if (buflen < 1 || !buf)
2746 return(0);
2747 #ifdef KUI
2748 if ( gui_dialog ) {
2749 rc = gui_txt_dialog(preface,prompt,echo,buf,buflen,dflt,timer);
2750 if ( rc > -1 )
2751 return(rc);
2752 /* Otherwise, the dialog could not be created. Fallback to text mode */
2753 }
2754 #endif /* KUI */
2755 #ifndef NOLOCAL
2756 #ifdef OS2
2757 if (win95_popup && !(startflags & 96)
2758 #ifdef IKSD
2759 && !inserver
2760 #endif /* IKSD */
2761 ) {
2762 debok = 0; /* Don't log */
2763 if (echo == 1)
2764 popup_readtext(vmode,preface,prompt,buf,buflen,0);
2765 else
2766 popup_readpass(vmode,preface,prompt,buf,buflen,0);
2767 debok = 1;
2768 return(1);
2769 }
2770 #endif /* OS2 */
2771 #endif /* NOLOCAL */
2772
2773 if (preface)
2774 printf("%s\n",preface);
2775 if (echo == 1)
2776 readtext(prompt,buf,buflen);
2777 else
2778 readpass(prompt,buf,buflen);
2779 return(1); /* (no buttons in parser) */
2780 }
2781
2782 /* u q _ m t x t -- User Query, get multiple text responses */
2783 /*
2784 Call with:
2785 preface: Explanatory text to print, or NULL.
2786 help: Help text (array of strings or NULL) [not used by parser].
2787 n: Number of responses wanted.
2788 field: Array of struct txtbox, one element per field, see ckuusr.h.
2789 Returns:
2790 0: User said No or Cancel.
2791 1 User said Yes or OK.
2792 Notes:
2793 preface and help as for uq_ok().
2794 */
2795 int
2796 #ifdef CK_ANSIC
uq_mtxt(char * preface,char ** help,int n,struct txtbox field[])2797 uq_mtxt(char * preface,char **help, int n, struct txtbox field[])
2798 #else /* CK_ANSIC */
2799 uq_mtxt(preface,help,n,field)
2800 char * preface; char ** help; int n; struct txtbox field[];
2801 #endif /* CK_ANSIC */
2802 {
2803 #ifndef NOLOCAL
2804 #ifdef OS2
2805 extern BYTE vmode;
2806 extern int startflags;
2807 extern int win95_popup;
2808 #endif /* OS2 */
2809 #endif /* NOLOCAL */
2810 int i, rc;
2811
2812 if (n < 1 || !field)
2813 return(0);
2814 #ifdef KUI
2815 if ( gui_dialog ) {
2816 rc = gui_mtxt_dialog(preface, n, field);
2817 if ( rc > -1 )
2818 return(rc);
2819 /* Otherwise, the dialog could not be created. Fallback to text mode */
2820 }
2821 #endif /* KUI */
2822 #ifndef NOLOCAL
2823 #ifdef OS2
2824 if (win95_popup && !(startflags & 96)
2825 #ifdef IKSD
2826 && !inserver
2827 #endif /* IKSD */
2828 ) {
2829 debok = 0; /* Don't log */
2830 for (i = 0; i < n; i++) {
2831 if (field[i].t_echo == 1)
2832 popup_readtext(vmode,preface,field[i].t_lbl,field[i].t_buf,field[i].t_len,0);
2833 else
2834 popup_readpass(vmode,preface,field[i].t_lbl,field[i].t_buf,field[i].t_len,0);
2835 }
2836 debok = 1;
2837 return(1);
2838 }
2839 #endif /* OS2 */
2840 #endif /* NOLOCAL */
2841
2842 if (preface)
2843 printf("%s\n",preface);
2844 for (i = 0; i < n; i++) {
2845 if (field[i].t_echo == 1)
2846 readtext(field[i].t_lbl,field[i].t_buf,field[i].t_len);
2847 else
2848 readpass(field[i].t_lbl,field[i].t_buf,field[i].t_len);
2849 }
2850 return(1);
2851 }
2852
2853 /* u q _ f i l e -- User Query, get file or directory name */
2854 /*
2855 Call with:
2856 preface: Explanatory text to print, or NULL.
2857 prompt: Prompt string.
2858 fc: Function code:
2859 1 = input (existing) file
2860 2 = existing directory
2861 3 = create new output file
2862 4 = output file allowing append access
2863 help: Help text (array of strings or NULL) [not used by parser].
2864 dflt: Default response.
2865 result: Pointer to result buffer.
2866 rlength: Length of result buffer.
2867
2868 Returns:
2869 -1: Invalid argument, result too long, or other error.
2870 0: User Canceled.
2871 1: OK, with file/pathname copied to result buffer.
2872 2: Like 1, but for output file that is to be appended to.
2873
2874 Notes:
2875 1. preface and prompt should not include final line terminator but may
2876 include embedded ones. Help text is in case GUI dialog needs a Help
2877 button; final element of help-string array is "".
2878
2879 2. The default might be a filename, a directory name, a relative
2880 pathname, or an absolute pathname. This routine must convert it into
2881 into a fully qualified (absolute) pathname so the user knows exactly
2882 where the file is to be found or stored. In addition, the Windows
2883 version of this routine must separate the directory part from the
2884 name part, so it can display the given directory in the file dialog,
2885 and put name in the filename box to be edited, replaced, or
2886 accepted.
2887
2888 3. When called with FC 4, the Windows version should include "New" and
2889 "Append" buttons in the dialog. so the user can say whether the file
2890 should overwrite any file of the same name, or be appended to it.
2891 */
2892
2893 int
2894 #ifdef CK_ANSIC
uq_file(char * preface,char * fprompt,int fc,char ** help,char * dflt,char * result,int rlength)2895 uq_file(char * preface, char * fprompt, int fc, char ** help,
2896 char * dflt, char * result, int rlength)
2897 #else /* CK_ANSIC */
2898 uq_file(preface,fprompt,fc,help,dflt,result,rlength)
2899 char * preface, * fprompt, ** help, * dflt, * result;
2900 int fc, rlength;
2901 #endif /* CK_ANSIC */
2902 /* uq_file */ {
2903
2904 int rc = -1, x, y, z;
2905 char * s, * p, * fullpath;
2906 char filebuf[CKMAXPATH+1];
2907
2908 #ifdef CK_RECALL
2909 extern int on_recall;
2910 #endif /* CK_RECALL */
2911
2912 #ifdef KUI
2913 if ( gui_dialog ) {
2914 rc = gui_saveas_dialog(preface,fprompt,fc,dflt,result,rlength);
2915 return rc;
2916 }
2917 #endif /* KUI */
2918
2919 #ifdef CK_RECALL
2920 on_recall = 0;
2921 #endif /* CK_RECALL */
2922
2923 if (preface) /* If prefatory text given... */
2924 printf("%s\n",preface); /* display it. */
2925
2926 cmsavp(psave,PROMPTL); /* Save old prompt */
2927
2928 /* We get the full pathname of the proposed output file just so */
2929 /* we can show it to the user but we don't use it ourselves. */
2930
2931 p = NULL; /* Build new prompt */
2932 if (!dflt) dflt = "";
2933 if (*dflt) /* Have default filename */
2934 zfnqfp(dflt,CKMAXPATH+1,filebuf); /* Get full path */
2935 else
2936 ckmakmsg(filebuf,CKMAXPATH+1,zgtdir(),"newfile",NULL,NULL);
2937 fullpath = filebuf;
2938 x = strlen(fullpath);
2939
2940 /* If no prompt given, build one that shows the proposed full pathname. */
2941
2942 if (!fprompt) fprompt = "";
2943 if (!*fprompt) fprompt = x ? " Filename" : " Filename: ";
2944 y = strlen(fprompt);
2945 if (x > 0) { /* Have default pathname? */
2946 p = (char *)malloc(x + y + 7); /* Get temp storage */
2947 if (p) { /* Build prompt */
2948 ckmakmsg(p,x+y+7,fprompt," [",fullpath,"]: ");
2949 fprompt = p;
2950 }
2951 }
2952 cmsetp(fprompt); /* Make new prompt */
2953 if (p) free(p); /* Free temp storage */
2954 cmini(ckxech); /* Initialize parser. */
2955 x = -1;
2956 do {
2957 prompt(NULL); /* Issue prompt. */
2958 switch (fc) { /* Parse depends on function code */
2959 case 1: /* Input file */
2960 x = cmifi("Name of existing file",dflt,&s,&y,xxstring);
2961 rc = 1;
2962 break;
2963 case 2: /* Directory */
2964 x = cmdir("Directory name",dflt,&s,xxstring);
2965 rc = 1;
2966 break;
2967 case 3: /* New output file */
2968 /* Fall thru... */
2969 case 4: /* Output file - Append allowed */
2970 x = cmofi("Output file specification",dflt,&s,xxstring);
2971 rc = (fc == 4) ? 1 : 2;
2972 break;
2973 default: /* Bad function code */
2974 goto x_uq_file;
2975 }
2976 if (x < 0) { /* Parse error */
2977 filebuf[0] = NUL;
2978 if (x == -4) { /* EOF */
2979 break;
2980 } else if (x == -3) /* No answer? */
2981 printf(fc == 2 ?
2982 " Please enter a directory name.\n" :
2983 " Please enter a filename.\n"
2984 );
2985 cmini(ckxech);
2986 } else {
2987 z = strlen(s);
2988 if (z > rlength || ckstrncpy(filebuf,brstrip(s),CKMAXPATH+1) < z) {
2989 printf("?Name too long\n");
2990 x = -9;
2991 } else
2992 x = cmcfm(); /* Get confirmation */
2993 }
2994 if (fc == 1 && x > -1 && y > 0) {
2995 printf("?Wildcards not allowed\n");
2996 x = -9;
2997 }
2998 } while (x < 0); /* Continue till done */
2999
3000 x_uq_file:
3001 if (x < 0)
3002 rc = -1;
3003
3004 cmsetp(psave); /* Restore real prompt */
3005
3006 if (rc > 0)
3007 ckstrncpy(result,filebuf,rlength);
3008 return(rc);
3009 }
3010
3011
3012 #ifdef CK_PERMS
3013 #ifdef UNIX
3014
3015 _PROTOTYP( int zsetperm, (char *, int));
3016
3017 /* CHMOD command for UNIX only */
3018
3019 #define CHM_DIR 0
3020 #define CHM_DOT 1
3021 #define CHM_FIL 2
3022 #define CHM_LIS 3
3023 #define CHM_NOL 4
3024 #define CHM_QUI 5
3025 #define CHM_REC 6
3026 #define CHM_VRB 7
3027 #define CHM_PAG 8
3028 #define CHM_NOP 9
3029 #define CHM_TYP 10
3030 #define CHM_SIM 11
3031
3032 static struct keytab uchmodsw[] = {
3033 "/directories", CHM_DIR, 0,
3034 "/dotfiles", CHM_DOT, 0,
3035 "/files", CHM_FIL, 0,
3036 "/list", CHM_LIS, 0,
3037 "/nolist", CHM_NOL, 0,
3038 "/nopage", CHM_NOP, 0,
3039 "/page", CHM_PAG, 0,
3040 "/quiet", CHM_QUI, CM_INV,
3041 "/recursive", CHM_REC, 0,
3042 "/simulate", CHM_SIM, 0,
3043 "/type", CHM_TYP, CM_ARG,
3044 "/verbose", CHM_VRB, CM_INV,
3045 };
3046 static int nchmodsw = (sizeof(uchmodsw) / sizeof(struct keytab));
3047
3048 int
douchmod()3049 douchmod() {
3050 extern int recursive, nscanfile, diractive;
3051 #ifdef CK_TTGWSIZ
3052 extern int tt_rows, tt_cols;
3053 int n = 0;
3054 #endif /* CK_TTGWSIZ */
3055 int i, files = 1, t1 = 1, t2 = 0, x, y, z, verbose = 0, rc = 1, paging;
3056 int xmode = -1, fs = 0, getval = 0, simulate = 0, wild = 0;
3057 char c, * s;
3058 struct FDB sw, nu;
3059
3060 if (xaskmore < 0) {
3061 #ifdef CK_TTGWSIZ
3062 xaskmore = 1;
3063 #else
3064 xaskmore = 0;
3065 #endif /* CK_TTGWSIZ */
3066 }
3067 paging = xaskmore;
3068
3069 cmfdbi(&sw, /* First FDB - command switches */
3070 _CMKEY, /* fcode */
3071 "Octal file permission code, or switch",
3072 "", /* default */
3073 "", /* addtl string data */
3074 nchmodsw, /* addtl numeric data 1: tbl size */
3075 4, /* addtl numeric data 2: 4 = cmswi */
3076 xxstring, /* Processing function */
3077 uchmodsw, /* Keyword table */
3078 &nu /* Pointer to next FDB */
3079 );
3080 cmfdbi(&nu,
3081 _CMNUM, /* Number */
3082 "", /* Help message */
3083 "", /* Default */
3084 "", /* N/A */
3085 8, /* Radix = 8 */
3086 0, /* N/A */
3087 xxstring, /* Processing function */
3088 NULL, /* N/A */
3089 NULL /* Next */
3090 );
3091
3092 while (1) {
3093 if ((x = cmfdb(&sw)) < 0) {
3094 if (x == -3) {
3095 x = -9;
3096 printf("?Filename required\n");
3097 }
3098 return(x);
3099 }
3100 if (cmresult.fcode != _CMKEY)
3101 break;
3102 c = cmgbrk();
3103 getval = (c == ':' || c == '=');
3104 if (getval && !(cmgkwflgs() & CM_ARG)) {
3105 printf("?This switch does not take an argument\n");
3106 return(-9);
3107 }
3108 if (!getval && (cmgkwflgs() & CM_ARG)) {
3109 printf("?This switch requires an argument\n");
3110 return(-9);
3111 }
3112 switch (cmresult.nresult) {
3113 case CHM_DIR:
3114 t1 = 1;
3115 t2 = 1;
3116 break;
3117 case CHM_DOT:
3118 matchdot = 1;
3119 break;
3120 case CHM_FIL:
3121 t1 = 0;
3122 t2 = 0;
3123 break;
3124 case CHM_LIS:
3125 case CHM_VRB:
3126 verbose = 1;
3127 break;
3128 case CHM_NOL:
3129 case CHM_QUI:
3130 verbose = 0;
3131 break;
3132 case CHM_REC:
3133 recursive = 1;
3134 break;
3135 case CHM_PAG:
3136 verbose = 1;
3137 paging = 1;
3138 break;
3139 case CHM_NOP:
3140 paging = 0;
3141 break;
3142 case CHM_SIM:
3143 simulate = 1;
3144 break;
3145 case CHM_TYP: {
3146 extern struct keytab txtbin[];
3147 if ((x = cmkey(txtbin,3,"","",xxstring)) < 0)
3148 return(x);
3149 if (x == 2) { /* ALL */
3150 xmode = -1;
3151 } else { /* TEXT or BINARY only */
3152 xmode = x;
3153 fs = 1;
3154 }
3155 break;
3156 }
3157 }
3158 }
3159 z = cmresult.nresult;
3160 x = cmifi2("File specification","",&s,&wild,t1,NULL,xxstring,t2);
3161 if (x < 0) {
3162 if (x == -3) {
3163 printf("?A file specification is required\n");
3164 return(-9);
3165 } else
3166 return(x);
3167 }
3168 ckstrncpy(tmpbuf,s,TMPBUFSIZ);
3169 s = tmpbuf;
3170 if ((x = cmcfm()) < 0)
3171 return(x);
3172 #ifdef ZXREWIND
3173 if (wild) files = zxrewind();
3174 #else
3175 if (wild) files = nzxpand(s,0);
3176 #endif /* ZXREWIND */
3177
3178 if (paging > -1)
3179 xaskmore = paging;
3180
3181 #ifdef CK_TTGWSIZ
3182 if (verbose && paging) {
3183 #ifdef OS2
3184 ttgcwsz();
3185 #else /* OS2 */
3186 if (ttgwsiz() > 0) {
3187 if (tt_rows > 0 && tt_cols > 0) {
3188 cmd_rows = tt_rows;
3189 cmd_cols = tt_cols;
3190 }
3191 }
3192 #endif /* OS2 */
3193 }
3194 #endif /* CK_TTGWSIZ */
3195
3196 for (i = 0; i < files; i++) {
3197 if (files == 1 && wild == 0) { /* For "chmod 777 ." */
3198 ckstrncpy(line,s,LINBUFSIZ);
3199 } else {
3200 x = znext(line);
3201 if (x < 1) {
3202 if (i == 0) {
3203 printf("?No files match - \"%s\"\n",line);
3204 return(-9);
3205 }
3206 return(1);
3207 }
3208 }
3209 if (fs) {
3210 #ifdef VMSORUNIX
3211 /* If /TYPE:TEXT or BINARY given, skip directories and links */
3212 /* since they are neither text nor binary. */
3213 extern int zgfs_dir, zgfs_link;
3214 zgetfs(line);
3215 if (zgfs_dir || zgfs_link)
3216 continue;
3217 #else
3218 if (zchki(line) < 0)
3219 continue;
3220 #endif /* VMSORUNIX */
3221 /* Regular file, scan it */
3222 switch (scanfile(line,&y,nscanfile)) {
3223 case FT_BIN:
3224 if (xmode != 1)
3225 continue;
3226 break;
3227 case FT_TEXT:
3228 case FT_7BIT:
3229 case FT_8BIT:
3230 #ifdef UNICODE
3231 case FT_UTF8:
3232 case FT_UCS2:
3233 #endif /* UNICODE */
3234 if (xmode != 0)
3235 continue;
3236 }
3237 }
3238 if (simulate) {
3239 #ifdef UNIX
3240 extern int zchkod; /* Unidentified Flying */
3241 int xx = zchkod; /* API Extension... */
3242 zchkod = 1;
3243 #endif /* UNIX */
3244 if (zchko(line) < 0)
3245 printf("%s - Access denied\n",line);
3246 else
3247 printf("%s - OK\n",line);
3248 #ifdef UNIX
3249 zchkod = xx;
3250 #endif /* UNIX */
3251 } else {
3252 if (zsetperm(line,z) < 1) {
3253 if (verbose || files < 2) {
3254 printf("%s: %s\n",line,ck_errstr());
3255 }
3256 rc = 0;
3257 } else if (verbose) {
3258 printf("%s %s\n",ziperm(line),line);
3259 }
3260 }
3261 #ifdef CK_TTGWSIZ
3262 if (verbose && paging) { /* Pause at end of screen */
3263 if (cmd_rows > 0 && cmd_cols > 0) {
3264 if (++n > cmd_rows - 3) {
3265 if (!askmore())
3266 break;
3267 else
3268 n = 0;
3269 }
3270 }
3271 }
3272 #endif /* CK_TTGWSIZ */
3273
3274 }
3275 return(success = rc);
3276 }
3277 #endif /* UNIX */
3278 #endif /* CK_PERMS */
3279
3280 #ifndef NOSPL /* S-Expressions */
3281 #ifndef NOSEXP
3282
3283 struct keytab sexptab[] = {
3284 "depth-limit", 1, 0,
3285 "echo-result", 0, 0,
3286 "truncate-all-results", 2
3287 };
3288
3289 static int sexpmaxdep = 1000; /* Maximum depth */
3290
3291 #define xxfloat(s,x) \
3292 ((isdigit(*s)||(*s=='-')||(*s=='+')||(*s=='.')||(*s=='\040'))?isfloat(s,x):0)
3293
3294 #define SX_ADD 1 /* Symbols for built-in operators */
3295 #define SX_SUB 2
3296 #define SX_MUL 3
3297 #define SX_DIV 4
3298 #define SX_POW 5
3299 #define SX_SET 6
3300 #define SX_MOD 7
3301 #define SX_EVA 8
3302 #define SX_EXP 9
3303 #define SX_AEQ 10
3304 #define SX_ALT 11
3305 #define SX_AGT 12
3306 #define SX_ALE 13
3307 #define SX_AGE 14
3308 #define SX_MIN 15
3309 #define SX_MAX 16
3310 #define SX_SQR 17
3311 #define SX_FLR 18
3312 #define SX_CEI 19
3313 #define SX_TRU 20
3314 #define SX_ABS 21
3315 #define SX_ROU 22
3316 #define SX_LET 23
3317 #define SX_LGN 24
3318 #define SX_LGX 25
3319 #define SX_FLO 26
3320 #define SX_IFC 27
3321 #define SX_NOT 28
3322 #define SX_NEQ 29
3323 #define SX_AND 30
3324 #define SX_LOR 31
3325 #define SX_SIN 32
3326 #define SX_COS 33
3327 #define SX_TAN 34
3328 #define SX_BWA 35
3329 #define SX_BWO 36
3330 #define SX_BWX 37
3331 #define SX_BWN 38
3332 #define SX_XOR 39
3333 #define SX_INC 40
3334 #define SX_DEC 41
3335 #define SX_QUO 42
3336 #define SX_STR 43
3337 #define SX_ECH 44
3338 #define SX_UNQ 45
3339
3340 /* Operator flags */
3341
3342 #define SXF_PRE 256 /* Predicate */
3343 #define SXF_ONE 512 /* Requires one arg */
3344 #define SXF_TWO 1024 /* Requires two args or more */
3345 #define SXF_FLO 2048 /* Coerce to floating-point */
3346
3347 /* Built-in constants */
3348
3349 #define SXC_NIL 1 /* NIL */
3350 #define SXC_PI 2 /* PI */
3351 #define SXC_T 3 /* T */
3352
3353 /*
3354 This is an xlookup() table and so need not be in "alhabetical" order.
3355 Therefore entries are arranged to minimize search for most common
3356 operators.
3357 */
3358 static struct keytab sexpops[] = { /* Built-in operators */
3359 "setq", SX_SET, 0, /* Global assignment */
3360 "+", SX_ADD, 0, /* Simple arithmetic */
3361 "-", SX_SUB, 0,
3362 "*", SX_MUL, 0,
3363 "/", SX_DIV, SXF_TWO,
3364 "^", SX_POW, SXF_TWO,
3365
3366 "if", SX_IFC, SXF_TWO, /* IF */
3367 "let", SX_LET, 0, /* Local assignment */
3368 "not", SX_NOT, SXF_ONE, /* NOT */
3369 "mod", SX_MOD, SXF_TWO, /* Modulus */
3370
3371 "<", SX_ALT, SXF_PRE, /* Comparisons */
3372 ">", SX_AGT, SXF_PRE,
3373 "<=", SX_ALE, SXF_PRE,
3374 "=", SX_AEQ, SXF_PRE,
3375 ">=", SX_AGE, SXF_PRE,
3376 "!=", SX_NEQ, SXF_PRE,
3377
3378 "++", SX_INC, SXF_ONE|SXF_TWO, /* Increment */
3379 "--", SX_DEC, SXF_ONE|SXF_TWO, /* Decrement */
3380
3381 "**", SX_POW, SXF_TWO, /* Common synonyms */
3382 "==", SX_AEQ, SXF_PRE,
3383 "!", SX_NOT, SXF_ONE,
3384 ".", SX_EVA, 0,
3385
3386 "and", SX_AND, 0, /* Logical operators */
3387 "or", SX_LOR, 0,
3388 "xor", SX_XOR, SXF_TWO,
3389
3390 "max", SX_MAX, SXF_ONE|SXF_TWO, /* Max and min */
3391 "min", SX_MIN, SXF_ONE|SXF_TWO,
3392
3393 "%", SX_MOD, SXF_TWO, /* More synonyms */
3394 "||", SX_LOR, 0,
3395 "&&", SX_AND, 0,
3396
3397 "quote", SX_QUO, SXF_ONE, /* String operators */
3398 "string", SX_STR, SXF_ONE,
3399 "unquote", SX_UNQ, SXF_ONE,
3400
3401 "eval", SX_EVA, 0, /* Assorted commands */
3402 "abs", SX_ABS, SXF_ONE,
3403 "truncate",SX_TRU, SXF_ONE|SXF_FLO,
3404 "round", SX_ROU, SXF_ONE|SXF_TWO|SXF_FLO,
3405 "ceiling", SX_CEI, SXF_ONE|SXF_FLO,
3406 "floor", SX_FLR, SXF_ONE|SXF_FLO,
3407 "float", SX_FLO, SXF_ONE|SXF_FLO,
3408 "echo", SX_ECH, 0,
3409
3410 #ifdef FNFLOAT
3411 "sqrt", SX_SQR, SXF_ONE|SXF_FLO, /* Floating point functions */
3412 "exp", SX_EXP, SXF_ONE|SXF_FLO,
3413 "sin", SX_SIN, SXF_ONE|SXF_FLO,
3414 "cos", SX_COS, SXF_ONE|SXF_FLO,
3415 "tan", SX_TAN, SXF_ONE|SXF_FLO,
3416 "log", SX_LGN, SXF_ONE|SXF_FLO,
3417 "log10", SX_LGX, SXF_ONE|SXF_FLO,
3418 #endif /* FNFLOAT */
3419
3420 "#", SX_BWX, SXF_TWO, /* Bitwise operators */
3421 "&", SX_BWA, 0,
3422 "|", SX_BWO, 0,
3423 "~", SX_BWN, SXF_ONE,
3424 "", 0, 0 /* (end) */
3425 };
3426 static int nsexpops = (sizeof(sexpops) / sizeof(struct keytab)) - 1;
3427
3428 static struct keytab sexpconsts[] = { /* Built-in constants */
3429 "nil", SXC_NIL, 0, /* NIL (false) */
3430 "pi", SXC_PI, 0, /* Pi (3.1415926...) */
3431 "t", SXC_T, 0, /* T (true) */
3432 "", 0, 0
3433 };
3434 static int nsexpconsts = (sizeof(sexpconsts) / sizeof(struct keytab)) - 1;
3435
3436 int sexprc = 0; /* S-Expression error flag */
3437 int sexppv = -1; /* Predicate value */
3438 static int sexptrunc = 0; /* Flag to force all results to int */
3439
3440 #define SXMLEN 64 /* Macro arg list initial length */
3441 #include <math.h> /* Floating-point functions */
3442
3443 _PROTOTYP( char * fpformat, (CKFLOAT, int, int) );
3444 _PROTOTYP( CKFLOAT ckround, (CKFLOAT, int, char *, int) );
3445
3446 extern char math_pi[]; /* Value of Pi */
3447 extern int sexpecho; /* SET SEXPRESSION ECHO value */
3448 extern char * sexpval; /* Last top-level S-Expression value */
3449 extern char * lastsexp; /* Last S-Expression */
3450 int sexprmax = 0; /* Longest result (for stats) */
3451 int sexpdmax = 0; /* Max depth reached (for stats) */
3452 int sexpdep = 0; /* dosexp() recursion depth */
3453 static int * sxrlen = NULL; /* Result stack string sizes */
3454 static char ** sxresult = NULL; /* Result stack */
3455
3456 /* s h o s e x p -- Show S-Expression info */
3457
3458 VOID
shosexp()3459 shosexp() {
3460 printf("\n");
3461 printf(" sexpression echo-result: %s\n",showooa(sexpecho));
3462 printf(" sexpression depth-limit: %d\n",sexpmaxdep);
3463 printf("\n");
3464 printf(" maximum depth reached: %d\n",sexpdmax);
3465 printf(" longest result returned: %d\n",sexprmax);
3466 printf("\n");
3467 printf(" truncate all results: %s\n",showoff(sexptrunc));
3468 printf("\n");
3469 printf(" last sexpression: %s\n",lastsexp ? lastsexp : "(none)");
3470 printf(" last value: %s\n",sexpval ? sexpval : "(none)");
3471 printf("\n");
3472 }
3473
3474
3475 static char *
sexpdebug(s)3476 sexpdebug(s) char * s; {
3477 /* For debugging -- includes recursion depth in each debug entry */
3478 static char buf[64];
3479 ckmakmsg(buf,64,"dosexp[",ckitoa(sexpdep),"] ",s);
3480 return((char *)buf);
3481 }
3482
3483 /* d o s e x p -- S-Expression Reader */
3484
3485 /* Returns value as string (empty, numeric, or non-numeric) */
3486
3487 static char sxroundbuf[32]; /* For ROUND result */
3488
3489 char *
dosexp(s)3490 dosexp(s) char *s; { /* s = S-Expression */
3491 extern struct mtab *mactab; /* Macro table */
3492 extern int maclvl, nmac;
3493 extern char *mrval[];
3494 extern int makestrlen; /* (see makestr()) */
3495 struct stringarray * q = NULL; /* cksplit() return type */
3496 char * p[SEXPMAX+1], ** p2; /* List items (must be on stack) */
3497 char * line = NULL; /* For building macro argument list */
3498 int nosplit = 0;
3499 int linelen = 0;
3500 int linepos = 0;
3501 int quote = 0; /* LISP quote flag */
3502 char * s2; /* Workers */
3503 int kw, kwflags, mx = 0, x = 0;
3504 int not = 0, truncate = 0, builtin = 0;
3505 int fpflag = 0, quit = 0, macro = 0;
3506 CK_OFF_T result = 0, i, j, k, n = 0;
3507 CKFLOAT fpj, fpresult = 0.0; /* Floating-point results */
3508 int pflag = 0; /* Have predicate */
3509 int presult = 0; /* Predicate result */
3510 int mustfree = 0; /* If we malloc'd we must free */
3511
3512 sexppv = -1; /* Predicate value */
3513 s2 = ""; /* Default return value */
3514
3515 debug(F111,sexpdebug("entry 1"),s,sexprc);
3516
3517 if (++sexpdep > sexpmaxdep) { /* Keep track of depth */
3518 printf("?S-Expression depth limit exceeded: %d\n",sexpmaxdep);
3519 sexprc++;
3520 debug(F111,sexpdebug("max depth exceeded"),s,sexprc);
3521 }
3522 if (sexpdep > sexpdmax) /* For stats */
3523 sexpdmax = sexpdep;
3524
3525 if (sexprc) /* Error, quit all levels */
3526 goto xdosexp; /* Always goto common exit point */
3527
3528 debug(F111,sexpdebug("entry 2"),s,sexprc);
3529
3530 if (!s) s = ""; /* Null or empty arg */
3531
3532 while (*s == SP) s++; /* Strip leading spaces */
3533 if (!*s) /* so empty result */
3534 goto xdosexp;
3535 /*
3536 Allocate result stack upon first use, or after it has been resized with
3537 SET SEXP DEPTH-LIMIT.
3538 */
3539 if (!sxresult) {
3540 sxresult = (char **)malloc(sexpmaxdep * sizeof(char *));
3541 if (!sxresult) {
3542 printf("?Memory allocation failure - \"%s\"\n", s);
3543 sexprc++;
3544 goto xdosexp;
3545 }
3546 sxrlen = (int *)malloc(sexpmaxdep * sizeof(int));
3547 if (!sxrlen) {
3548 printf("?Memory allocation failure - \"%s\"\n", s);
3549 sexprc++;
3550 goto xdosexp;
3551 }
3552 for (i = 0; i < sexpmaxdep; i++) {
3553 sxresult[i] = NULL; /* Result pointers */
3554 sxrlen[i] = 0; /* Buffer sizes */
3555 }
3556 }
3557 s2 = s; /* s2 is the result pointer */
3558 k = 0; /* Length accumulator */
3559 if (s[0] == '(') { /* Starts with open paren? */
3560 while (*s2++) k++; /* Get length */
3561 if (s[k-1] == ')') { /* Strip outer parens if any */
3562 s[k-1] = NUL;
3563 s++;
3564 k -= 2;
3565 while (*s == SP) { /* Strip leading spaces from result */
3566 s++;
3567 k--;
3568 }
3569 while (k > 0 && s[k-1] == SP) { /* And trailing spaces. */
3570 s[k-1] = NUL;
3571 k--;
3572 }
3573 }
3574 if (!*s) { /* If nothing remains */
3575 s2 = ""; /* return empty result. */
3576 goto xdosexp;
3577 }
3578 }
3579 /* Break result up into "words" (an SEXP counts as a word) */
3580
3581 for (i = 0; i < SEXPMAX+1; i++ ) { /* Clear the operands */
3582 p[i] = NULL;
3583 }
3584 if (!*(s+1) || !*(s+2)) { /* No need to call cksplit() */
3585 n = 1; /* if it's one or two chars. */
3586 p[1] = s; /* No need to malloc this either. */
3587 nosplit = 1;
3588 debug(F101,sexpdebug("nosplit"),"",n);
3589 if (s[0] == '(') { /* () empty */
3590 s2 = "";
3591 goto xdosexp;
3592 }
3593 } else {
3594 nosplit = 0;
3595 q = cksplit(1,SEXPMAX,s,NULL,"\\%[]&$+-/=*^_@!{}/<>|.#~'`:;?",8,39,0,0);
3596 if (!q)
3597 goto xdosexp;
3598 n = q->a_size; /* Number of items */
3599 // printf("XXX cksplit=%d\n",n);
3600 debug(F101,sexpdebug("split"),"",n);
3601 if (n < 0 || n > SEXPMAX) { /* Check for too many */
3602 printf("?Too many operands: max = %d\n",SEXPMAX);
3603 sexprc++;
3604 goto xdosexp;
3605 }
3606 if (n == 0) /* None, result is NULL, done. */
3607 goto xdosexp;
3608 if (n == 1 && s[0] == '(') { /* One but it's another SEXP */
3609 // printf("XXX s.00=[%s]\n",s);
3610 s2 = dosexp(s);
3611 // printf("XXX s2.00=[%s]\n",s2);
3612 goto xdosexp;
3613 }
3614 if (n == 1 && s[0] == '\047') { /* One but it's a string constant */
3615 int x = (int) strlen(s);
3616 s2 = s;
3617 if (s2[1] == '(' && s2[x-1] == ')') { /* '(string) */
3618 s2[x-1] = NUL;
3619 s2 += 2;
3620 // printf("XXX s2.2=[%s]\n",s2);
3621 }
3622 goto xdosexp;
3623 }
3624 /* More than one */
3625
3626 p2 = q->a_head; /* Point to result array. */
3627 for (i = 1; i <= n; i++) { /* We must copy it because */
3628 p[i] = NULL; /* recursive calls to dosexp() */
3629 if (p2[i]) /* write over the same array */
3630 makestr(&(p[i]),p2[i]);
3631 }
3632 if (s[0] == '(') { /* Operator is an S-Expression */
3633 // printf("XXX p[1]=[%s] s=[%s]\n",p[1],s);
3634 s2 = dosexp(p[1]); /* Replace it by its value */
3635 // printf("XXX s2.1=[%s]\n",s2);
3636 if (s2[0] == '\047') { /* LISP string literal */
3637 int x = (int) strlen(s2);
3638 if (s2[1] == '(' && s2[x-1] == ')') { /* '(string) */
3639 s2[x-1] = NUL;
3640 s2 += 2;
3641 printf("XXX s2.2=[%s]\n",s2);
3642 }
3643 }
3644 makestr(&(p[1]),s2);
3645 }
3646 mustfree++; /* Remember to free it */
3647 }
3648 debug(F110,sexpdebug("head"),p[1],0);
3649
3650 if (n == 1 && p[1]) {
3651 if (*(p[1]) == '\047') { /* Apostrophe = LISP quote character */
3652 s2 = p[1];
3653 goto xdosexp;
3654 }
3655 }
3656 /*
3657 This section sidesteps xlookup() of the most common operators.
3658 It's not necessary but it speeds up SEXP-heavy loops by about 10%.
3659 */
3660 kwflags = 0;
3661 if (n > 0) { /* Look up the operator */
3662 s2 = p[1]; /* Prelookup optimization... */
3663 if (!s2)
3664 s2 = "";
3665 if (!*s2)
3666 goto xdosexp;
3667 kw = 0;
3668 x = 0;
3669 if (isdigit(*s2)) { /* Digit */
3670 x = -2;
3671
3672 } else if (isalpha(*s2) && !*(s2+1)) { /* Single letter */
3673 x = -1;
3674
3675 } else if (*s2 == 's' || *s2 == 'S') { /* SETQ */
3676 s2++;
3677 if (*s2 == 'e' || *s2 == 'E') {
3678 s2++;
3679 if (*s2 == 't' || *s2 == 'T') {
3680 s2++;
3681 if (*s2 == 'q' || *s2 == 'Q') {
3682 if (!*(s2+1)) {
3683 x = SX_SET;
3684 kwflags = 0;
3685 builtin = 1;
3686 }
3687 }
3688 }
3689 }
3690 }
3691 if (!x) {
3692 if (!*(s2+1)) { /* Common single-character ops */
3693 if (*s2 == '+') {
3694 x = SX_ADD;
3695 kwflags = 0;
3696 builtin = 1;
3697 } else if (*s2 == '-') {
3698 x = SX_SUB;
3699 kwflags = 0;
3700 builtin = 1;
3701 } else if (*s2 == '*') {
3702 x = SX_MUL;
3703 kwflags = 0;
3704 builtin = 1;
3705 } else if (*s2 == '/') {
3706 x = SX_DIV;
3707 kwflags = SXF_TWO;
3708 builtin = 1;
3709 }
3710 }
3711 if (!x) { /* None of the above, look it up */
3712 x = xlookup(sexpops,p[1],nsexpops,&kw);
3713 if (x > 0) {
3714 kwflags = sexpops[kw].flgs;
3715 builtin = 1;
3716 }
3717 }
3718 }
3719 }
3720 /* If none of the above, check built-in constants */
3721
3722 if (x == -1) {
3723 x = xlookup(sexpconsts,p[1],nsexpconsts,&kw);
3724 if (x > 0) {
3725 switch (x) {
3726 case SXC_NIL:
3727 s2 = "";
3728 goto xdosexp;
3729 case SXC_PI:
3730 s2 = math_pi;
3731 goto xdosexp;
3732 case SXC_T:
3733 s2 = "1";
3734 goto xdosexp;
3735 }
3736 }
3737 }
3738 if (n == 1) { /* Not an expression */
3739 if (builtin) { /* Built-in operand? */
3740 switch (x) { /* Operators with default values */
3741 case SX_EVA:
3742 s2 = "";
3743 goto xdosexp;
3744 case SX_MUL: /* (*) */
3745 s2 = sexpval ? sexpval : "1";
3746 goto xdosexp;
3747 case SX_AND: /* (AND) */
3748 case SX_BWA: /* Bitwise (&) */
3749 result++;
3750 case SX_LOR: /* (OR) */
3751 case SX_BWO: /* Bitwise (|) */
3752 case SX_ADD: /* (+) */
3753 case SX_SUB: /* (-) */
3754 s2 = result ? "1" : "0";
3755 goto xdosexp;
3756 }
3757
3758 } else { /* Not a built-in operand */
3759 char * p1;
3760 p1 = p[1];
3761 while (*p1 == SP) p1++;
3762 if (!isalpha(*p1)) {
3763 if (xxfloat(p1,0) > 0) { /* Is it a number? */
3764 s2 = p1;
3765 while (*s2 == '+') s2++;
3766 } else if (*p1 == '(') { /* An S-Expression? */
3767
3768 #ifdef COMMENT
3769 s2 = dosexp(s2);
3770 #else
3771 s2 = dosexp(p1);
3772 #endif /* COMMENT */
3773 }
3774 goto xdosexp;
3775 } else if (x < 1) { /* Is it a variable? */
3776 j = mxlook(mactab,p[1],nmac); /* Look it up */
3777 debug(F111,sexpdebug("n==1 mxlook"),p[1],j);
3778 s2 = (j > -1) ? mactab[j].mval : "";
3779 if (!s2) s2 = "";
3780 if (xxfloat(s2,0) > 0) /* Macro value is a number */
3781 goto xdosexp;
3782 if (j > -1) { /* It's a macro */
3783 mx = j;
3784 x = j; /* whose definition is not numeric */
3785 if (*s2 == '(') { /* Is it an S-Expression? */
3786 /* We have to allocate memory on the stack */
3787 /* to call ourselves recursively on it */
3788 /* otherwise we'll wipe out the macro definition */
3789 char * s3 = NULL;
3790 /* int k = 0; */
3791 s3 = s2;
3792 while (*s3++) k++;
3793 s3 = (char *)malloc(k + 4);
3794 if (s3) {
3795 strcpy(s3,s2); /* SAFE */
3796 s2 = dosexp(s3); /* Evaluate it */
3797 free(s3);
3798 } else {
3799 printf("?Memory allocation failure - \"%s\"\n",s2);
3800 sexprc++;
3801 }
3802 goto xdosexp;
3803 }
3804 if (*s2 == '\047') {
3805 s2++;
3806 #ifdef COMMENT
3807 /* Dumps core if petty optimization was taken */
3808 makestr(&(p[1]),s2);
3809 #else
3810 if (!nosplit && p[1]) free(p[1]);
3811 p[1] = (char *)malloc((int)strlen(s2) + 1);
3812 #endif /* COMMENT */
3813 s2 = p[1];
3814 if (!s2) s2 = "";
3815 if (*s2 == '(') {
3816 if (s2[makestrlen-1] == ')') {
3817 s2[makestrlen-1] = NUL;
3818 s2++;
3819 }
3820 }
3821 debug(F110,sexpdebug("'A"),s2,0);
3822 goto xdosexp;
3823 }
3824 macro++; /* Not an S-Expression */
3825 } else {
3826 printf("?Not defined - \"%s\"\n", p[1]);
3827 sexprc++;
3828 goto xdosexp;
3829 }
3830 }
3831 }
3832 } else if (x < 1 && !macro) { /* n > 1 and not a built-in operator */
3833 x = mxlook(mactab,p[1],nmac); /* See if it's a macro */
3834 debug(F111,sexpdebug("n!=1 mxlook"),p[1],x);
3835 if (x < 0) {
3836 printf("?Invalid operand - \"%s\"\n",p[1]);
3837 sexprc++;
3838 s2 = NULL; /* Bad operator, no result */
3839 goto xdosexp;
3840 }
3841 mx = x;
3842 macro++;
3843 }
3844 if (builtin) { /* Built-in operator... */
3845 if (kwflags) {
3846 int flgs;
3847 if ((flgs = (kwflags & (SXF_ONE|SXF_TWO)))) {
3848 switch (flgs) {
3849 case (SXF_ONE|SXF_TWO):
3850 if (n < 2) {
3851 printf("?Too few operands - \"%s\"\n",s);
3852 sexprc++;
3853 goto xdosexp;
3854 }
3855 break;
3856 case SXF_TWO:
3857 if (n < 3) {
3858 printf("?Too few operands - \"%s\"\n",s);
3859 sexprc++;
3860 goto xdosexp;
3861 }
3862 break;
3863 case SXF_ONE:
3864 if (n != 2) {
3865 printf("?Too %s operands - \"%s\"\n",
3866 (n > 2) ? "many" : "few", s);
3867 sexprc++;
3868 goto xdosexp;
3869 }
3870 }
3871 }
3872 if (kwflags & SXF_PRE) { /* Predicate? */
3873 if (n < 2) {
3874 printf("?Too few operands - \"%s\"\n",s);
3875 sexprc++;
3876 goto xdosexp;
3877 }
3878 pflag = 1;
3879 presult = 1;
3880 }
3881 if (kwflags & SXF_FLO) /* Operator requires floating point */
3882 fpflag++; /* Force it */
3883
3884 if (x == SX_ROU) { /* ROUND can have 1 or 2 arguments */
3885 if (n < 2 || n > 3) {
3886 printf("?Too %s operands - \"%s\"\n",
3887 (n > 3) ? "many" : "few", s);
3888 sexprc++;
3889 goto xdosexp;
3890 }
3891 }
3892 if (x == SX_ROU) {
3893 /* But they are not "cumulative" like other SEXP args */
3894 /* So this case is handled specially */
3895 char buf1[32], buf2[32];
3896 float r;
3897 char * s0, * s1;
3898 char * q0, * q1;
3899
3900 s0 = p[2];
3901 if (!s0) s0 = "";
3902 if (!*s0) s0 = "0";
3903 q0 = dosexp(s0);
3904 ckstrncpy(buf1,q0,32);
3905 q0 = buf1;
3906
3907 s1 = p[3];
3908 if (!s1) s1 = "";
3909 if (!*s1) s1 = "0";
3910 q1 = dosexp(s1);
3911 if (!q1) q1 = "";
3912 if (!*q1) q1 = "0";
3913 ckstrncpy(buf2,q1,32);
3914 q1 = buf2;
3915 r = ckround(atof(q0),(int)(atof(q1)),sxroundbuf,31);
3916 s2 = sxroundbuf;
3917 sexprc = 0;
3918 goto xdosexp;
3919 }
3920 }
3921 if (x == SX_SET || x == SX_LET || /* Assignment is special */
3922 x == SX_INC || x == SX_DEC) {
3923 int rc;
3924 char c, * m, * s3;
3925 if (n == 1) {
3926 s2 = "";
3927 goto xdosexp;
3928 }
3929 s2 = NULL;
3930 for (i = 1; i < n; i += 2) { /* Loop thru operand pairs */
3931 rc = 0;
3932 s3 = p[i+1];
3933 c = *s3;
3934 debug(F110,sexpdebug("target p"),s3,0);
3935
3936 /* Make sure target doesn't have multiple words */
3937 while (*s3) { if (*s3 < '!') { rc = 1; break; }; s3++; }
3938 s3 = p[i+1];
3939 if (rc) { /* If it does it must have been */
3940 char * s4; /* an SEXP so evaluate it */
3941 s3 = dosexp(s3);
3942 s4 = s3;
3943 rc = 0;
3944 while (*s4) { if (*s4 < '!') { rc = 1; break; }; s4++; }
3945 if (rc == 0) makestr(&(p[i+1]),s3);
3946 }
3947
3948 /* And that it's not a number, etc. */
3949 if (rc > 0 || isdigit(c) || c == '(') {
3950 printf("?Invalid assignment - \"%s\"\n",s);
3951 sexprc++;
3952 goto xdosexp;
3953 } else if (isalpha(c)) {
3954 rc = xlookup(sexpconsts,s3,nsexpconsts,NULL);
3955 if (rc > 0) {
3956 printf("?Assignment to constant - \"%s\"\n",s);
3957 sexprc++;
3958 goto xdosexp;
3959 }
3960 }
3961
3962 /* If ++ or --, get current value of variable */
3963 if (x == SX_INC || x == SX_DEC) {
3964 int ok = 1;
3965 char buf[32];
3966 if (c == CMDQ) { /* A backslash variable */
3967 int n = 32;
3968 char * s = buf;
3969 buf[0] = NUL;
3970 if (zzstring(s3,&s,&n) < 0 || !buf[0])
3971 ok = 0;
3972 s2 = buf;
3973 } else { /* A macro */
3974 if ((k = mxlook(mactab,s3,nmac)) < 0)
3975 ok = 0;
3976 else
3977 s2 = mactab[k].mval;
3978 }
3979 if (!ok) {
3980 printf("?Not defined - \"%s\"\n",p[i+1]);
3981 sexprc++;
3982 goto xdosexp;
3983 }
3984 if (!s2) s2 = "";
3985 k = xxfloat(s2,0);
3986 if (k < 1) {
3987 printf("?Not numeric - \"%s\"\n",p[i+1]);
3988 sexprc++;
3989 goto xdosexp;
3990 }
3991 while (*s2 == '+') s2++;
3992 result = ckatofs(s2);
3993 fpresult = floatval;
3994 if (k > 1 || fpresult != result)
3995 fpflag++;
3996 }
3997 if (n < i+2) { /* Variable with no value */
3998 s2 = "";
3999 if (x == SX_SET || x == SX_LET) {
4000 delmac(p[i+1],1); /* Delete the variable */
4001 break;
4002 } else {
4003 s2 = "1";
4004 }
4005 } else { /* Variable with value */
4006 k = xxfloat(p[i+2],0); /* Is it a number? */
4007 if (k > 0) {
4008 s2 = p[i+2];
4009 while (*s2 == '+') s2++;
4010 } else {
4011 s2 = dosexp(p[i+2]); /* Have value, evaluate it */
4012 if (sexprc) goto xdosexp;
4013 if (!s2) s2 = "";
4014 if (!*s2 && (x == SX_INC || x == SX_DEC))
4015 continue;
4016 }
4017 }
4018 if (x == SX_INC || x == SX_DEC) {
4019 k = xxfloat(s2,0);
4020 if (k < 1) {
4021 printf("?Not numeric - \"%s\"\n",s2);
4022 sexprc++;
4023 goto xdosexp;
4024 }
4025 while (*s2 == '+') s2++;
4026 j = ckatofs(s2);
4027 if (k > 1) {
4028 fpj = floatval;
4029 fpflag++;
4030 } else {
4031 fpj = (CKFLOAT)j;
4032 }
4033 if (x == SX_INC) {
4034 result += j;
4035 fpresult += fpj;
4036 } else if (x == SX_DEC) {
4037 result -= j;
4038 fpresult -= fpj;
4039 }
4040 #ifdef FNFLOAT
4041 if (result != fpresult) fpflag++;
4042 #endif /* FNFLOAT */
4043 s2 = (fpflag && !sexptrunc) ?
4044 fpformat(fpresult,0,0) : ckfstoa(result);
4045 }
4046 if (x == SX_LET && cmdlvl > 0) /* LET makes var local */
4047 addlocal(p[i+1]);
4048 if ((rc = addmac(p[i+1],s2)) < 0) { /* Add the value */
4049 switch (rc) {
4050 case -3: m = "Array not declared"; break;
4051 case -2: m = "Subscript out of range"; break;
4052 case -4: m = "Out of memory"; break;
4053 default: m = "Error creating variable";
4054 }
4055 printf("?%s - \"%s\"\n",m,s);
4056 sexprc++;
4057 goto xdosexp;
4058 }
4059 if (s2) result = ckatofs(s2);
4060 }
4061 goto xdosexp;
4062 } else if (x == SX_IFC) { /* Conditional expression */
4063 int true = 0;
4064 if (n > 4) {
4065 printf("?Too many operands: IF - \"%s\"\n",s);
4066 sexprc++;
4067 goto xdosexp;
4068 }
4069 s2 = dosexp(p[2]);
4070 if (sexprc) goto xdosexp;
4071 if (s2) {
4072 j = ckatofs(s2);
4073 if (xxfloat(s2,0) == 2) {
4074 fpflag++;
4075 fpresult = (CKFLOAT)result;
4076 fpj = floatval;
4077 } else {
4078 fpj = atof(s2);
4079 }
4080 true = ((fpj != 0.0) ? 1 : 0);
4081 }
4082 if (!true && n < 4) {
4083 s2 = NULL;
4084 } else {
4085 s2 = dosexp(true ? p[3] : p[4]);
4086 if (sexprc) goto xdosexp;
4087 j = s2 ? ckatofs(s2) : 0;
4088 if (xxfloat(s2,0) == 2) {
4089 fpflag++;
4090 fpresult = (CKFLOAT)result;
4091 fpj = floatval;
4092 } else {
4093 fpj = s2 ? atof(s2) : 0.0;
4094 }
4095 fpresult = fpj;
4096 result = j;
4097 }
4098 goto xdosexp;
4099 } else if (x == SX_QUO) {
4100 int k, xx;
4101 xx = strlen(p[2]);
4102 p[3] = (char *)malloc(xx+4);
4103 s2 = p[3];
4104 ckmakmsg(p[3],xx+4,"'(",p[2],")",NULL);
4105 n++;
4106 goto xdosexp;
4107 } else if (x == SX_UNQ) { /* UNQUOTE */
4108 int k, xx = 0;
4109 s2 = p[2];
4110 if (!s2) s2 = "";
4111 xx = strlen(s2);
4112 // printf("XXX ENTRY: %s, len=%d\n",s2,xx);
4113 if (xx = 0) /* Null or empty arg */
4114 goto xdosexp;
4115
4116 /* Case 0 - number */
4117 if (isfloat(s2,0))
4118 goto xdosexp;
4119
4120 /* Case 2 - S-expression that evaluates to a quoted string */
4121 if (s2[0] == '(' && s2[xx-1] == ')') {
4122 // printf("XXX SEXP: %s\n",p[2]);
4123 s2 = dosexp(s2);
4124 // printf("XXX SEXP EVALUATED: %s\n",p[2]);
4125 } else if (s2[0] != '\047') {
4126 /* Case 3 - Variable */
4127 // printf("XXX MACRO NAME: %s\n",p[2]);
4128 if ((k = mxlook(mactab,p[2],nmac)) >= 0) {
4129 s2 = mactab[k].mval;
4130 // printf("XXX MACRO VALUE: %s\n",s2);
4131 } else {
4132 // printf("XXX UNDEFINED MACRO: %s\n",p[2]);
4133 s2 = "";
4134 }
4135 }
4136 /* If result is a quoted string, unquote it */
4137 // printf("XXX BEFORE UNQUOTING: %s\n",s2);
4138 xx = strlen(s2);
4139 if (s2[0] == '\047' && s2[1] == '(' && s2[xx-1] == ')') {
4140 // printf("XXX HAVE QUOTED STRING: %s\n",s2);
4141 s2[xx-1] = NUL;
4142 s2 += 2;
4143 }
4144 // printf("XXX RESULT: %s\n",s2);
4145 goto xdosexp;
4146
4147 } else if (x == SX_STR) {
4148 int xx;
4149 s2 = dosexp(p[2]);
4150 if (sexprc) goto xdosexp;
4151 xx = strlen(s2);
4152 p[3] = (char *)malloc(xx+4);
4153 ckmakmsg(p[3],xx+4,"'(",s2,")",NULL);
4154 s2 = p[3];
4155 n++;
4156 goto xdosexp;
4157 }
4158 }
4159 /* Arithmetic operator or macro - Loop thru operands */
4160
4161 quit = 0; /* Short-circuit flag. */
4162 if (macro && n > 1) { /* If operator is a macro */
4163 if (!line) { /* allocate local buffer for */
4164 line = (char *)malloc(SXMLEN); /* the evaluated argument list. */
4165 if (!line) {
4166 printf("?Memory allocation failure - \"%s\"\n",p[1]);
4167 sexprc++;
4168 goto xdosexp;
4169 }
4170 linelen = SXMLEN;
4171 /* debug(F101,"dosexp macro arg buffer","",linelen); */
4172 }
4173 linepos = 0;
4174 line[linepos] = NUL;
4175 }
4176 for (i = 1; ((i < n) && !sexprc && !quit); i++) { /* Loop thru operands */
4177 quote = 0;
4178 s2 = p[i+1]; /* Get operand */
4179 if (!s2) s2 = "";
4180
4181 #ifdef COMMENT
4182 if (*s2 == '\047') { /* Is it quoted? */
4183 debug(F110,sexpdebug("'B"),s2,0);
4184 s2++; /* Space past the quote */
4185 quote++;
4186 if (*s2 == '(') { /* Quoted S-Expression? */
4187 char c4, * s4 = s2+1; /* Strip outer parens */
4188 while ((c4 = *s4++)) {
4189 if (c4 == ')' && !*s4) {
4190 s2++;
4191 *(s4-1) = NUL;
4192 break;
4193 }
4194 }
4195 }
4196 debug(F110,sexpdebug("'C"),s2,0);
4197
4198 } else { /* Not quoted */
4199 s2 = dosexp(p[i+1]); /* evaluate it */
4200 if (sexprc) goto xdosexp;
4201 if (!s2) s2 = "";
4202 if (!macro && x == SX_EVA)
4203 continue;
4204 }
4205 #else
4206 if (*s2 != '\047') { /* Not quoted */
4207 // printf("XXX UNQUOTED ARG %s\n",s2);
4208 if (x == SX_ECH && (k = mxlook(mactab,s2,nmac)) > -1) {
4209 s2 = mactab[k].mval;
4210 // printf("XXX MACRO DEF %s\n",s2);
4211 } else {
4212 s2 = dosexp(s2); /* No, evaluate it */
4213 // printf("XXX SEXP VALUE %s\n",s2);
4214 }
4215 if (sexprc && x != SX_ECH)
4216 goto xdosexp;
4217 if (!s2) s2 = "";
4218 if (!macro && x == SX_EVA)
4219 continue;
4220 if (x == SX_ECH) { /* ECHO */
4221 printf("%s ",s2);
4222 if (i == n-1) printf("\n");
4223 continue;
4224 }
4225 }
4226 if (*s2 == '\047') { /* Is result quoted? */
4227 debug(F110,sexpdebug("'B"),s2,0);
4228 s2++; /* Space past the quote */
4229 quote++;
4230 if (*s2 == '(') { /* Quoted S-Expression? */
4231 char c4, * s4 = s2+1; /* Strip outer parens */
4232 while ((c4 = *s4++)) {
4233 if (c4 == ')' && !*s4) {
4234 s2++;
4235 *(s4-1) = NUL;
4236 break;
4237 }
4238 }
4239 }
4240 debug(F110,sexpdebug("'C"),s2,0);
4241 if (x == SX_ECH) { /* ECHO */
4242 printf("%s ",s2);
4243 if (i == n-1) printf("\n");
4244 continue;
4245 }
4246 }
4247 #endif /* COMMENT */
4248 if (macro) {
4249 debug(F111,sexpdebug("macro arg"),s2,i);
4250 if (!*s2) quote++;
4251 if (!quote) {
4252 register char c4, * s4 = s2;
4253 while ((c4 = *s4++)) if (c4 == SP) { quote++; break; }
4254 }
4255 if (quote) line[linepos++] = '{';
4256 while ((line[linepos++] = *s2++)) {
4257 if (linepos > linelen - 3) {
4258 char * tmp = NULL;
4259 line[linepos] = NUL;
4260 linelen += SXMLEN;
4261 tmp = (char *) malloc(linelen);
4262 if (!tmp) {
4263 printf("?Memory re-allocation failure - \"%s...\"\n",
4264 line);
4265 sexprc++;
4266 goto xdosexp;
4267 }
4268 strcpy(tmp,line);
4269 free(line);
4270 line = tmp;
4271 }
4272 }
4273 linepos--; /* Back up over NUL */
4274 if (quote)
4275 line[linepos++] = '}'; /* End quote group */
4276 line[linepos++] = SP; /* add a space */
4277 line[linepos] = NUL; /* and a NUL */
4278 continue;
4279 }
4280 if (!quote) { /* Built-in operator... */
4281 s2 = dosexp(s2);
4282 if (sexprc) goto xdosexp;
4283 if (!s2) s2 = "";
4284 }
4285 if (x == SX_EVA)
4286 continue;
4287
4288 if (!*s2) {
4289 /* An empty value is not a legal number */
4290 /* but it is a legal truth value */
4291 if (x != SX_AND && x != SX_LOR && x != SX_NOT) {
4292 printf("?Not Numeric - \"%s\"\n",p[i+1]);
4293 sexprc++;
4294 goto xdosexp;
4295 }
4296 j = 0;
4297 fpj = 0.0;
4298 } else {
4299 j = ckatofs(s2);
4300 /* Switch to floating-point upon encountering any f.p. arg */
4301 /* OR... if integer is too big */
4302 if (!fpflag) if (xxfloat(s2,0) == 2)
4303 fpflag++;
4304 fpj = atof(s2);
4305 }
4306 if (i == 1) { /* Initial result is first operand */
4307 result = (n == 2 && x == SX_SUB) ? 0-j : j;
4308 fpresult = (n == 2 && x == SX_SUB) ? -fpj : fpj;
4309 if ((x == SX_AND && result == 0) || /* Short circuit */
4310 (x == SX_LOR && result != 0))
4311 quit++;
4312 if (!(kwflags & SXF_ONE)) /* Command w/single arg */
4313 continue;
4314 }
4315 if (x == SX_MOD || x == SX_DIV) {
4316 if (!result)
4317 fpflag++;
4318 if (!fpj) {
4319 printf("?Divide by zero - \"%s\"\n",cmdbuf);
4320 sexprc++;
4321 goto xdosexp;
4322 }
4323 }
4324 switch (x) { /* Accumulate result */
4325
4326 case SX_EVA: /* EVAL */
4327 result = j;
4328 fpresult = fpj;
4329 break;
4330
4331 case SX_ADD: /* + */
4332 result += j;
4333 fpresult += fpj;
4334 #ifdef FNFLOAT
4335 if (result != fpresult)
4336 fpflag++;
4337 #endif /* FNFLOAT */
4338 break;
4339
4340 case SX_SUB: /* - */
4341 result -= j;
4342 fpresult -= fpj;
4343 #ifdef FNFLOAT
4344 if (result != fpresult)
4345 fpflag++;
4346 #endif /* FNFLOAT */
4347 break;
4348
4349 case SX_MUL: /* * */
4350 result *= j;
4351 fpresult *= fpj;
4352 #ifdef FNFLOAT
4353 if (result != fpresult)
4354 fpflag++;
4355 #endif /* FNFLOAT */
4356 break;
4357
4358 case SX_AND: /* AND */
4359 result = result && j;
4360 if (!result) quit++;
4361 fpresult = fpresult && fpj;
4362 break;
4363
4364 case SX_LOR: /* OR */
4365 result = result || j;
4366 if (!result) quit++;
4367 fpresult = fpresult || fpj;
4368 break;
4369
4370 case SX_MOD: /* Modulus */
4371 result = result % j;
4372 #ifdef FNFLOAT
4373 fpresult = (CKFLOAT)fmod(fpresult,fpj);
4374 if (result != fpresult)
4375 fpflag++;
4376 #else
4377 fpresult = result;
4378 #endif /* FNFLOAT */
4379 break;
4380
4381 case SX_DIV: /* / */
4382 if (j) {
4383 result /= j;
4384 fpresult /= fpj;
4385 #ifdef FNFLOAT
4386 if (result != fpresult)
4387 fpflag++;
4388 #endif /* FNFLOAT */
4389 } else {
4390 fpresult /= fpj;
4391 result = fpj;
4392 #ifdef FNFLOAT
4393 fpflag++;
4394 #endif /* FNFLOAT */
4395 }
4396 break;
4397
4398 case SX_AEQ: /* Test for equality */
4399 if (fpflag) {
4400 if (fpresult != fpj)
4401 presult = 0;
4402 } else {
4403 if (result != j)
4404 presult = 0;
4405 }
4406 break;
4407
4408 case SX_NEQ: /* Test for ineqality */
4409 if (fpflag) {
4410 if (fpresult == fpj)
4411 presult = 0;
4412 } else {
4413 if (result == j)
4414 presult = 0;
4415 }
4416 break;
4417
4418 case SX_ALE: /* Arithmetic less-equal */
4419 if (fpflag) {
4420 if (fpj < fpresult)
4421 presult = 0;
4422 fpresult = fpj;
4423 } else {
4424 if (j < result)
4425 presult = 0;
4426 result = j;
4427 }
4428 break;
4429
4430 case SX_ALT: /* Arithmetic less-than */
4431 if (fpflag) {
4432 if (fpj <= fpresult)
4433 presult = 0;
4434 fpresult = fpj;
4435 } else {
4436 if (j <= result)
4437 presult = 0;
4438 result = j;
4439 }
4440 break;
4441
4442 case SX_AGT: /* Arithmetic greater-than */
4443 if (fpflag) {
4444 if (fpj >= fpresult)
4445 presult = 0;
4446 fpresult = fpj;
4447 } else {
4448 if (j >= result)
4449 presult = 0;
4450 result = j;
4451 }
4452 break;
4453
4454 case SX_AGE: /* Arithmetic greater-equal */
4455 if (fpflag) {
4456 if (fpj > fpresult)
4457 presult = 0;
4458 fpresult = fpj;
4459 } else {
4460 if (j > result)
4461 presult = 0;
4462 result = j;
4463 }
4464 break;
4465
4466 case SX_POW: /* Raise to power */
4467 #ifdef FNFLOAT
4468 {
4469 double dummy;
4470 if (!fpj) {
4471 fpresult = 1.0;
4472 } else if ((!fpresult && fpj <= 0.0)) {
4473 printf("?Divide by zero - \"%s\"\n",cmdbuf);
4474 sexprc++;
4475 goto xdosexp;
4476 } else if (fpresult < 0.0 && modf(fpj,&dummy)) {
4477 printf("?Domain error - \"%s\"\n",cmdbuf);
4478 sexprc++;
4479 goto xdosexp;
4480 } else {
4481 fpresult = (CKFLOAT)pow(fpresult,fpj);
4482 }
4483 }
4484 #endif /* FNFLOAT */
4485 if (j == 0) {
4486 result = 1;
4487 } else {
4488 CK_OFF_T z, sign = 0;
4489 if (j < 0) {
4490 if (result == 0) {
4491 printf("?Divide by zero - \"%s\"\n",cmdbuf);
4492 sexprc++;
4493 goto xdosexp;
4494 }
4495 j = 0 - j;
4496 sign++;
4497 }
4498 z = result;
4499 while (--j > 0)
4500 result *= z;
4501 if (sign)
4502 result = 1 / result;
4503 }
4504 #ifdef FNFLOAT
4505 if (result != fpresult)
4506 fpflag++;
4507 #endif /* FNFLOAT */
4508 break;
4509
4510 #ifdef FNFLOAT
4511 case SX_EXP: /* e to the given power */
4512 fpresult = (CKFLOAT) exp(fpj);
4513 break;
4514
4515 case SX_LGN: /* Natural log */
4516 case SX_LGX: /* Log base 10 */
4517 case SX_SQR: /* Square root */
4518 if (fpj < 0.0) {
4519 printf("?Argument out of range - \"%s\"\n",cmdbuf);
4520 sexprc++;
4521 goto xdosexp;
4522 }
4523 if (x == SX_SQR)
4524 fpresult = (CKFLOAT) sqrt(fpj);
4525 else if (x == SX_LGN)
4526 fpresult = (CKFLOAT) log(fpj);
4527 else
4528 fpresult = (CKFLOAT) log10(fpj);
4529 break;
4530
4531 case SX_SIN: /* sine */
4532 fpresult = (CKFLOAT) sin(fpj);
4533 break;
4534
4535 case SX_COS: /* cosine */
4536 fpresult = (CKFLOAT) cos(fpj);
4537 break;
4538
4539 case SX_TAN: /* tangent */
4540 fpresult = (CKFLOAT) tan(fpj);
4541 break;
4542 #endif /* FNFLOAT */
4543
4544 case SX_CEI: /* Ceiling */
4545 if (j != fpj)
4546 if (fpj > 0.0)
4547 fpj += 1.0;
4548 fpresult = fpj;
4549 fpflag = 1;
4550 truncate = 1;
4551 break;
4552
4553 case SX_FLR: /* Floor */
4554 if (j != fpj)
4555 if (fpj < 0.0)
4556 fpj -= 1.0;
4557 fpresult = fpj;
4558 fpflag = 1;
4559 truncate = 1;
4560 break;
4561
4562 case SX_TRU: /* Truncate */
4563 fpresult = fpj;
4564 fpflag = 1;
4565 truncate = 1;
4566 break;
4567
4568 case SX_ABS: /* Absolute value */
4569 result = (j < 0) ? 0 - j : j;
4570 #ifdef FNFLOAT
4571 fpresult = (fpj < 0.0) ? 0.0 - fpj : fpj;
4572 if (result != fpresult)
4573 fpflag++;
4574 #endif /* FNFLOAT */
4575 break;
4576
4577 case SX_MAX: /* Max */
4578 if (j != fpj)
4579 fpflag++;
4580 if (fpflag) {
4581 if (fpj > fpresult)
4582 fpresult = fpj;
4583 } else
4584 if (j > result)
4585 result = j;
4586 break;
4587
4588 case SX_MIN: /* Min */
4589 if (j != fpj)
4590 fpflag++;
4591 if (fpflag) {
4592 if (fpj < fpresult)
4593 fpresult = fpj;
4594 } else
4595 if (j < result)
4596 result = j;
4597 break;
4598
4599 case SX_FLO: /* Float */
4600 fpflag++;
4601 fpresult = result;
4602 fpj = j;
4603 break;
4604
4605 case SX_NOT: /* NOT (reverse truth value) */
4606 fpflag = 0;
4607 not++;
4608 break;
4609
4610 case SX_BWA: /* Bitwise AND */
4611 fpflag = 0;
4612 result &= j;
4613 break;
4614
4615 case SX_BWO: /* Bitwise OR */
4616 fpflag = 0;
4617 result |= j;
4618 break;
4619
4620 case SX_BWX: /* Bitwise XOR */
4621 case SX_XOR: /* Logical XOR */
4622 if (n > 3) {
4623 printf("?Too many operands - \"%s\"\n",s);
4624 sexprc++;
4625 goto xdosexp;
4626 }
4627 fpflag = 0;
4628 if (x == SX_BWX) {
4629 result ^= j;
4630 } else {
4631 result = (result && !j) || (!result && j);
4632 if (result) result = 1;
4633 }
4634 break;
4635
4636 case SX_BWN: /* Bitwise Not */
4637 fpflag = 0;
4638 result = ~result;
4639 break;
4640
4641 default:
4642 printf("BAD OP [%s]\n",p[1]);
4643 sexprc++;
4644 }
4645 }
4646 if (!pflag) /* Not a predicate */
4647 sexppv = -1; /* So unset this */
4648
4649 /* domacro: */
4650
4651 if (macro) { /* User-defined macro */
4652 extern int fsexpflag; /* (see fneval():ckuus4.c) */
4653 int lookagain = 0; /* Maybe the macro table changed */
4654 if (mactab[mx].kwd) { /* Check and see */
4655 if (ckstrcmp(mactab[mx].kwd,p[1],-1,0))
4656 lookagain++;
4657 } else
4658 lookagain++;
4659 if (lookagain) { /* The table changed */
4660 mx = mxlook(mactab,p[1],nmac); /* Get the macro's new index */
4661 debug(F111,sexpdebug("macro moved"),p[1],mx);
4662 if (mx < 0) { /* Yikes! */
4663 printf("?Macro disappeared! - \"%s\"\n",p[1]);
4664 sexprc++;
4665 goto xdosexp;
4666 }
4667 }
4668 debug(F111,sexpdebug("macro mx"),mactab[mx].kwd,mx);
4669 if (fsexpflag) { /* If embedded in a function call */
4670 if (cmpush() > -1) { /* get a new copy of the parsing */
4671 extern int ifc; /* environment, */
4672 int k, ifcsav = ifc; /* save the IF state */
4673 dodo(mx,line,0); /* Set up the macro */
4674 k = parser(1); /* Call the parser to execute it */
4675 cmpop(); /* Pop back to previous level */
4676 ifc = ifcsav; /* restore IF state */
4677 if (k == 0) /* If no error */
4678 s2 = mrval[maclvl+1]; /* get return value, if any */
4679 if (!s2) s2 = "";
4680 debug(F110,sexpdebug("macro return"),s2,0);
4681 } else {
4682 printf("?Resources exhausted - \"%s\"\n",s);
4683 sexprc++;
4684 }
4685 } else { /* Not embedded in a function call */
4686 dodo(mx,line,0); /* As above but without cmpush/pop() */
4687 k = parser(1);
4688 if (k == 0)
4689 s2 = mrval[maclvl+1];
4690 if (!s2) s2 = "";
4691 }
4692 } else if (pflag) { /* Predicate */
4693 if (not) presult = presult ? 0 : 1;
4694 sexppv = presult; /* So set predicate value (0 or 1) */
4695 s2 = presult ? "1" : "0";
4696 } else if (fpflag && !sexptrunc) { /* Result is floating-point */
4697 if (not) fpresult = fpresult ? 0.0 : 1.0;
4698 s2 = fpformat(fpresult,0,0);
4699 } else if (x != SX_EVA) {
4700 if (not) result = result ? 0 : 1;
4701 s2 = ckfstoa(result);
4702 }
4703
4704 /* Common exit point. Always come here to exit. */
4705
4706 xdosexp:
4707
4708 if (!s2) s2 = "";
4709 debug(F111,"xdosexp s2",s2,sexprc);
4710 // printf("XXX xdosexp s2=[%s]\n",s2);
4711 if (x == SX_ECH) s2 = "";
4712 debug(F111,"xdosexp s2 ECHO",s2,sexprc);
4713
4714 if (!sexprc /* && *s2 */) { /* Have a result */
4715 char * sx; /* Note -- do this even if result empty */
4716 char * q2 = s2; int xx = 0;
4717 if (*s2) {
4718 while (*q2++) xx++; /* Get length */
4719 if (xx > sexprmax) /* (stats) */
4720 sexprmax = xx;
4721 } else
4722 xx = 0;
4723 if (xx > sxrlen[sexpdep] || !sxresult[sexpdep]) {
4724 int k;
4725 k = xx + xx / 4;
4726 if (k < 32) k = 32;
4727 if (sxresult[sexpdep])
4728 free(sxresult[sexpdep]);
4729 if ((sxresult[sexpdep] = (char *)malloc(k))) {
4730 sxrlen[sexpdep] = k;
4731 } else {
4732 printf("?Memory allocation failure - \"%s\"\n",s2);
4733 sexprc++;
4734 }
4735 }
4736 sx = sxresult[sexpdep]; /* Point to result buffer */
4737 while ((*sx++ = *s2++)) ; /* copy result. */
4738 if (fpflag && truncate) { /* Floating point + truncate */
4739 sx = sxresult[sexpdep]; /* at decimal point */
4740 for (i = xx - 1; i >= 0; i--) {
4741 if (sx[i] == '.') {
4742 sx[i] = NUL;
4743 if (i == 0) { /* If nothing left */
4744 sx[0] = '0'; /* put a zero. */
4745 sx[1] = NUL;
4746 }
4747 }
4748 }
4749 }
4750 }
4751 xxdosexp:
4752 if (line) /* If macro arg buffer allocated */
4753 free(line); /* free it. */
4754 if (mustfree) { /* And free local copy of split list */
4755 for (i = 1; i <= n; i++) {
4756 if (p[i]) free(p[i]);
4757 }
4758 }
4759 debug(F111,sexpdebug("exit"),sxresult[sexpdep],sexprc);
4760 s = sxresult[sexpdep--];
4761 if (!s) s = "";
4762 return(s);
4763 }
4764 #endif /* NOSEXP */
4765 #endif /* NOSPL */
4766
4767 int /* CHECK command */
dochk()4768 dochk() {
4769 int x, y;
4770 if ((y = cmkey(ftrtab,nftr,"","",xxstring)) < 0)
4771 return(y);
4772 ckstrncpy(line,atmbuf,LINBUFSIZ);
4773 if ((y = cmcfm()) < 0)
4774 return(y);
4775 #ifdef HAVE_LOCALE
4776 if (!ckstrcmp(line,"locale",(int)strlen(line),0)) {
4777 extern int nolocale;
4778 int ok = 0;
4779 ok = (nolocale ? 0 : 1);
4780 if (msgflg)
4781 printf(" locale%s available\n", ok ? "" : " not");
4782 else if (nolocale && !backgrd)
4783 printf(" CHECK: locale not available\n");
4784 return(success = ok);
4785 }
4786 #endif /* HAVE_LOCALE */
4787 #ifndef NOPUSH
4788 if (!ckstrcmp(line,"push",(int)strlen(line),0)) {
4789 if (msgflg) /* If at top level... */
4790 printf(" push%s available\n", nopush ? " not" : "");
4791 else if (nopush && !backgrd)
4792 printf(" CHECK: push not available\n");
4793 return(success = 1 - nopush);
4794 }
4795 #endif /* NOPUSH */
4796 #ifdef PIPESEND
4797 if (!ckstrcmp(line,"pipes",(int)strlen(line),0)) {
4798 if (msgflg) /* If at top level... */
4799 printf(" pipes%s available\n",
4800 (nopush || protocol != PROTO_K) ? " not" : "");
4801 else if ((nopush || protocol != PROTO_K) && !backgrd)
4802 printf(" CHECK: pipes not available\n");
4803 return(success = 1 - nopush);
4804 }
4805 #endif /* PIPESEND */
4806 y = lookup(ftrtab,line,nftr,&x); /* Look it up */
4807 debug(F111,"dochk",ftrtab[x].kwd,y);
4808 if (msgflg) /* If at top level... */
4809 printf(" %s%s available\n", ftrtab[x].kwd, y ? " not" : "");
4810 else if (y && !backgrd)
4811 printf(" CHECK: %s not available\n", ftrtab[x].kwd);
4812 return(success = 1 - y);
4813 }
4814
4815 #ifndef NOLOCAL
4816 #ifdef CKLOGDIAL
4817
4818 /* Connection log and elapsed-time reporting */
4819
4820 extern char cxlogbuf[]; /* Log record buffer */
4821 extern char diafil[]; /* Log file name */
4822 extern int dialog, cx_active; /* Flags */
4823 static long cx_prev = 0L; /* Elapsed time of previous session */
4824
4825 #endif /* CKLOGDIAL */
4826 #endif /* NOLOCAL */
4827
4828 VOID
dologend()4829 dologend() { /* Write record to connection log */
4830 #ifdef LOCUS
4831 extern int locus, autolocus;
4832 #endif /* LOCUS */
4833
4834 #ifndef NOLOCAL
4835 #ifdef CKLOGDIAL
4836 long d1, d2, t1, t2;
4837 char buf[32], * p;
4838 #endif /* CKLOGDIAL */
4839 #endif /* NOLOCAL */
4840
4841 #ifdef LOCUS
4842 if (autolocus) {
4843 int x = locus;
4844 #ifdef NEWFTP
4845 debug(F101,"dologend ftpisconnected","",ftpisconnected());
4846 setlocus(ftpisconnected() ? 0 : 1, 1);
4847 #else
4848 setlocus(1,1);
4849 #endif /* NEWFTP */
4850 }
4851 #endif /* LOCUS */
4852
4853 #ifndef NOLOCAL
4854 #ifdef CKLOGDIAL
4855 debug(F101,"dologend dialog","",dialog);
4856 debug(F101,"dologend cxlogbuf[0]","",cxlogbuf[0]);
4857 #ifdef CKSYSLOG
4858 debug(F101,"dologend ckxlogging","",ckxlogging);
4859 #endif /* CKSYSLOG */
4860
4861 if (!cx_active || !cxlogbuf[0]) /* No active record */
4862 return;
4863
4864 cx_active = 0; /* Record is not active */
4865 debug(F111,"dologend cxlogbuf 1",cxlogbuf,cx_active);
4866
4867 d1 = mjd((char *)cxlogbuf); /* Get start date of this session */
4868 ckstrncpy(buf,ckdate(),31); /* Get current date */
4869 d2 = mjd(buf); /* Convert them to mjds */
4870 p = cxlogbuf; /* Get start time */
4871 p[11] = NUL;
4872 p[14] = NUL; /* Convert to seconds */
4873 t1 = atol(p+9) * 3600L + atol(p+12) * 60L + atol(p+15);
4874 p[11] = ':';
4875 p[14] = ':';
4876 p = buf; /* Get end time */
4877 p[11] = NUL;
4878 p[14] = NUL;
4879 t2 = atol(p+9) * 3600L + atol(p+12) * 60L + atol(p+15);
4880 t2 = ((d2 - d1) * 86400L) + (t2 - t1); /* Compute elapsed time */
4881 debug(F101,"dologend t2","",t2);
4882 if (t2 > -1L) {
4883 cx_prev = t2;
4884 p = hhmmss(t2);
4885 debug(F110,"dologend hhmmss",p,0);
4886 ckstrncat(cxlogbuf,"E=",CXLOGBUFL); /* Append to log record */
4887 ckstrncat(cxlogbuf,p,CXLOGBUFL);
4888 debug(F110,"dologend cxlogbuf 2",cxlogbuf,0);
4889 } else
4890 cx_prev = 0L;
4891 debug(F101,"dologend cx_prev","",cx_prev);
4892 if (dialog) { /* If logging */
4893 int x;
4894 x = diaopn(diafil,1,1); /* Open log in append mode */
4895 debug(F101,"dologend diaopn","",x);
4896 x = zsoutl(ZDIFIL,cxlogbuf); /* Write the record */
4897 debug(F101,"dologend zsoutl","",x);
4898 x = zclose(ZDIFIL); /* Close the log */
4899 debug(F101,"dologend zclose","",x);
4900 }
4901 #ifdef CKSYSLOG
4902 debug(F101,"dologend ckxlogging","",ckxlogging);
4903 if (ckxlogging) {
4904 int x;
4905 x = ckindex("T=DIAL",cxlogbuf,0,0,1);
4906 debug(F111,"dologend ckxsyslog",cxlogbuf,ckxsyslog);
4907 debug(F111,"dologend ckindex","T=DIAL",x);
4908 if (x > 0) {
4909 if (ckxsyslog >= SYSLG_DI) {
4910 debug(F110,"dologend syslog",cxlogbuf+18,0);
4911 cksyslog(SYSLG_DI,1,"CONNECTION",(char *)(cxlogbuf+18),"");
4912 } else if (ckxsyslog >= SYSLG_AC) {
4913 debug(F110,"dologend syslog",cxlogbuf+18,0);
4914 cksyslog(SYSLG_AC,1,"CONNECTION",(char *)(cxlogbuf+18),"");
4915 }
4916 }
4917 }
4918 #endif /* CKSYSLOG */
4919 #endif /* CKLOGDIAL */
4920 #endif /* NOLOCAL */
4921 }
4922
4923 #ifndef NOLOCAL
4924 #ifdef CKLOGDIAL
4925
4926 /* D O L O G S H O W -- Show session/connection info */
4927
4928 /* Call with fc == 1 to show, fc == 0 to only calculate. */
4929 /* Returns session elapsed time in seconds. */
4930 /* If no session active, returns elapsed time of previous session, if any, */
4931 /* otherwise 0 */
4932
4933 long
dologshow(fc)4934 dologshow(fc) int fc; { /* SHOW (current) CONNECTION */
4935 long d1, d2, t1, t2 = 0, prev;
4936 char c, buf1[32], buf2[32], * info[32], * p, * s;
4937 char * xlogbuf, xbuf[CXLOGBUFL+1];
4938 int i, x = 0, z, ftp = 0, active = 0;
4939
4940 #ifdef NEWFTP
4941 extern char ftplogbuf[];
4942 extern long ftplogprev;
4943 extern int ftplogactive;
4944 if (fc & W_FTP) {
4945 fc &= 63;
4946 ftp = 1;
4947 xlogbuf = ftplogbuf;
4948 prev = ftplogprev;
4949 active = ftplogactive;
4950 } else {
4951 #endif /* NEWFTP */
4952 ftp = 0;
4953 xlogbuf = cxlogbuf;
4954 prev = cx_prev;
4955 active = cx_active;
4956 #ifdef NEWFTP
4957 }
4958 #endif /* NEWFTP */
4959
4960 debug(F101,"dologshow local","",local);
4961 debug(F101,"dologshow ftp","",ftp);
4962 debug(F111,"dologshow active",xlogbuf,active);
4963
4964 if (!xlogbuf[0]) {
4965 if (fc) {
4966 if (didsetlin || ftp)
4967 printf(" %s: No record.\n", ftp ? "FTP" : "Kermit");
4968 else
4969 printf(" %s: No connection.\n", ftp ? "FTP" : "Kermit");
4970 }
4971 return(prev);
4972 }
4973
4974 #ifdef NEWFTP
4975 if (ftp) {
4976 z = ftpisconnected() ? 1 : -1;
4977 } else {
4978 #endif /* NEWFTP */
4979 if (local) { /* See if we have an open connection */
4980 z = ttchk();
4981 debug(F101,"dologshow ttchk","",z);
4982 z = (z > -1) ? 1 : -2;
4983 } else {
4984 z = active ? 1 : -2;
4985 }
4986 #ifdef NEWFTP
4987 }
4988 #endif /* NEWFTP */
4989 if (z < 0L) {
4990 if (!fc)
4991 return(prev);
4992 else
4993 t2 = prev;
4994 }
4995 /* Note: NOT ckstrncpy! */
4996 strncpy(buf1,xlogbuf,17); /* Copy of just the timestamp */
4997 buf1[17] = NUL; /* Terminate it */
4998 ckstrncpy(xbuf,xlogbuf+18,CXLOGBUFL); /* Copy that can be poked */
4999 debug(F111,"dologshow prev",xbuf,prev);
5000
5001 xwords(xbuf,31,info,1); /* Break up into fields */
5002 d1 = mjd(buf1); /* Convert start time to MJD */
5003 ckstrncpy(buf2,ckdate(),31); /* Current date */
5004 d2 = mjd(buf2); /* Convert to MJD */
5005 p = buf1; /* Point to start time */
5006 p[11] = NUL;
5007 p[14] = NUL; /* Convert to seconds */
5008 t1 = atol(p+9) * 3600L + atol(p+12) * 60L + atol(p+15);
5009 p[11] = ':';
5010 p[14] = ':';
5011 p = buf2; /* Ditto for current time */
5012 p[11] = NUL;
5013 p[14] = NUL;
5014 if (z > -1L) {
5015 t2 = atol(p+9) * 3600L + atol(p+12) * 60L + atol(p+15);
5016 t2 = ((d2 - d1) * 86400L) + (t2 - t1); /* Elapsed time so far */
5017 }
5018 if (fc) {
5019 p = NULL;
5020 if (t2 > -1L) /* Convert seconds to hh:mm:ss */
5021 p = hhmmss(t2);
5022 if (z > -1)
5023 s = "Active";
5024 else if (z == -2)
5025 s = "Closed";
5026 else
5027 s = "Unknown";
5028 printf("\n"); /* Show results */
5029 printf(" Status: %s\n",s);
5030 printf(" Opened: %s\n",buf1);
5031 printf(" User: %s\n",info[1] ? info[1] : "");
5032 printf(" PID: %s\n",info[2] ? info[2] : "");
5033 for (i = 3; info[i]; i++) {
5034 c = info[i][0];
5035 s = (info[i]) ? info[i]+2 : "";
5036 switch (c) {
5037 case 'T': printf(" Type: %s\n", s); break;
5038 case 'N': printf(" To: %s\n", s); break;
5039 case 'P': printf(" Port: %s\n", s); break;
5040 case 'H': printf(" From: %s\n", s); break;
5041 case 'D': printf(" Device: %s\n", s); break;
5042 case 'O': printf(" Origin: %s\n", s); break;
5043 case 'E': break;
5044 default: printf(" %s\n",info[i] ? info[i] : "");
5045 }
5046 }
5047 if (z < 0L)
5048 printf(" Elapsed time: %s\n", hhmmss(t2));
5049 else
5050 printf(" Elapsed time: %s\n", p ? p : "(unknown)");
5051 x = 0;
5052 #ifdef NETCONN
5053 #ifdef SSHBUILTIN
5054 if ( IS_SSH() ) x++;
5055 #endif /* SSHBUILTIN */
5056 #ifdef CK_ENCRYPTION
5057 if (ck_tn_encrypting() && ck_tn_decrypting()) x++;
5058 #endif /* CK_ENCRYPTION */
5059 #ifdef CK_SSL
5060 if (tls_active_flag || ssl_active_flag) x++;
5061 #endif /* CK_SSL */
5062 #ifdef RLOGCODE
5063 #ifdef CK_KERBEROS
5064 #ifdef CK_ENCRYPTION
5065 if (ttnproto == NP_EK4LOGIN || ttnproto == NP_EK5LOGIN) x++;
5066 #endif /* CK_ENCRYPTION */
5067 #endif /* CK_KERBEROS */
5068 #endif /* RLOGCODE */
5069 #endif /* NETCONN */
5070 if (z > 0)
5071 printf(" Encrypted: %s\n", x ? "Yes" : "No");
5072 printf(" Log: %s\n", dialog ? diafil : "(none)");
5073 printf("\n");
5074 }
5075 return(t2 > -1L ? t2 : 0L);
5076 }
5077
5078 VOID
dologline()5079 dologline() {
5080 char * p;
5081 int n, m = 0;
5082
5083 dologend(); /* Previous session not closed out? */
5084 cx_active = 1; /* Record is active */
5085 cx_prev = 0L;
5086 p = ckdate(); /* Get timestamp */
5087 n = ckstrncpy(cxlogbuf,p,CXLOGBUFL-1); /* Start record off with it */
5088 if (!uidbuf[0]) {
5089 debug(F100,"dologline uidbuf empty","",0);
5090 #ifdef UNIX /* Who has whoami()... */
5091 ckstrncpy(uidbuf,(char *)whoami(),UIDBUFLEN);
5092 #else
5093 #ifdef STRATUS
5094 ckstrncpy(uidbuf,(char *)whoami(),UIDBUFLEN);
5095 #else
5096 ckstrncpy(uidbuf,"UNKNOWN",UIDBUFLEN);
5097 #endif /* STRATUS */
5098 #endif /* UNIX */
5099 }
5100 m = strlen(uidbuf) + strlen(myhost) + strlen(ttname) + 32;
5101 if (n+m < CXLOGBUFL-1) { /* Add serial device info */
5102 p = cxlogbuf+n;
5103 sprintf(p," %s %s T=SERIAL H=%s D=%s ", /* SAFE */
5104 uidbuf,
5105 ckgetpid(),
5106 myhost,
5107 ttname
5108 );
5109 } else
5110 ckstrncpy(cxlogbuf,"LOGLINE BUFFER OVERFLOW",CXLOGBUFL);
5111 debug(F110,"dologline",cxlogbuf,0);
5112 }
5113
5114 #ifdef NETCONN
5115 VOID
dolognet()5116 dolognet() {
5117 char * p, * s = "NET", * uu = uidbuf;
5118 char * port = "";
5119 int n, m, tcp = 0;
5120 char * h = NULL;
5121
5122 dologend(); /* Previous session not closed out? */
5123 cx_prev = 0L;
5124 cx_active = 1; /* Record is active */
5125 p = ckdate();
5126 n = ckstrncpy(cxlogbuf,p,CXLOGBUFL);
5127 #ifdef TCPSOCKET
5128 if (nettype == NET_TCPB || nettype == NET_TCPA) {
5129 tcp++;
5130 s = "TCP";
5131 } else if (nettype == NET_SSH) {
5132 s = "SSH";
5133 tcp++;
5134 }
5135 #endif /* TCPSOCKET */
5136 #ifdef ANYX25
5137 if (nettype == NET_SX25 || nettype == NET_VX25 || nettype == NET_IX25)
5138 s = "X25";
5139 #endif /* ANYX25 */
5140 #ifdef DECNET
5141 if (nettype == NET_DEC)
5142 s = "DECNET";
5143 #endif /* DECNET */
5144 #ifdef SUPERLAT
5145 if (nettype == NET_SLAT)
5146 s = "SUPERLAT";
5147 #endif /* SUPERLAT */
5148 #ifdef CK_NETBIOS
5149 if (nettype == NET_BIOS)
5150 s = "NETBIOS";
5151 #endif /* CK_NETBIOS */
5152
5153 if (!uu[0]) {
5154 debug(F100,"dolognet uidbuf empty","",0);
5155 #ifdef OS2ORUNIX /* Who has whoami()... */
5156 uu = (char *)whoami();
5157 #else
5158 #ifdef STRATUS
5159 uu = (char *)whoami();
5160 #else
5161 uu = "UNKNOWN";
5162 #endif /* STRATUS */
5163 #endif /* UNIX */
5164 }
5165 #ifdef TCPSOCKET
5166 if (tcp) {
5167 int k;
5168 makestr(&h,myhost);
5169 if ((k = ckindex(":",h,0,0,0)) > 0) {
5170 h[k-1] = NUL;
5171 port = &h[k];
5172 } else {
5173 int svcnum = gettcpport();
5174 if (svcnum > 0)
5175 port = ckitoa(svcnum);
5176 else
5177 port = "unk";
5178 }
5179 }
5180 #endif /* TCPSOCKET */
5181 m = strlen(uu) + strlen(myhost) + strlen(ttname) + strlen(s) + 32;
5182 if (n+m < CXLOGBUFL-1) { /* SAFE */
5183 p = cxlogbuf+n;
5184 sprintf(p," %s %s T=%s N=%s H=%s P=%s ",
5185 uu,
5186 ckgetpid(),
5187 s,
5188 ttname,
5189 myhost,
5190 port
5191 );
5192 } else
5193 ckstrncpy(cxlogbuf,"LOGNET BUFFER OVERFLOW",CXLOGBUFL);
5194 debug(F110,"dolognet cxlogbuf",cxlogbuf,0);
5195 if (h) makestr(&h,NULL);
5196 }
5197 #endif /* NETCONN */
5198 #endif /* CKLOGDIAL */
5199
5200 #ifndef NODIAL
5201 /*
5202 Parse a DIAL-related string, stripping enclosing braces, if any.
5203 */
5204 static int
dialstr(p,msg)5205 dialstr(p,msg) char **p; char *msg; {
5206 int x;
5207 char *s;
5208
5209 if ((x = cmtxt(msg, "", &s, xxstring)) < 0)
5210 return(x);
5211 s = brstrip(s); /* Strip braces around. */
5212 debug(F110,"dialstr",s,0);
5213 makestr(p,*s?s:NULL);
5214 return(success = 1);
5215 }
5216
5217 VOID
initmdm(x)5218 initmdm(x) int x; {
5219 MDMINF * p;
5220 int m;
5221
5222 mdmtyp = x; /* Set global modem type */
5223 debug(F101,"initmdm mdmtyp","",mdmtyp);
5224 debug(F101,"initmdm usermdm","",usermdm);
5225 if (x < 1) return;
5226
5227 m = usermdm ? usermdm : mdmtyp;
5228
5229 p = modemp[m]; /* Point to modem info struct, and */
5230 /* debug(F101,"initmdm p","",p); */
5231 if (p) {
5232 dialec = p->capas & CKD_EC; /* set DIAL ERROR-CORRECTION, */
5233 dialdc = p->capas & CKD_DC; /* DIAL DATA-COMPRESSION, and */
5234 mdmspd = p->capas & CKD_SB ? 0 : 1; /* DIAL SPEED-MATCHING from it. */
5235 dialfc = FLO_AUTO; /* Modem's local flow control.. */
5236 dialmax = p->max_speed;
5237 dialcapas = p->capas;
5238 dialesc = p->esc_char;
5239 } else if (mdmtyp > 0) {
5240 printf("WARNING: modem info for \"%s\" not filled in yet\n",
5241 gmdmtyp()
5242 );
5243 }
5244
5245 /* Reset or set the SET DIAL STRING items ... */
5246
5247 #ifdef DEBUG
5248 if (deblog) {
5249 debug(F110,"initmdm dialini",dialini,0);
5250 debug(F110,"initmdm dialmstr ",dialmstr,0);
5251 debug(F110,"initmdm dialmprmt",dialmprmt,0);
5252 debug(F110,"initmdm dialcmd",dialcmd,0);
5253 debug(F110,"initmdm dialdcon",dialdcon,0);
5254 debug(F110,"initmdm dialdcoff",dialdcoff,0);
5255 debug(F110,"initmdm dialecon",dialecon,0);
5256 debug(F110,"initmdm dialecoff",dialecoff,0);
5257 debug(F110,"initmdm dialhcmd",dialhcmd,0);
5258 debug(F110,"initmdm dialhwfc",dialhwfc,0);
5259 debug(F110,"initmdm dialswfc",dialswfc,0);
5260 debug(F110,"initmdm dialnofc",dialnofc,0);
5261 debug(F110,"initmdm dialtone",dialtone,0);
5262 debug(F110,"initmdm dialpulse",dialpulse,0);
5263 debug(F110,"initmdm dialname",dialname,0);
5264 debug(F110,"initmdm dialaaon",dialaaon,0);
5265 debug(F110,"initmdm dialaaoff",dialaaoff,0);
5266 debug(F110,"initmdm dialx3",dialx3,0);
5267 debug(F110,"initmdm dialspon",dialspon,0);
5268 debug(F110,"initmdm dialspoff",dialspoff,0);
5269 debug(F110,"initmdm dialvol1",dialvol1,0);
5270 debug(F110,"initmdm dialvol2",dialvol2,0);
5271 debug(F110,"initmdm dialvol3",dialvol3,0);
5272 debug(F110,"initmdm dialini2",dialini2,0);
5273 }
5274 #endif /* DEBUG */
5275
5276 if (usermdm && p) { /* USER-DEFINED: copy info from specified template */
5277
5278 makestr(&dialini ,p->wake_str);
5279 makestr(&dialmstr ,p->dmode_str);
5280 makestr(&dialmprmt,p->dmode_prompt);
5281 makestr(&dialcmd ,p->dial_str);
5282 makestr(&dialdcon ,p->dc_on_str);
5283 makestr(&dialdcoff,p->dc_off_str);
5284 makestr(&dialecon ,p->ec_on_str);
5285 makestr(&dialecoff,p->ec_off_str);
5286 makestr(&dialhcmd ,p->hup_str);
5287 makestr(&dialhwfc ,p->hwfc_str);
5288 makestr(&dialswfc ,p->swfc_str);
5289 makestr(&dialnofc ,p->nofc_str);
5290 makestr(&dialtone ,p->tone);
5291 makestr(&dialpulse,p->pulse);
5292 makestr(&dialname ,"This space available (use SET MODEM NAME)");
5293 makestr(&dialaaon ,p->aa_on_str);
5294 makestr(&dialaaoff,p->aa_off_str);
5295 makestr(&dialx3 ,p->ignoredt);
5296 makestr(&dialspon ,p->sp_on_str);
5297 makestr(&dialspoff,p->sp_off_str);
5298 makestr(&dialvol1 ,p->vol1_str);
5299 makestr(&dialvol2 ,p->vol2_str);
5300 makestr(&dialvol3 ,p->vol3_str);
5301 makestr(&dialini2 ,p->ini2);
5302
5303 } else { /* Not user-defined, so wipe out overrides */
5304
5305 if (dialini) makestr(&dialini,NULL); /* Init-string */
5306 if (dialmstr) makestr(&dialmstr,NULL); /* Dial-mode-str */
5307 if (dialmprmt) makestr(&dialmprmt,NULL); /* Dial-mode-pro */
5308 if (dialcmd) makestr(&dialcmd,NULL); /* Dial-command */
5309 if (dialdcon) makestr(&dialdcon,NULL); /* DC ON command */
5310 if (dialdcoff) makestr(&dialdcoff,NULL); /* DC OFF command */
5311 if (dialecon) makestr(&dialecon,NULL); /* EC ON command */
5312 if (dialecoff) makestr(&dialecoff,NULL); /* EC OFF command */
5313 if (dialhcmd) makestr(&dialhcmd,NULL); /* Hangup command */
5314 if (dialhwfc) makestr(&dialhwfc,NULL); /* Flow control... */
5315 if (dialswfc) makestr(&dialswfc,NULL); /* */
5316 if (dialnofc) makestr(&dialnofc,NULL); /* */
5317 if (dialtone) makestr(&dialtone,NULL); /* Dialing method */
5318 if (dialpulse) makestr(&dialpulse,NULL); /* */
5319 if (dialname) makestr(&dialname,NULL); /* Modem name */
5320 if (dialaaon) makestr(&dialaaon,NULL); /* Autoanswer On */
5321 if (dialaaoff) makestr(&dialaaoff,NULL); /* Autoanswer Off */
5322 if (dialx3) makestr(&dialx3,NULL); /* Ignore dialtone */
5323 if (dialspon) makestr(&dialspon,NULL); /* Speaker On */
5324 if (dialspoff) makestr(&dialspoff,NULL); /* Speaker Off */
5325 if (dialvol1) makestr(&dialvol1,NULL); /* Low volume */
5326 if (dialvol2) makestr(&dialvol2,NULL); /* Medium volume */
5327 if (dialvol3) makestr(&dialvol3,NULL); /* High volume */
5328 if (dialini2) makestr(&dialini2,NULL); /* Init string 2 */
5329 }
5330 if (autoflow) /* Maybe change flow control */
5331 setflow();
5332
5333 #ifndef MINIDIAL
5334 #ifdef OLDTBCODE
5335 tbmodel = 0; /* If it's a Telebit, we don't know the model yet */
5336 #endif /* OLDTBCODE */
5337 #endif /* MINIDIAL */
5338 }
5339
5340 #ifdef COMMENT
5341 /* Not implemented yet */
5342 int
setanswer()5343 setanswer() {
5344 int x, y;
5345 extern int ans_cid, ans_ring;
5346 if ((x = cmkey(answertab,nanswertab,"","",xxstring)) < 0)
5347 return(x);
5348 switch (x) {
5349 case XYA_CID:
5350 return(seton(&ans_cid));
5351 case XYA_RNG:
5352 y = cmnum("How many rings before answering","1",10,&x,xxstring);
5353 y = setnum(&ans_rings,x,y,254);
5354 return(y);
5355 }
5356 }
5357 #endif /* COMMENT */
5358
5359 int
setmodem()5360 setmodem() { /* SET MODEM */
5361
5362 int x, y, z;
5363 long zz;
5364 struct FDB k1, k2;
5365 extern int mdmset;
5366
5367 cmfdbi(&k1,_CMKEY,
5368 "Modem parameter","","",nsetmdm, 0, xxstring, setmdm, &k2);
5369 cmfdbi(&k2,_CMKEY,"","","",nmdm,0,xxstring,mdmtab,NULL);
5370 x = cmfdb(&k1);
5371 if (x < 0) { /* Error */
5372 if (x == -2 || x == -9)
5373 printf("?No keywords match: \"%s\"\n",atmbuf);
5374 return(x);
5375 }
5376 y = cmresult.nresult; /* Keyword value */
5377 if (cmresult.fdbaddr == &k2) { /* Modem-type keyword table */
5378 if ((x = cmcfm()) < 0)
5379 return(x);
5380 usermdm = 0;
5381 initmdm(cmresult.nresult); /* Set the modem type. */
5382 return(success = 1); /* Done */
5383 }
5384 switch (cmresult.nresult) { /* SET MODEM keyword table. */
5385 #ifdef MDMHUP
5386 case XYDMHU: /* DIAL MODEM-HANGUP */
5387 if ((y = cmkey(mdmhang,4,"how to hang up modem",
5388 "modem-command", xxstring)) < 0)
5389 return(y);
5390 if ((x = cmcfm()) < 0)
5391 return(x);
5392 dialmhu = y;
5393 #ifdef COMMENT
5394 /* Nope, I fixed it (2001 11 08) */
5395 #ifdef CK_SCOV5
5396 if (dialmhu == 0 && !quiet) {
5397 printf(
5398 "\n WARNING: RS-232 signal sampling and manipulation do not work\n"
5399 );
5400 printf(
5401 " in the standard SCO OSR5 serial i/o drivers. SET MODEM HANGUP-METHOD\n"
5402 );
5403 printf(
5404 " MODEM-COMMAND is recommended for OSR5.\n\n"
5405 );
5406 }
5407 #endif /* CK_SCOV5 */
5408 #endif /* COMMENT */
5409 return(success = 1);
5410 #endif /* MDMHUP */
5411
5412 case XYDCAP:
5413 zz = 0L;
5414 y = 0;
5415 while (y != -3) {
5416 if ((y = cmkey(mdmcap,nmdmcap,
5417 "capability of modem", "", xxstring)) < 0) {
5418 if (y == -3)
5419 break;
5420 else
5421 return(y);
5422 }
5423 zz |= y;
5424 }
5425 if ((x = cmcfm()) < 0)
5426 return(x);
5427 dialcapas = zz;
5428 debug(F101,"setmodem autoflow","",autoflow);
5429 debug(F101,"setmodem flow 1","",flow);
5430 if (autoflow) /* Maybe change flow control */
5431 setflow();
5432 debug(F101,"setmodem flow 2","",flow);
5433 mdmspd = zz & CKD_SB ? 0 : 1; /* Set MODEM SPEED-MATCHING from it. */
5434 return(success = 1);
5435
5436 case XYDMAX:
5437 #ifdef TN_COMPORT
5438 if (network && istncomport())
5439 x = cmkey(tnspdtab,ntnspd,line,"",xxstring);
5440 else
5441 #endif /* TN_COMPORT */
5442 x = cmkey(spdtab,nspd,line,"",xxstring);
5443 if (x < 0) {
5444 if (x == -3) printf("?value required\n");
5445 return(x);
5446 }
5447 if ((y = cmcfm()) < 0) return(y);
5448 dialmax = (long) x * 10L;
5449 if (dialmax == 70) dialmax = 75;
5450 return(success = 1);
5451
5452 case XYDSTR: /* These moved from SET DIAL */
5453 case XYDDC:
5454 case XYDEC:
5455 case XYDESC:
5456 case XYDFC:
5457 case XYDKSP:
5458 case XYDSPD:
5459 case XYDDIA:
5460 return(setdial(x));
5461
5462 case XYDTYP:
5463 if ((y = cmkey(mdmtab,nmdm,"modem type","none", xxstring)) < 0)
5464 return(y);
5465 if (y == dialudt) { /* User-defined modem type */
5466 if ((x = cmkey(mdmtab,nmdm,"based on existing modem type",
5467 "unknown", xxstring)) < 0)
5468 return(x);
5469 }
5470 if ((z = cmcfm()) < 0)
5471 return(z);
5472 usermdm = 0;
5473 usermdm = (y == dialudt) ? x : 0;
5474 initmdm(y);
5475 mdmset = (mdmtyp > 0);
5476 return(success = 1);
5477
5478 case XYDNAM:
5479 return(dialstr(&dialname,"Descriptive name for modem"));
5480
5481 case XYDMCD: /* SET MODEM CARRIER-WATCH */
5482 return(setdcd());
5483
5484 case XYDSPK: /* SET MODEM SPEAKER */
5485 return(seton(&mdmspk));
5486
5487 case XYDVOL: /* SET MODEM VOLUME */
5488 if ((x = cmkey(voltab,3,"","medium",xxstring)) < 0)
5489 return(x);
5490 if ((y = cmcfm()) < 0)
5491 return(y);
5492 mdmvol = x;
5493 return(success = 1);
5494
5495 default:
5496 printf("Unexpected SET MODEM parameter\n");
5497 return(-9);
5498 }
5499 }
5500
5501 static int /* Set DIAL command options */
setdial(y)5502 setdial(y) int y; {
5503 int x = 0, z = 0;
5504 char *s = NULL;
5505
5506 if (y < 0)
5507 if ((y = cmkey(dialtab,ndial,"","",xxstring)) < 0)
5508 return(y);
5509 switch (y) {
5510 case XYDHUP: /* DIAL HANGUP */
5511 return(seton(&dialhng));
5512 case XYDINI: /* DIAL INIT-STRING */
5513 return(dialstr(&dialini,"Modem initialization string"));
5514 case XYDNPR: /* DIAL PREFIX */
5515 return(dialstr(&dialnpr,"Telephone number prefix"));
5516 case XYDDIA: /* DIAL DIAL-COMMAND */
5517 x = cmtxt("Dialing command for modem,\n\
5518 include \"%s\" to stand for phone number,\n\
5519 for example, \"set dial dial-command ATDT%s\\13\"",
5520 "",
5521 &s,
5522 xxstring);
5523 if (x < 0 && x != -3) /* Handle parse errors */
5524 return(x);
5525 s = brstrip(s); /* Strip braces or quotes */
5526 y = x = strlen(s); /* Get length of text */
5527 if (y > 0) { /* If there is any text (left), */
5528 for (x = 0; x < y; x++) { /* make sure they included "%s" */
5529 if (s[x] != '%') continue;
5530 if (s[x+1] == 's') break;
5531 }
5532 if (x == y) {
5533 printf(
5534 "?Dial-command must contain \"%cs\" for phone number.\n",'%');
5535 return(-9);
5536 }
5537 }
5538 if (dialcmd) { /* Free any previous string. */
5539 free(dialcmd);
5540 dialcmd = (char *) 0;
5541 }
5542 if (y > 0) {
5543 dialcmd = malloc(y + 1); /* Allocate space for it */
5544 if (dialcmd)
5545 strcpy(dialcmd,s); /* and make a safe copy. */
5546 }
5547 return(success = 1);
5548 #ifndef NOXFER
5549 case XYDKSP: /* DIAL KERMIT-SPOOF */
5550 return(seton(&dialksp));
5551 #endif /* NOXFER */
5552 case XYDTMO: /* DIAL TIMEOUT */
5553 y = cmnum("Seconds to wait for call completion","0",10,&x,xxstring);
5554 if (y < 0) return(y);
5555 y = cmnum("Kermit/modem timeout differential","10",10,&z,xxstring);
5556 if (y < 0) return(y);
5557 if ((y = cmcfm()) < 0)
5558 return(y);
5559 dialtmo = x;
5560 mdmwaitd = z;
5561 case XYDESC: /* DIAL ESCAPE-CHARACTER */
5562 y = cmnum("ASCII value of character to escape back to modem",
5563 "43",10,&x,xxstring);
5564 y = setnum(&dialesc,x,y,128);
5565 if (y > -1 && dialesc < 0) /* No escape character */
5566 dialmhu = 0; /* So no hangup by modem command */
5567 return(y);
5568 case XYDDPY: /* DIAL DISPLAY */
5569 return(seton(&dialdpy));
5570 case XYDSPD: /* DIAL SPEED-MATCHING */
5571 /* used to be speed-changing */
5572 if ((y = seton(&mdmspd)) < 0) return(y);
5573 #ifdef COMMENT
5574 mdmspd = 1 - mdmspd; /* so here we reverse the meaning */
5575 #endif /* COMMENT */
5576 return(success = 1);
5577 case XYDMNP: /* DIAL MNP-ENABLE */
5578 case XYDEC: /* DIAL ERROR-CORRECTION */
5579 x = seton(&dialec);
5580 if (x > 0)
5581 if (!dialec) dialdc = 0; /* OFF also turns off compression */
5582 return(x);
5583
5584 case XYDDC: /* DIAL COMPRESSION */
5585 x = seton(&dialdc);
5586 if (x > 0)
5587 if (dialdc) dialec = 1; /* ON also turns on error correction */
5588 return(x);
5589
5590 #ifdef MDMHUP
5591 case XYDMHU: /* DIAL MODEM-HANGUP */
5592 return(seton(&dialmhu));
5593 #endif /* MDMHUP */
5594
5595 #ifndef NOSPL
5596 case XYDDIR: /* DIAL DIRECTORY (zero or more) */
5597 return(parsdir(0)); /* 0 means DIAL */
5598 #endif /* NOSPL */
5599
5600 case XYDSTR: /* DIAL STRING */
5601 if ((y = cmkey(mdmcmd,nmdmcmd,"","",xxstring)) < 0) return(y);
5602 switch (y) {
5603 case XYDS_AN: /* Autoanswer ON/OFF */
5604 case XYDS_DC: /* Data compression ON/OFF */
5605 case XYDS_EC: /* Error correction ON/OFF */
5606 if ((x = cmkey(onoff,2,"","on",xxstring)) < 0)
5607 return(x);
5608 sprintf(tmpbuf,"Modem's command to %sable %s", /* SAFE */
5609 x ? "en" : "dis",
5610 (y == XYDS_DC) ? "compression" :
5611 ((y == XYDS_EC) ? "error-correction" :
5612 "autoanswer")
5613 );
5614 if (x) {
5615 if (y == XYDS_DC)
5616 return(dialstr(&dialdcon,tmpbuf));
5617 else if (y == XYDS_EC)
5618 return(dialstr(&dialecon,tmpbuf));
5619 else
5620 return(dialstr(&dialaaon,tmpbuf));
5621 } else {
5622 if (y == XYDS_DC)
5623 return(dialstr(&dialdcoff,tmpbuf));
5624 else if (y == XYDS_EC)
5625 return(dialstr(&dialecoff,tmpbuf));
5626 else
5627 return(dialstr(&dialaaoff,tmpbuf));
5628 }
5629 case XYDS_HU: /* hangup command */
5630 return(dialstr(&dialhcmd,"Modem's hangup command"));
5631 case XYDS_HW: /* hwfc */
5632 return(dialstr(&dialhwfc,
5633 "Modem's command to enable hardware flow control"));
5634 case XYDS_IN: /* init */
5635 return(dialstr(&dialini,"Modem's initialization string"));
5636 case XYDS_NF: /* no flow control */
5637 return(dialstr(&dialnofc,
5638 "Modem's command to disable local flow control"));
5639 case XYDS_PX: /* prefix */
5640 return(dialstr(&dialnpr,"Telephone number prefix for dialing"));
5641 case XYDS_SW: /* swfc */
5642 return(dialstr(&dialswfc,
5643 "Modem's command to enable local software flow control"));
5644 case XYDS_DT: /* tone dialing */
5645 return(dialstr(&dialtone,
5646 "Command to configure modem for tone dialing"));
5647 case XYDS_DP: /* pulse dialing */
5648 return(dialstr(&dialpulse,
5649 "Command to configure modem for pulse dialing"));
5650 case XYDS_MS: /* dial mode string */
5651 return(dialstr(&dialmstr,
5652 "Command to enter dial mode"));
5653 case XYDS_MP: /* dial mode prompt */
5654 return(dialstr(&dialmprmt,
5655 "Modem response upon entering dial mode"));
5656 case XYDS_SP: /* SPEAKER OFF */
5657 if ((x = cmkey(onoff,2,"","on",xxstring)) < 0) return(x);
5658 if (x)
5659 return(dialstr(&dialspon,"Command to turn modem speaker on"));
5660 else
5661 return(dialstr(&dialspoff,"Command to turn modem speaker off"));
5662
5663 case XYDS_VO: /* VOLUME LOW */
5664 if ((x = cmkey(voltab,3,"","medium",xxstring)) < 0) return(x);
5665 switch (x) {
5666 case 0:
5667 case 1:
5668 return(dialstr(&dialvol1,
5669 "Command for low modem speaker volume"));
5670 case 2:
5671 return(dialstr(&dialvol2,
5672 "Command for medium modem speaker volume"));
5673
5674 case 3:
5675 return(dialstr(&dialvol3,
5676 "Command for high modem speaker volume"));
5677 default:
5678 return(-2);
5679 }
5680
5681 case XYDS_ID: /* IGNORE-DIALTONE */
5682 return(dialstr(&dialx3,
5683 "Command to tell modem to ignore dialtone"));
5684
5685 case XYDS_I2: /* PREDIAL-INIT */
5686 return(dialstr(&dialini2,
5687 "Command to send to modem just prior to dialing"));
5688
5689 default:
5690 printf("?Unexpected SET DIAL STRING parameter\n");
5691 }
5692
5693 case XYDFC: /* DIAL FLOW-CONTROL */
5694 if ((y = cmkey(dial_fc,4,"","auto",xxstring)) < 0) return(y);
5695 if ((x = cmcfm()) < 0) return(x);
5696 dialfc = y;
5697 return(success = 1);
5698
5699 case XYDMTH: { /* DIAL METHOD */
5700 extern int dialmauto;
5701 if ((y = cmkey(dial_m,ndial_m,"","default",xxstring)) < 0)
5702 return(y);
5703 if ((x = cmcfm()) < 0)
5704 return(x);
5705 if (y == XYDM_A) { /* AUTO */
5706 dialmauto = 1; /* local country code, if known. */
5707 dialmth = XYDM_D;
5708 } else {
5709 dialmauto = 0; /* use the method specified */
5710 dialmth = y;
5711 }
5712 return(success = 1);
5713 }
5714 case XYDRTM:
5715 y = cmnum("Number of times to try dialing a number",
5716 "1",10,&x,xxstring);
5717 z = setnum(&dialrtr,x,y,-1);
5718 if (z > -1 && dialrtr < 0) {
5719 printf("?Sorry, negative dial retries not valid: %d\n",dialrtr);
5720 return(-9);
5721 }
5722 return(z);
5723
5724 case XYDINT:
5725 y = cmnum("Seconds to wait between redial attempts",
5726 "30",10,&x,xxstring);
5727 z = setnum(&dialint,x,y,-1);
5728 if (z > -1 && dialint < 0) {
5729 printf("?Sorry, negative dial interval not valid: %d\n",dialint);
5730 return(-9);
5731 }
5732 return(z);
5733
5734 case XYDLAC: /* DIAL AREA-CODE */
5735 if ((x = dialstr(&diallac,"Area code you are calling from")) < 0)
5736 return(x);
5737 if (diallac) {
5738 if (!rdigits(diallac)) {
5739 printf("?Sorry, area code must be numeric\n");
5740 if (*diallac == '(')
5741 printf("(please omit the parentheses)\n");
5742 if (*diallac == '/')
5743 printf("(no slashes, please)\n");
5744 if (diallac) free(diallac);
5745 diallac = NULL;
5746 return(-9);
5747 }
5748 }
5749 return(x);
5750
5751 case XYDCNF: /* CONFIRMATION */
5752 return(success = seton(&dialcnf));
5753
5754 case XYDCVT: /* CONVERT-DIRECTORY */
5755 if ((y = cmkey(dcnvtab,3,"","ask",xxstring)) < 0)
5756 return(y);
5757 if ((x = cmcfm()) < 0)
5758 return(x);
5759 dialcvt = y;
5760 return(success = 1);
5761
5762 case XYDLCC: /* DIAL COUNTRY-CODE */
5763 x = dialstr(&diallcc,"Country code you are calling from");
5764 if (x < 1) return(x);
5765 if (diallcc) {
5766 if (!rdigits(diallcc)) {
5767 printf("?Sorry, country code must be numeric\n");
5768 if (*diallcc == '+')
5769 printf("(please omit the plus sign)\n");
5770 if (diallcc) free(diallcc);
5771 diallcc = NULL;
5772 return(-9);
5773 }
5774 if (!strcmp(diallcc,"1")) { /* Set defaults for USA and Canada */
5775 if (!dialldp) /* Long-distance prefix */
5776 makestr(&dialldp,"1");
5777 if (!dialixp) /* International dialing prefix */
5778 makestr(&dialixp,"011");
5779 if (ntollfree == 0) { /* Toll-free area codes */
5780 if ((dialtfc[0] = malloc(4))) {
5781 strcpy(dialtfc[0],"800"); /* 1970-something */
5782 ntollfree++;
5783 if ((dialtfc[1] = malloc(4))) {
5784 strcpy(dialtfc[1],"888"); /* 1996 */
5785 ntollfree++;
5786 if ((dialtfc[2] = malloc(4))) {
5787 strcpy(dialtfc[2],"877"); /* 5 April 1998 */
5788 ntollfree++;
5789 if ((dialtfc[3] = malloc(4))) {
5790 strcpy(dialtfc[3],"866"); /* 2000? */
5791 ntollfree++;
5792 }
5793 }
5794 }
5795 }
5796 }
5797 if (!dialtfp) /* Toll-free dialing prefix */
5798 makestr(&dialtfp,"1");
5799 #ifdef COMMENT
5800 /* The time for this is past */
5801 } else if (!strcmp(diallcc,"358") &&
5802 ((int) strcmp(zzndate(),"19961011") > 0)
5803 ) { /* Finland */
5804 if (!dialldp) /* Long-distance prefix */
5805 makestr(&dialldp,"9");
5806 if (!dialixp) /* International dialing prefix */
5807 makestr(&dialixp,"990");
5808 #endif /* COMMENT */
5809 } else { /* Everywhere else ... */
5810 if (!dialldp) {
5811 if ((dialldp = malloc(4)))
5812 strcpy(dialldp,"0");
5813 }
5814 if (!dialixp) {
5815 if ((dialixp = malloc(4)))
5816 strcpy(dialixp,"00");
5817 }
5818 }
5819 if (!strcmp(diallcc,"33")) /* France */
5820 dialfld = 1; /* Long-distance dialing is forced */
5821 }
5822 return(success = 1);
5823
5824 case XYDIXP: /* DIAL INTL-PREFIX */
5825 return(dialstr(&dialixp,"International dialing prefix"));
5826
5827 case XYDIXS: /* DIAL INTL-SUFFIX */
5828 return(dialstr(&dialixs,"International dialing suffix"));
5829
5830 case XYDLDP: /* DIAL LD-PREFIX */
5831 return(dialstr(&dialldp,"Long-distance dialing prefix"));
5832
5833 case XYDLDS: /* DIAL LD-SUFFIX */
5834 return(dialstr(&diallds,"Long-distance dialing suffix"));
5835
5836 case XYDLCP: /* DIAL LC-PREFIX */
5837 return(dialstr(&diallcp,"Local dialing prefix"));
5838
5839 case XYDLCS: /* DIAL LC-SUFFIX */
5840 return(dialstr(&diallcs,"Local dialing suffix"));
5841
5842 #ifdef COMMENT
5843 case XYDPXX: /* DIAL PBX-EXCHANGE */
5844 return(dialstr(&dialpxx,"Exchange of PBX you are calling from"));
5845 #endif /* COMMENT */
5846
5847 case XYDPXI: { /* DIAL PBX-INTERNAL-PREFIX */
5848 #ifdef COMMENT
5849 return(dialstr(&dialpxi,
5850 "Internal-call prefix of PBX you are calling from"));
5851 #else
5852 int x;
5853 if ((x = cmtxt("Internal-call prefix of PBX you are calling from",
5854 "",&s,NULL)) < 0) /* Don't evaluate */
5855 return(x);
5856 #ifndef NOSPL
5857 if (*s) {
5858 char c, * p = tmpbuf;
5859 if (*s == '\\') {
5860 c = *(s+1);
5861 if (isupper(c)) c = tolower(c);
5862 if (c != 'f' &&
5863 ckstrcmp(s,"\\v(d$px)",8,0) &&
5864 ckstrcmp(s,"\\v(d$pxx)",9,0) &&
5865 ckstrcmp(s,"\\v(d$p)",7,0)) {
5866 x = TMPBUFSIZ;
5867 zzstring(s,&p,&x);
5868 s = tmpbuf;
5869 }
5870 }
5871 }
5872 #endif /* NOSPL */
5873 makestr(&dialpxi,s);
5874 return(1);
5875 }
5876 #endif /* COMMENT */
5877
5878 case XYDPXO: /* DIAL PBX-OUTSIDE-PREFIX */
5879 return(dialstr(&dialpxo,
5880 "Outside-line prefix of PBX you are calling from"));
5881
5882 case XYDSFX: /* DIAL INTL-SUFFIX */
5883 return(dialstr(&dialsfx," Telephone number suffix for dialing"));
5884
5885 case XYDSRT: /* DIAL SORT */
5886 return(success = seton(&dialsrt));
5887
5888 case XYDPXX: /* DIAL PBX-EXCHANGE */
5889 case XYDTFC: { /* DIAL TOLL-FREE-AREA-CODE */
5890 int n, i; /* (zero or more of them...) */
5891 char * p[MAXTOLLFREE]; /* Temporary pointers */
5892 char * m;
5893 for (n = 0; n < MAXTOLLFREE; n++) {
5894 if (n == 0) {
5895 m = (y == XYDTFC) ?
5896 "Toll-free area code(s) in the country you are calling from"
5897 : "Exchange(s) of PBX you are calling from";
5898 } else {
5899 m = (y == XYDTFC) ?
5900 "Another toll-free area code"
5901 : "Another PBX exchange";
5902 }
5903 if ((x = cmfld(m,"",&s,xxstring)) < 0)
5904 break;
5905 if (s) {
5906 int k;
5907 k = (int) strlen(s);
5908 if (k > 0) {
5909 if ((p[n] = malloc(k + 1)))
5910 strcpy(p[n], s); /* safe */
5911 } else break;
5912 } else break;
5913 }
5914 if (x == -3) { /* Command was successful */
5915 int m;
5916 m = (y == XYDTFC) ? ntollfree : ndialpxx;
5917 if ((x = cmcfm()) < 0)
5918 return(x);
5919 x = 1;
5920 for (i = 0; i < m; i++) { /* Remove old list, if any */
5921 if (y == XYDTFC)
5922 makestr(&(dialtfc[i]),NULL);
5923 else
5924 makestr(&(dialpxx[i]),NULL);
5925 }
5926 if (y == XYDTFC)
5927 ntollfree = n; /* New count */
5928 else
5929 ndialpxx = n;
5930 for (i = 0; i < n; i++) { /* New list */
5931 if (y == XYDTFC)
5932 makestr(&(dialtfc[i]),p[i]);
5933 else
5934 makestr(&(dialpxx[i]),p[i]);
5935 }
5936 x = 1;
5937 }
5938 for (i = 0; i < n; i++)
5939 if (p[i]) free(p[i]);
5940 return(x);
5941 }
5942
5943 case XYDTFP: /* TOLL-FREE-PREFIX */
5944 return(dialstr(&dialtfp,
5945 " Long-distance prefix for toll-free dialing"));
5946
5947 case XYDCON: /* CONNECT */
5948 z = -1;
5949 if ((y = cmkey(crrtab,ncrr,"","auto",xxstring)) < 0) return(y);
5950 if (y != CAR_OFF) /* AUTO or ON? */
5951 if ((z = cmkey(qvtab,nqvt,"","verbose",xxstring)) < 0) return(z);
5952 if ((x = cmcfm()) < 0) return(x);
5953 if (z > -1)
5954 dialcq = z;
5955 dialcon = y;
5956 return(success = 1);
5957
5958 case XYDRSTR: /* RESTRICT */
5959 if ((y = cmkey(drstrtab,4,"","none",xxstring)) < 0) return(y);
5960 if ((x = cmcfm()) < 0) return(x);
5961 dialrstr = y;
5962 return(success = 1);
5963
5964 case XYDLLAC: { /* Local area-code list */
5965 int n, i; /* (zero or more of them...) */
5966 char * p[MAXLOCALAC]; /* Temporary pointers */
5967 for (n = 0; n < MAXLOCALAC; n++) {
5968 if ((x = cmfld(
5969 "Area code to which calls from your area are local",
5970 "",&s,xxstring)) < 0)
5971 break;
5972 if (s) {
5973 int k;
5974 k = (int) strlen(s);
5975 if (k > 0) {
5976 if ((p[n] = malloc(k + 1)))
5977 strcpy(p[n], s); /* safe */
5978 } else break;
5979 } else break;
5980 }
5981 if (x == -3) { /* Command was successful */
5982 if ((x = cmcfm()) < 0)
5983 return(x);
5984 for (i = 0; i < nlocalac; i++) /* Remove old list, if any */
5985 if (diallcac[i]) {
5986 free(diallcac[i]);
5987 diallcac[i] = NULL;
5988 }
5989 nlocalac = n; /* New count */
5990 for (i = 0; i < nlocalac; i++) /* New list */
5991 diallcac[i] = p[i];
5992 return(success = 1);
5993 } else { /* Parse error, undo everything */
5994 for (i = 0; i < n; i++)
5995 if (p[i]) free(p[i]);
5996 return(x);
5997 }
5998 }
5999
6000 case XYDFLD:
6001 return(success = seton(&dialfld));
6002
6003 case XYDIDT: /* DIAL IGNORE-DIALTONE */
6004 return(seton(&dialidt));
6005
6006 case XYDPAC:
6007 y = cmnum(
6008 "Milliseconds to pause between each character sent to dialer",
6009 "",10,&x,xxstring);
6010 return(setnum(&dialpace,x,y,9999));
6011
6012 #ifndef NOSPL
6013 case XYDMAC:
6014 if ((x = cmfld("Name of macro to execute just prior to dialing",
6015 "",&s,xxstring)) < 0) {
6016 if (x == -3)
6017 s = NULL;
6018 else
6019 return(x);
6020 }
6021 if (s) {
6022 if (!*s) {
6023 s = NULL;
6024 } else {
6025 ckstrncpy(line,s,LINBUFSIZ);
6026 s = line;
6027 }
6028 }
6029 if ((x = cmcfm()) < 0)
6030 return(x);
6031 makestr(&dialmac,s);
6032 return(success = 1);
6033 #endif /* NOSPL */
6034
6035 case XYDPUCC: /* Pulse country codes */
6036 case XYDTOCC: { /* Tone country codes */
6037 int n, i;
6038 char * p[MAXTPCC];
6039 char * m;
6040 for (n = 0; n < MAXTPCC; n++) {
6041 if (n == 0) {
6042 m = (y == XYDPUCC) ?
6043 "Country code where Pulse dialing is required"
6044 : "Country code where Tone dialing is available";
6045 } else
6046 m = "Another country code";
6047 if ((x = cmfld(m,"",&s,xxstring)) < 0)
6048 break;
6049 if (s) {
6050 int k;
6051 k = (int) strlen(s);
6052 if (k > 0) {
6053 if ((p[n] = malloc(k + 1)))
6054 strcpy(p[n], s); /* safe */
6055 } else break;
6056 } else break;
6057 }
6058 if (x == -3) { /* Command was successful */
6059 int m;
6060 m = (y == XYDPUCC) ? ndialpucc : ndialtocc;
6061 if ((x = cmcfm()) < 0)
6062 return(x);
6063 x = 1;
6064 for (i = 0; i < m; i++) { /* Remove old list, if any */
6065 if (y == XYDPUCC)
6066 makestr(&(dialpucc[i]),NULL);
6067 else
6068 makestr(&(dialtocc[i]),NULL);
6069 }
6070 if (y == XYDPUCC) {
6071 ndialpucc = n; /* New count */
6072 } else {
6073 ndialtocc = n;
6074 }
6075 for (i = 0; i < n; i++) { /* New list */
6076 if (y == XYDPUCC) {
6077 makestr(&(dialpucc[i]),p[i]);
6078 } else {
6079 makestr(&(dialtocc[i]),p[i]);
6080 }
6081 }
6082 x = 1;
6083 }
6084 for (i = 0; i < n; i++)
6085 if (p[i]) free(p[i]);
6086 return(x);
6087 }
6088 case XYDTEST:
6089 return(seton(&dialtest));
6090
6091 default:
6092 printf("?Unexpected SET DIAL parameter\n");
6093 return(-9);
6094 }
6095 }
6096
6097 #ifndef NOSHOW
6098 int /* SHOW MODEM */
6099 shomodem() {
6100 MDMINF * p;
6101 int x, n, mdm;
6102 char c;
6103 long zz;
6104
6105 #ifdef IKSD
6106 if (inserver) {
6107 printf("Sorry, command disabled\r\n");
6108 return(success = 0);
6109 }
6110 #endif /* IKSD */
6111
6112 shmdmlin();
6113 printf("\n");
6114
6115 mdm = (mdmtyp > 0) ? mdmtyp : mdmsav;
6116 p = (mdm > 0) ? modemp[mdm] : NULL;
6117
6118 if (p) {
6119 printf(" %s\n\n", dialname ? dialname : p->name);
6120
6121 printf(" Modem capabilities: ");
6122 zz = dialcapas ? dialcapas : p->capas;
6123 if (!zz) {
6124 printf(" (none)");
6125 } else {
6126 if (zz & CKD_AT) printf(" AT");
6127 if (zz & CKD_V25) printf(" ITU");
6128 if (zz & CKD_SB) printf(" SB");
6129 if (zz & CKD_EC) printf(" EC");
6130 if (zz & CKD_DC) printf(" DC");
6131 if (zz & CKD_HW) printf(" HWFC");
6132 if (zz & CKD_SW) printf(" SWFC");
6133 if (zz & CKD_KS) printf(" KS");
6134 if (zz & CKD_TB) printf(" TB");
6135 }
6136 printf("\n Modem carrier-watch: ");
6137 if (carrier == CAR_OFF) printf("off\n");
6138 else if (carrier == CAR_ON) printf("on\n");
6139 else if (carrier == CAR_AUT) printf("auto\n");
6140 else printf("unknown\n");
6141
6142 printf(" Modem maximum-speed: ");
6143 zz = (dialmax > 0L) ? dialmax : p->max_speed;
6144 if (zz > 0)
6145 printf("%ld bps\n", zz);
6146 else
6147 printf("(unknown)\n");
6148 printf(" Modem error-correction: %s\n", dialec ? "on" : "off");
6149 printf(" Modem compression: %s\n", dialdc ? "on" : "off");
6150 printf(" Modem speed-matching: %s", mdmspd ? "on" : "off");
6151 printf(" (interface speed %s)\n", mdmspd ? "changes" : "is locked");
6152 printf(" Modem flow-control: ");
6153 if (dialfc == FLO_NONE) printf("none\n");
6154 else if (dialfc == FLO_XONX) printf("xon/xoff\n");
6155 else if (dialfc == FLO_RTSC) printf("rts/cts\n");
6156 else if (dialfc == FLO_AUTO) printf("auto\n");
6157 printf(" Modem hangup-method: %s\n",
6158 dialmhu ?
6159 "modem-command" :
6160 "rs232-signal"
6161 );
6162 printf(" Modem speaker: %s\n", showoff(mdmspk));
6163 printf(" Modem volume: %s\n",
6164 (mdmvol == 2) ? "medium" : ((mdmvol <= 1) ? "low" : "high"));
6165 printf(" Modem kermit-spoof: %s\n", dialksp ? "on" : "off");
6166 c = (char) (x = (dialesc ? dialesc : p->esc_char));
6167 printf(" Modem escape-character: %d", x);
6168 if (isprint(c))
6169 printf(" (= \"%c\")",c);
6170 printf(
6171 "\n\nMODEM COMMANDs (* = set automatically by SET MODEM TYPE):\n\n");
6172 debug(F110,"show dialini",dialini,0);
6173 printf(" %c Init-string: ", dialini ? ' ' : '*' );
6174 shods(dialini ? dialini : p->wake_str);
6175 printf(" %c Dial-mode-string: ", dialmstr ? ' ' : '*' );
6176 shods(dialmstr ? dialmstr : p->dmode_str);
6177 n = local ? 19 : 20;
6178 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
6179 printf(" %c Dial-mode-prompt: ", dialmprmt ? ' ' : '*' );
6180 shods(dialmprmt ? dialmprmt : p->dmode_prompt);
6181 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
6182 printf(" %c Dial-command: ", dialcmd ? ' ' : '*' );
6183 shods(dialcmd ? dialcmd : p->dial_str);
6184 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
6185 printf(" %c Compression on: ", dialdcon ? ' ' : '*' );
6186 if (!dialdcon)
6187 debug(F110,"dialdcon","(null)",0);
6188 else
6189 debug(F110,"dialdcon",dialdcon,0);
6190 shods(dialdcon ? dialdcon : p->dc_on_str);
6191 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
6192 printf(" %c Compression off: ", dialdcoff ? ' ' : '*' );
6193 shods(dialdcoff ? dialdcoff : p->dc_off_str);
6194 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
6195 printf(" %c Error-correction on: ", dialecon ? ' ' : '*' );
6196 shods(dialecon ? dialecon : p->ec_on_str);
6197 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
6198 printf(" %c Error-correction off: ", dialecoff ? ' ' : '*' );
6199 shods(dialecoff ? dialecoff : p->ec_off_str);
6200 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
6201 printf(" %c Autoanswer on: ", dialaaon ? ' ' : '*' );
6202 shods(dialaaon ? dialaaon : p->aa_on_str);
6203 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
6204 printf(" %c Autoanswer off: ", dialaaoff ? ' ' : '*' );
6205 shods(dialaaoff ? dialaaoff : p->aa_off_str);
6206 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
6207
6208 printf(" %c Speaker on: ", dialspon ? ' ' : '*' );
6209 shods(dialspon ? dialspon : p->sp_on_str);
6210 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
6211 printf(" %c Speaker off: ", dialspoff ? ' ' : '*' );
6212 shods(dialspoff ? dialspoff : p->sp_off_str);
6213 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
6214 printf(" %c Volume low: ", dialvol1 ? ' ' : '*' );
6215 shods(dialvol1 ? dialvol1 : p->vol1_str);
6216 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
6217 printf(" %c Volume medium: ", dialvol2 ? ' ' : '*' );
6218 shods(dialvol2 ? dialvol2 : p->vol2_str);
6219 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
6220 printf(" %c Volume high: ", dialvol3 ? ' ' : '*' );
6221 shods(dialvol3 ? dialvol3 : p->vol3_str);
6222 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
6223
6224 printf(" %c Hangup-command: ", dialhcmd ? ' ' : '*' );
6225 shods(dialhcmd ? dialhcmd : p->hup_str);
6226 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
6227 printf(" %c Hardware-flow: ", dialhwfc ? ' ' : '*' );
6228 shods(dialhwfc ? dialhwfc : p->hwfc_str);
6229 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
6230 printf(" %c Software-flow: ", dialswfc ? ' ' : '*' );
6231 shods(dialswfc ? dialswfc : p->swfc_str);
6232 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
6233 printf(" %c No-flow-control: ", dialnofc ? ' ' : '*' );
6234 shods(dialnofc ? dialnofc : p->nofc_str);
6235 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
6236 printf(" %c Pulse: ", dialpulse ? ' ' : '*');
6237 shods(dialpulse ? dialpulse : p->pulse);
6238 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
6239 printf(" %c Tone: ", dialtone ? ' ' : '*');
6240 shods(dialtone ? dialtone : p->tone);
6241
6242 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
6243 printf(" %c Ignore-dialtone: ", dialx3 ? ' ' : '*');
6244 shods(dialx3 ? dialx3 : p->ignoredt);
6245
6246 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
6247 printf(" %c Predial-init: ", dialini2 ? ' ' : '*');
6248 shods(dialini2 ? dialini2 : p->ini2);
6249
6250 if (++n > cmd_rows - 4) if (!askmore()) return(0); else n = 0;
6251 printf("\n For more info: SHOW DIAL and SHOW COMMUNICATIONS\n");
6252
6253 } else if (mdm > 0) {
6254 printf("Modem info for \"%s\" not filled in yet\n", gmdmtyp());
6255 } else printf(
6256 " No modem selected, so DIAL and most SET MODEM commands have no effect.\n\
6257 Use SET MODEM TYPE to select a modem.\n");
6258 return(success = 1);
6259 }
6260 #endif /* NOSHOW */
6261 #endif /* NODIAL */
6262
6263 #ifdef CK_TAPI
6264 int /* TAPI action commands */
6265 dotapi() {
6266 int x,y;
6267 char *s;
6268
6269 if (!TAPIAvail) {
6270 printf("\nTAPI is unavailable on this system.\n");
6271 return(-9);
6272 }
6273 if ((y = cmkey(tapitab,ntapitab,"MS TAPI command","",xxstring)) < 0)
6274 return(y);
6275 switch (y) {
6276 case XYTAPI_CFG: { /* TAPI CONFIGURE-LINE */
6277 extern struct keytab * tapilinetab;
6278 extern struct keytab * _tapilinetab;
6279 extern int ntapiline;
6280 extern int LineDeviceId;
6281 int lineID=LineDeviceId;
6282 if (TAPIAvail)
6283 cktapiBuildLineTable(&tapilinetab, &_tapilinetab, &ntapiline);
6284 if (tapilinetab && _tapilinetab && ntapiline > 0) {
6285 int i=0, j = 9999, k = -1;
6286
6287 if ( LineDeviceId == -1 ) {
6288 /* Find out what the lowest numbered TAPI device is */
6289 /* and use it as the default. */
6290 for (i = 0; i < ntapiline; i++ ) {
6291 if (tapilinetab[i].kwval < j) {
6292 k = i;
6293 }
6294 }
6295 } else {
6296 /* Find the LineDeviceId in the table and use that entry */
6297 for (i = 0; i < ntapiline; i++ ) {
6298 if (tapilinetab[i].kwval == LineDeviceId) {
6299 k = i;
6300 break;
6301 }
6302 }
6303 }
6304 if (k >= 0)
6305 s = _tapilinetab[k].kwd;
6306 else
6307 s = "";
6308
6309 if ((y = cmkey(_tapilinetab,ntapiline,
6310 "TAPI device name",s,xxstring)) < 0)
6311 return(y);
6312 lineID = y;
6313 }
6314 if ((x = cmcfm()) < 0) return(x);
6315 #ifdef IKSD
6316 if (inserver) {
6317 printf("Sorry, command disabled\r\n");
6318 return(success = 0);
6319 }
6320 #endif /* ISKD */
6321 cktapiConfigureLine(lineID);
6322 break;
6323 }
6324 case XYTAPI_DIAL: /* TAPI DIALING-PROPERTIES */
6325 if ((x = cmcfm()) < 0)
6326 return(x);
6327 #ifdef IKSD
6328 if (inserver) {
6329 printf("Sorry, command disabled\r\n");
6330 return(success = 0);
6331 }
6332 #endif /* ISKD */
6333 cktapiDialingProp();
6334 break;
6335 }
6336 return(success = 1);
6337 }
6338
6339 static int /* SET TAPI command options */
6340 settapi() {
6341 int x, y;
6342 char *s;
6343
6344 if (!TAPIAvail) {
6345 printf("\nTAPI is unavailable on this system.\n");
6346 return(-9);
6347 }
6348 if ((y = cmkey(settapitab,nsettapitab,"MS TAPI option","",xxstring)) < 0)
6349 return(y);
6350 switch (y) {
6351 case XYTAPI_USE:
6352 return (success = seton(&tapiusecfg));
6353 case XYTAPI_LGHT:
6354 return (success = seton(&tapilights));
6355 case XYTAPI_PRE:
6356 return (success = seton(&tapipreterm));
6357 case XYTAPI_PST:
6358 return (success = seton(&tapipostterm));
6359 case XYTAPI_INA:
6360 y = cmnum("seconds of inactivity before auto-disconnect",
6361 "0",10,&x,xxstring);
6362 return(setnum(&tapiinactivity,x,y,65535));
6363 case XYTAPI_BNG:
6364 y = cmnum("seconds to wait for credit card tone",
6365 "8",10,&x,xxstring);
6366 return(setnum(&tapibong,x,y,90));
6367 case XYTAPI_MAN:
6368 return (success = seton(&tapimanual));
6369 case XYTAPI_CON: /* TAPI CONVERSIONS */
6370 return (success = setonaut(&tapiconv));
6371 case XYTAPI_LIN: /* TAPI LINE */
6372 x = setlin(XYTAPI_LIN,1,0);
6373 if (x > -1) didsetlin++;
6374 return(x);
6375 case XYTAPI_PASS: { /* TAPI PASSTHROUGH */
6376 #ifdef NODIAL
6377 printf("\n?Modem-dialing not supported\n");
6378 return(-9);
6379 #else /* NODIAL */
6380 /* Passthrough became Modem-dialing which is an antonym */
6381 success = seton(&tapipass);
6382 tapipass = !tapipass;
6383 return (success);
6384 #endif /* NODIAL */
6385 }
6386 case XYTAPI_LOC: { /* TAPI LOCATION */
6387 extern char tapiloc[];
6388 extern int tapilocid;
6389 int i = 0, j = 9999, k = -1;
6390
6391 cktapiBuildLocationTable(&tapiloctab, &ntapiloc);
6392 if (!tapiloctab || !ntapiloc) {
6393 printf("\nNo TAPI Locations are configured for this system\n");
6394 return(-9);
6395 }
6396 if (tapilocid == -1)
6397 tapilocid = cktapiGetCurrentLocationID();
6398
6399 /* Find the current tapiloc entry */
6400 /* and use it as the default. */
6401 for (k = 0; k < ntapiloc; k++) {
6402 if (tapiloctab[k].kwval == tapilocid)
6403 break;
6404 }
6405 if (k >= 0 && k < ntapiloc)
6406 s = tapiloctab[k].kwd;
6407 else
6408 s = "";
6409
6410 if ((y = cmkey(tapiloctab,ntapiloc, "TAPI location",s,xxstring)) < 0)
6411 return(y);
6412
6413 if ((x = cmcfm()) < 0)
6414 return(x);
6415 #ifdef IKSD
6416 if (inserver) {
6417 printf("Sorry, command disabled\r\n");
6418 return(success = 0);
6419 }
6420 #endif /* IKSD */
6421 cktapiFetchLocationInfoByID( y );
6422 #ifndef NODIAL
6423 CopyTapiLocationInfoToKermitDialCmd();
6424 #endif /* NODIAL */
6425 }
6426 break;
6427 }
6428 return(success=1);
6429 }
6430 #endif /* CK_TAPI */
6431 #endif /* NOLOCAL */
6432
6433 #ifndef NOSPL
6434 /* Method for evaluating \%x and \&x[] variables */
6435
6436 static struct keytab varevaltab[] = {
6437 { "recursive", 1, 0 },
6438 { "simple", 0, 0 }
6439 };
6440 static int nvarevaltab = (sizeof(varevaltab) / sizeof(struct keytab));
6441
6442 int
6443 setvareval() {
6444 int x = 0, y = 0;
6445 extern int vareval;
6446 #ifdef DCMDBUF
6447 extern int * xvarev;
6448 #else
6449 extern int xvarev[];
6450 #endif /* DCMDBUF */
6451
6452 if ((x = cmkey(varevaltab,
6453 nvarevaltab,
6454 "Method for evaluating \\%x and \\&x[] variables",
6455 "",
6456 xxstring)) < 0)
6457 return(x);
6458 if ((y = cmcfm()) < 0)
6459 return(y);
6460 xvarev[cmdlvl] = x;
6461 vareval = x;
6462 return(success = 1);
6463 }
6464
6465 #ifdef CK_ANSIC /* SET ALARM */
6466 int
6467 setalarm(long xx)
6468 #else
6469 int
6470 setalarm(xx) long xx;
6471 #endif /* CK_ANSIC */
6472 /* setalarm */ {
6473 #ifdef COMMENT
6474 int yyyy, mm, dd, x;
6475 char *s;
6476 long zz;
6477 char buf[6];
6478 #endif /* COMMENT */
6479 long sec, jd;
6480 char xbuf[20], * p;
6481
6482 debug(F101,"setalarm xx","",xx);
6483 ck_alarm = 0L; /* 0 = no alarm (in case of error) */
6484 if (xx < 0L) {
6485 printf("%ld - illegal value, must be 0 or positive\n", xx);
6486 return(-9);
6487 }
6488 if (xx == 0L) { /* CLEAR ALARM */
6489 alrm_date[0] = NUL;
6490 alrm_time[0] = NUL;
6491 return(1);
6492 }
6493 #ifdef COMMENT
6494 x = 8; /* Get current date */
6495 s = alrm_date;
6496 if (zzstring("\\v(ndate)",&s,&x) < 0) {
6497 printf("Internal date error, sorry.\n");
6498 alrm_date[0] = SP;
6499 return(-9);
6500 }
6501 x = 5; /* Get current time */
6502 s = alrm_time;
6503 if (zzstring("\\v(ntime)",&s,&x) < 0) {
6504 printf("Internal time error, sorry.\n");
6505 alrm_time[0] = SP;
6506 return(-9);
6507 }
6508 sprintf(buf,"%05ld",atol(alrm_time)); /* SAFE (20) */
6509 ckstrncpy(alrm_time,buf,8);
6510 debug(F110,"SET ALARM date (1)",alrm_date,0);
6511 debug(F110,"SET ALARM time (1)",alrm_time,0);
6512
6513 if ((zz = atol(alrm_time) + xx) < 0L) {
6514 printf("Internal time conversion error, sorry.\n");
6515 return(-9);
6516 }
6517 if (zz >= 86400L) { /* Alarm crosses midnight */
6518 char d[10]; /* Local date buffer */
6519 int lastday; /* Last day of this month */
6520
6521 ckstrncpy(d,alrm_date,8); /* We'll have to change the date */
6522
6523 x = (zz / 86400L); /* How many days after today */
6524
6525 dd = atoi((char *)(d+6)); /* Parse yyyymmdd */
6526 d[6] = NUL; /* into yyyy, mm, dd ... */
6527 mm = atoi((char *)(d+4));
6528 d[4] = NUL;
6529 yyyy = atoi((char *)d);
6530
6531 /* How many days in this month */
6532
6533 lastday = mdays[mm];
6534 if (mm == 2 && yyyy % 4 == 0) /* Works thru 2099 AD... */
6535 lastday++;
6536
6537 if (dd + x > lastday) { /* Dumb loop */
6538 int y;
6539
6540 x -= (mdays[mm] - dd); /* Deduct rest of this month's days */
6541
6542 /* There's a more elegant way to do this... */
6543
6544 while (1) {
6545 mm++; /* Next month */
6546 if (mm > 12) { /* Wrap around */
6547 mm = 1; /* Jan, next year */
6548 yyyy++;
6549 }
6550 y = mdays[mm]; /* Days in new month */
6551 if (mm == 2 && yyyy % 4 == 0) /* Feb in leap year */
6552 y++; /* Works until 2100 AD */
6553 if (x - y < 1)
6554 break;
6555 x -= y;
6556 }
6557 dd = x; /* Day of alarm month */
6558 } else dd += x;
6559
6560 sprintf(alrm_date,"%04d%02d%02d",yyyy,mm,dd); /* SAFE (24) */
6561 zz = zz % 86400L;
6562 }
6563 sprintf(alrm_time,"%ld",zz); /* SAFE (24) */
6564 debug(F110,"SET ALARM date (2)",alrm_date,0);
6565 debug(F110,"SET ALARM time (2)",alrm_time,0);
6566 ck_alarm = xx;
6567 #else
6568 /* Jul 1998 */
6569 ckstrncpy(xbuf,ckcvtdate("",1),20); /* Get current date and time */
6570 p = xbuf;
6571 ckstrncpy(alrm_date,xbuf,10);
6572 alrm_date[8] = NUL;
6573 sec = atol(p+9) * 3600L + atol(p+12) * 60L + atol(p+15);
6574 debug(F110,"SET ALARM date (1)",alrm_date,0);
6575 debug(F101,"SET ALARM time (1)","",sec);
6576 if ((sec += xx) < 0L) {
6577 printf("Internal time conversion error, sorry.\n");
6578 return(-9);
6579 }
6580 if (sec >= 86400L) { /* Alarm crosses midnight */
6581 long days;
6582 days = sec / 86400L;
6583 jd = mjd(p) + days; /* Get modified Julian date */
6584 ckstrncpy(alrm_date,mjd2date(jd),10);
6585 sec %= 86400L;
6586 }
6587 sprintf(alrm_time,"%05ld",sec); /* SAFE (24) */
6588 debug(F110,"SET ALARM date (2)",alrm_date,0);
6589 debug(F110,"SET ALARM time (2)",alrm_time,0);
6590 ck_alarm = 1; /* Alarm is set */
6591
6592 #endif /* COMMENT */
6593 return(success = 1);
6594 }
6595 #endif /* NOSPL */
6596
6597 #ifndef NOSETKEY
6598 int
6599 dosetkey() { /* SET KEY */
6600 int x, y;
6601 int flag = 0;
6602 int kc; /* Key code */
6603 char *s; /* Key binding */
6604 #ifndef NOKVERBS
6605 char *p; /* Worker */
6606 #endif /* NOKVERBS */
6607 #ifdef OS2
6608 extern int os2gks;
6609 extern int mskkeys;
6610 extern int initvik;
6611 #endif /* OS2 */
6612
6613 x_ifnum = 1;
6614 y = cmnum("numeric key code, or the word CLEAR,","",10,&kc,xxstring);
6615 x_ifnum = 0;
6616 if (y < 0) {
6617 debug(F111,"SET KEY",atmbuf,y);
6618 if (y == -2) { /* Not a valid number */
6619 if ((y = strlen(atmbuf)) < 0) /* Check for SET KEY CLEAR */
6620 return(-2);
6621 if (ckstrcmp(atmbuf,"clear",y,0))
6622 return(-2);
6623 if ((x = cmcfm()) < 0)
6624 return(x);
6625 for (y = 0; y < KMSIZE; y++) {
6626 keymap[y] = (KEY) y;
6627 macrotab[y] = NULL;
6628 }
6629 #ifdef OS2
6630 keymapinit(); /* Special OS/2 initializations */
6631 initvik = 1; /* Update the VIK table */
6632 #endif /* OS2 */
6633 return(1);
6634 } else if (y == -3) { /* SET KEY <Return> */
6635 printf(" Press key to be defined: "); /* Prompt for a keystroke */
6636 #ifdef UNIX
6637 #ifdef NOSETBUF
6638 fflush(stdout);
6639 #endif /* NOSETBUF */
6640 #endif /* UNIX */
6641 conbin((char)escape); /* Put terminal in binary mode */
6642 #ifdef OS2
6643 os2gks = 0; /* Turn off Kverb preprocessing */
6644 #endif /* OS2 */
6645 kc = congks(0); /* Get character or scan code */
6646 #ifdef OS2
6647 os2gks = 1; /* Turn on Kverb preprocessing */
6648 #endif /* OS2 */
6649 concb((char)escape); /* Restore terminal to cbreak mode */
6650 if (kc < 0) { /* Check for error */
6651 printf("?Error reading key\n");
6652 return(0);
6653 }
6654 #ifdef OS2
6655 shokeycode(kc,-1); /* Show current definition */
6656 #else
6657 shokeycode(kc); /* Show current definition */
6658 #endif /* OS2 */
6659 flag = 1; /* Remember it's a multiline command */
6660 } else /* Error */
6661 return(y);
6662 }
6663
6664 /* Normal SET KEY <scancode> <value> command... */
6665
6666 #ifdef OS2
6667 if (mskkeys)
6668 kc = msktock(kc);
6669 #endif /* OS2 */
6670
6671 if (kc < 0 || kc >= KMSIZE) {
6672 printf("?key code must be between 0 and %d\n", KMSIZE - 1);
6673 return(-9);
6674 }
6675 if (kc == escape) {
6676 printf("Sorry, %d is the CONNECT-mode escape character\n",kc);
6677 return(-9);
6678 }
6679 #ifdef OS2
6680 wideresult = -1;
6681 #endif /* OS2 */
6682 if (flag) {
6683 cmsavp(psave,PROMPTL);
6684 cmsetp(" Enter new definition: ");
6685 cmini(ckxech);
6686 cmflgs = 0;
6687 prompt(NULL);
6688 }
6689 def_again:
6690 if (flag)
6691 cmres();
6692 if ((y = cmtxt("key definition,\n\
6693 or Ctrl-C to cancel this command,\n\
6694 or Enter to restore default definition",
6695 "",&s,NULL)) < 0) {
6696 if (flag) /* Handle parse errors */
6697 goto def_again;
6698 else
6699 return(y);
6700 }
6701 s = brstrip(s);
6702 #ifndef NOKVERBS
6703 p = s; /* Save this place */
6704 #endif /* NOKVERBS */
6705 /*
6706 If the definition included any \Kverbs, quote the backslash so the \Kverb
6707 will still be in the definition when the key is pressed. We don't do this
6708 in zzstring(), because \Kverbs are valid only in this context and nowhere
6709 else.
6710
6711 We use this code active for all versions that support SET KEY, even if they
6712 don't support \Kverbs, because otherwise \K would behave differently for
6713 different versions.
6714 */
6715 for (x = 0, y = 0; s[x]; x++, y++) { /* Convert \K to \\K */
6716 if ((x > 0) &&
6717 (s[x] == 'K' || s[x] == 'k')
6718 ) { /* Have K */
6719
6720 if ((x == 1 && s[x-1] == CMDQ) ||
6721 (x > 1 && s[x-1] == CMDQ && s[x-2] != CMDQ)) {
6722 line[y++] = CMDQ; /* Make it \\K */
6723 }
6724 if (x > 1 && s[x-1] == '{' && s[x-2] == CMDQ) {
6725 line[y-1] = CMDQ; /* Have \{K */
6726 line[y++] = '{'; /* Make it \\{K */
6727 }
6728 }
6729 line[y] = s[x];
6730 }
6731 line[y++] = NUL; /* Terminate */
6732 s = line + y + 1; /* Point to after it */
6733 x = LINBUFSIZ - (int) strlen(line) - 1; /* Calculate remaining space */
6734 if ((x < (LINBUFSIZ / 2)) ||
6735 (zzstring(line, &s, &x) < 0)) { /* Expand variables, etc. */
6736 printf("?Key definition too long\n");
6737 if (flag) cmsetp(psave);
6738 return(-9);
6739 }
6740 s = line + y + 1; /* Point to result. */
6741
6742 #ifndef NOKVERBS
6743 /*
6744 Special case: see if the definition starts with a \Kverb.
6745 If it does, point to it with p, otherwise set p to NULL.
6746 */
6747 p = s;
6748 if (*p++ == CMDQ) {
6749 if (*p == '{') p++;
6750 p = (*p == 'k' || *p == 'K') ? p + 1 : NULL;
6751 }
6752 #endif /* NOKVERBS */
6753
6754 if (macrotab[kc]) { /* Possibly free old macro from key. */
6755 free((char *)macrotab[kc]);
6756 macrotab[kc] = NULL;
6757 }
6758 switch (strlen(s)) { /* Action depends on length */
6759 case 0: /* Reset to default binding */
6760 keymap[kc] = (KEY) kc;
6761 break;
6762 case 1: /* Single character */
6763 keymap[kc] = (CHAR) *s;
6764 break;
6765 default: /* Character string */
6766 #ifndef NOKVERBS
6767 if (p) {
6768 y = xlookup(kverbs,p,nkverbs,&x); /* Look it up */
6769 debug(F101,"set key kverb lookup",0,y); /* exact match required */
6770 if (y > -1) {
6771 keymap[kc] = F_KVERB | y;
6772 break;
6773 }
6774 }
6775 #endif /* NOKVERBS */
6776 keymap[kc] = (KEY) kc;
6777 macrotab[kc] = (MACRO) malloc(strlen(s)+1);
6778 if (macrotab[kc])
6779 strcpy((char *) macrotab[kc], s); /* safe */
6780 break;
6781 }
6782 if (flag) cmsetp(psave);
6783 #ifdef OS2
6784 initvik = 1; /* Update VIK table */
6785 #endif /* OS2 */
6786 return(1);
6787 }
6788 #endif /* NOSETKEY */
6789
6790 #ifdef STOPBITS
6791 struct keytab stoptbl[] = {
6792 { "1", 1, 0 },
6793 { "2", 2, 0 }
6794 };
6795 #endif /* STOPBITS */
6796
6797 static struct keytab sertbl[] = {
6798 { "7E1", 0, 0 },
6799 { "7E2", 1, 0 },
6800 { "7M1", 2, 0 },
6801 { "7M2", 3, 0 },
6802 { "7O1", 4, 0 },
6803 { "7O2", 5, 0 },
6804 { "7S1", 6, 0 },
6805 { "7S2", 7, 0 },
6806 #ifdef HWPARITY
6807 { "8E1", 9, 0 },
6808 { "8E2", 10, 0 },
6809 #endif /* HWPARITY */
6810 { "8N1", 8, 0 },
6811 #ifdef HWPARITY
6812 { "8N2", 11, 0 },
6813 { "8O1", 12, 0 },
6814 { "8O2", 13, 0 },
6815 #endif /* HWPARITY */
6816 { "", 0, 0 }
6817 };
6818 static int nsertbl = (sizeof(sertbl) / sizeof(struct keytab)) - 1;
6819
6820 static char * sernam[] = { /* Keep this in sync with sertbl[] */
6821 "7E1", "7E2", "7M1", "7M2", "7O1", "7O2", "7S1", "7S2",
6822 "8N1", "8E1", "8E2", "8N2", "8O1", "8O2"
6823 };
6824
6825 static struct keytab optstab[] = { /* SET OPTIONS table */
6826 #ifndef NOFRILLS
6827 { "delete", XXDEL, 0}, /* DELETE */
6828 #endif /* NOFRILLS */
6829 { "directory", XXDIR, 0}, /* DIRECTORY */
6830 #ifdef CKPURGE
6831 { "purge", XXPURGE, 0}, /* PURGE */
6832 #endif /* CKPURGE */
6833 { "type", XXTYP, 0}, /* TYPE */
6834 { "", 0, 0}
6835 };
6836 static int noptstab = (sizeof(optstab) / sizeof(struct keytab)) - 1;
6837
6838 #ifndef NOXFER
6839 /*
6840 PROTOCOL SELECTION. Kermit is always available. If CK_XYZ is defined at
6841 compile time, then the others become selections also. In OS/2 and
6842 Windows, they are integrated and the various SET commands (e.g. "set file
6843 type") affect them as they would Kermit. In other OS's (UNIX, VMS, etc),
6844 they are external protocols which are run via Kermit's REDIRECT mechanism.
6845 All we do is collect and verify the filenames and pass them along to the
6846 external protocol.
6847 */
6848 struct keytab protos[] = {
6849 #ifdef CK_XYZ
6850 "g", PROTO_G, CM_INV,
6851 #endif /* CK_XYZ */
6852 "kermit", PROTO_K, 0,
6853 #ifdef CK_XYZ
6854 "other", PROTO_O, 0,
6855 "x", PROTO_X, CM_INV|CM_ABR,
6856 "xmodem", PROTO_X, 0,
6857 "xmodem-crc", PROTO_XC, 0,
6858 "y", PROTO_Y, CM_INV|CM_ABR,
6859 "ymodem", PROTO_Y, 0,
6860 "ymodem-g", PROTO_G, 0,
6861 "zmodem", PROTO_Z, 0
6862 #endif /* CK_XYZ */
6863 };
6864 int nprotos = (sizeof(protos) / sizeof(struct keytab));
6865
6866 #ifndef XYZ_INTERNAL
6867 #ifndef NOPUSH
6868 #define EXP_HANDLER 1
6869 #define EXP_STDERR 2
6870 #define EXP_TIMO 3
6871
6872 static struct keytab extprotab[] = {
6873 { "handler", EXP_HANDLER, 0 },
6874 { "redirect-stderr", EXP_STDERR, 0 },
6875 { "timeout", EXP_TIMO, 0 }
6876 };
6877 static int nxtprotab = (sizeof(extprotab) / sizeof(struct keytab));
6878 #endif /* NOPUSH */
6879 #endif /* XYZ_INTERNAL */
6880
6881 #define XPCMDLEN 71
6882
6883 _PROTOTYP(static int protofield, (char *, char *, char *));
6884 _PROTOTYP(static int setproto, (void));
6885
6886 static int
6887 protofield(current, help, px) char * current, * help, * px; {
6888
6889 char *s, tmpbuf[XPCMDLEN+1];
6890 int x;
6891
6892 if (current) /* Put braces around default */
6893 ckmakmsg(tmpbuf,TMPBUFSIZ,"{",current,"}",NULL);
6894 else
6895 tmpbuf[0] = NUL;
6896
6897 if ((x = cmfld(help, (char *)tmpbuf, &s, xxstring)) < 0)
6898 return(x);
6899 if ((int)strlen(s) > XPCMDLEN) {
6900 printf("?Sorry - maximum length is %d\n", XPCMDLEN);
6901 return(-9);
6902 } else if (*s) {
6903 strcpy(px,s); /* safe */
6904 } else {
6905 px = NULL;
6906 }
6907 return(x);
6908 }
6909
6910 static int
6911 setproto() { /* Select a file transfer protocol */
6912 /* char * s = NULL; */
6913 int x = 0, y;
6914 char s1[XPCMDLEN+1], s2[XPCMDLEN+1], s3[XPCMDLEN+1];
6915 char s4[XPCMDLEN+1], s5[XPCMDLEN+1], s6[XPCMDLEN+1], s7[XPCMDLEN+1];
6916 char * p1 = s1, * p2 = s2, *p3 = s3;
6917 char * p4 = s4, * p5 = s5, *p6 = s6, *p7 = s7;
6918
6919 #ifdef XYZ_INTERNAL
6920 extern int p_avail;
6921 #else
6922 #ifndef CK_REDIR
6923 x = 1;
6924 #endif /* CK_REDIR */
6925 #endif /* XYZ_INTERNAL */
6926 s1[0] = NUL;
6927 s2[0] = NUL;
6928 s3[0] = NUL;
6929 s4[0] = NUL;
6930 s5[0] = NUL;
6931 s6[0] = NUL;
6932
6933 if ((y = cmkey(protos,nprotos,"","kermit",xxstring)) < 0)
6934 return(y);
6935
6936 if (x && y != PROTO_K) {
6937 printf(
6938 "?Sorry, REDIRECT capability required for external protocols.\n");
6939 return(-9);
6940 }
6941 if ((x = protofield(ptab[y].h_b_init,
6942 "Optional command to send to host prior to uploading in binary mode",
6943 p1)) < 0) {
6944 if (x == -3) {
6945 protocol = y; /* Set protocol but don't change */
6946 return(1); /* anything else */
6947 } else
6948 return(x);
6949 }
6950 if ((x = protofield(ptab[y].h_t_init,
6951 "Optional command to send to host prior to uploading in text mode",
6952 p2)) < 0) {
6953 if (x == -3)
6954 goto protoexit;
6955 else
6956 return(x);
6957 }
6958
6959 if (y == PROTO_K) {
6960 if ((x = protofield(ptab[y].h_x_init,
6961 "Optional command to send to host to start Kermit server",
6962 p3)) < 0) {
6963 if (x == -3)
6964 goto protoexit;
6965 else
6966 return(x);
6967 }
6968 }
6969
6970
6971 #ifndef XYZ_INTERNAL /* If XYZMODEM are external... */
6972
6973 if (y != PROTO_K) {
6974 if ((x = protofield(ptab[y].p_b_scmd,
6975 "External command to SEND in BINARY mode with this protocol",
6976 p4)) < 0) {
6977 if (x == -3)
6978 goto protoexit;
6979 else
6980 return(x);
6981 }
6982 if ((x = protofield(ptab[y].p_t_scmd,
6983 "External command to SEND in TEXT mode with this protocol",
6984 p5)) < 0) {
6985 if (x == -3)
6986 goto protoexit;
6987 else
6988 return(x);
6989 }
6990 if ((x = protofield(ptab[y].p_b_rcmd,
6991 "External command to RECEIVE in BINARY mode with this protocol",
6992 p6)) < 0) {
6993 if (x == -3)
6994 goto protoexit;
6995 else
6996 return(x);
6997 }
6998 if ((x = protofield(ptab[y].p_t_rcmd,
6999 "External command to RECEIVE in TEXT mode with this protocol",
7000 p7)) < 0) {
7001 if (x == -3)
7002 goto protoexit;
7003 else
7004 return(x);
7005 }
7006 }
7007 #endif /* XYZ_INTERNAL */
7008
7009 if ((x = cmcfm()) < 0) /* Confirm the command */
7010 return(x);
7011
7012 protoexit: /* Common exit from this routine */
7013
7014 #ifdef XYZ_INTERNAL
7015 if (!p_avail) {
7016 bleep(BP_WARN);
7017 printf("\n?X,Y, and Zmodem are unavailable\n");
7018 return(success = 0);
7019 }
7020 #endif /* XYZ_INTERNAL */
7021
7022 p1 = brstrip(p1);
7023 p2 = brstrip(p2);
7024 p3 = brstrip(p3);
7025 p4 = brstrip(p4);
7026 p5 = brstrip(p5);
7027 p6 = brstrip(p6);
7028 p7 = brstrip(p7);
7029 initproto(y,p1,p2,p3,p4,p5,p6,p7);
7030 return(success = 1);
7031 }
7032
7033 #ifndef NOPUSH
7034 #ifndef XYZ_INTERNAL
7035
7036 #define DEF_EXP_TIMO 12 /* Default timeout for external protocol (seconds) */
7037
7038 int exp_handler = 0; /* These are exported */
7039 int exp_timo = DEF_EXP_TIMO;
7040 int exp_stderr = SET_AUTO;
7041
7042 VOID
7043 shoextern() { /* Invoked by SHOW PROTOCOL */
7044 printf("\n External-protocol handler: %s\n",
7045 exp_handler ? (exp_handler == 1 ? "pty" : "system") : "automatic");
7046 #ifdef COMMENT
7047 printf(" External-protocol redirect-stderr: %s\n", showooa(exp_stderr));
7048 #endif /* COMMENT */
7049 printf(" External-protocol timeout: %d (sec)\n", exp_timo);
7050 }
7051
7052 static struct keytab setexternhandler[] = {
7053 { "automatic", 0, 0 },
7054 { "pty", 1, 0 },
7055 { "system", 2, 0 }
7056 };
7057
7058 int
7059 setextern() { /* SET EXTERNAL-PROTOCOL */
7060 int x, y;
7061 if ((x = cmkey(extprotab,nxtprotab,"","",xxstring)) < 0)
7062 return(x);
7063 switch (x) {
7064 case EXP_HANDLER:
7065 if ((x = cmkey(setexternhandler,3,"","automatic",xxstring)) < 0)
7066 return(x);
7067 if ((y = cmcfm()) < 0)
7068 return(y);
7069 exp_handler = x;
7070 break;
7071
7072 #ifdef COMMENT
7073 case EXP_STDERR:
7074 if ((x = cmkey(ooatab,3,"","automatic",xxstring)) < 0)
7075 return(x);
7076 if ((y = cmcfm()) < 0)
7077 return(y);
7078 exp_stderr = x;
7079 break;
7080 #endif /* COMMENT */
7081
7082 case EXP_TIMO:
7083 y = cmnum("Inactivity timeout, seconds,",ckitoa(DEF_EXP_TIMO),
7084 10,&x,xxstring);
7085 return(setnum(&exp_timo,x,y,-1));
7086 }
7087 return(success = 1);
7088 }
7089 #endif /* XYZ_INTERNAL */
7090 #endif /* NOPUSH */
7091
7092 int
7093 setdest() {
7094 int x, y;
7095 if ((y = cmkey(desttab,ndests,"","disk",xxstring)) < 0) return(y);
7096 if ((x = cmcfm()) < 0) return(x);
7097 dest = y;
7098 return(1);
7099 }
7100 #endif /* NOXFER */
7101
7102 #ifdef DECNET
7103 struct keytab dnettab[] = {
7104 #ifndef OS2ONLY
7105 "cterm", NP_CTERM, 0,
7106 #endif /* OS2ONLY */
7107 "lat", NP_LAT, 0
7108 };
7109 int ndnet = (sizeof(dnettab) / sizeof(struct keytab));
7110 #endif /* DECNET */
7111
7112 /* S E T P R I N T E R -- SET PRINTER command */
7113
7114 #ifdef PRINTSWI
7115 static struct keytab prntab[] = { /* SET PRINTER switches */
7116 "/bidirectional", PRN_BID, 0,
7117 #ifdef OS2
7118 "/character-set", PRN_CS, CM_ARG,
7119 #endif /* OS2 */
7120 "/command", PRN_PIP, CM_ARG,
7121 "/dos-device", PRN_DOS, CM_ARG,
7122 "/end-of-job-string",PRN_TRM, CM_ARG,
7123 "/file", PRN_FIL, CM_ARG,
7124 #ifdef BPRINT
7125 "/flow-control", PRN_FLO, CM_ARG,
7126 #endif /* BPRINT */
7127 "/job-header-file", PRN_SEP, CM_ARG,
7128 #ifdef OS2
7129 "/length", PRN_LEN, CM_ARG,
7130 #endif /* OS2 */
7131 "/none", PRN_NON, 0,
7132 #ifdef OS2
7133 "/nopostscript", PRN_RAW, 0,
7134 "/nops", PRN_RAW, CM_INV,
7135 #endif /* OS2 */
7136 "/output-only", PRN_OUT, 0,
7137 #ifdef BPRINT
7138 "/parity", PRN_PAR, CM_ARG,
7139 #endif /* BPRINT */
7140 "/pipe", PRN_PIP, CM_ARG|CM_INV,
7141 #ifdef OS2
7142 "/postscript", PRN_PS, 0,
7143 "/ps", PRN_PS, CM_INV,
7144 #endif /* OS2 */
7145 "/separator", PRN_SEP, CM_ARG|CM_INV,
7146 #ifdef BPRINT
7147 "/speed", PRN_SPD, CM_ARG,
7148 #endif /* BPRINT */
7149 "/timeout", PRN_TMO, CM_ARG,
7150 "/terminator", PRN_TRM, CM_ARG|CM_INV,
7151 #ifdef OS2
7152 #ifdef NT
7153 "/w", PRN_WIN, CM_ARG|CM_ABR|CM_INV,
7154 "/wi", PRN_WIN, CM_ARG|CM_ABR|CM_INV,
7155 #endif /* NT */
7156 "/width", PRN_WID, CM_ARG,
7157 #endif /* OS2 */
7158 #ifdef NT
7159 "/windows-queue", PRN_WIN, CM_ARG,
7160 #endif /* NT */
7161 "", 0, 0
7162 };
7163 int nprnswi = (sizeof(prntab) / sizeof(struct keytab)) - 1;
7164 #endif /* PRINTSWI */
7165
7166 static int
7167 setprinter(xx) int xx; {
7168 int x, y;
7169 char * s;
7170 char * defname = NULL;
7171 #ifdef OS2
7172 extern int prncs;
7173 #endif /* OS2 */
7174
7175 #ifdef BPRINT
7176 char portbuf[64];
7177 long portspeed = 0L;
7178 int portparity = 0;
7179 int portflow = 0;
7180 #endif /* BPRINT */
7181
7182 #ifdef PRINTSWI
7183 int c, i, n, wild, confirmed = 0; /* Workers */
7184 int getval = 0; /* Whether to get switch value */
7185 struct stringint pv[PRN_MAX+1]; /* Temporary array for switch values */
7186 struct FDB sw, of, cm; /* FDBs for each parse function */
7187 int haveque = 0;
7188 int typeset = 0;
7189 #endif /* PRINTSWI */
7190
7191 #ifdef NT
7192 struct keytab * printtab = NULL, * _printtab = NULL;
7193 int nprint = 0, printdef=0;
7194 #endif /* NT */
7195
7196 #ifdef OS2
7197 defname = "PRN"; /* default */
7198 #else
7199 #ifdef VMS
7200 defname = "LPT:";
7201 #else
7202 #ifdef UNIX
7203 defname = "|lpr";
7204 #endif /* UNIX */
7205 #endif /* VMS */
7206 #endif /* OS2 */
7207
7208 #ifdef PRINTSWI
7209 #ifdef NT
7210 haveque = Win32EnumPrt(&printtab,&_printtab,&nprint,&printdef);
7211 haveque = haveque && nprint;
7212 #endif /* NT */
7213
7214 for (i = 0; i <= PRN_MAX; i++) { /* Initialize switch values */
7215 pv[i].sval = NULL; /* to null pointers */
7216 pv[i].ival = -1; /* and -1 int values */
7217 pv[i].wval = (CK_OFF_T)-1; /* and -1 wide values */
7218 }
7219 if (xx == XYBDCP) { /* SET BPRINTER == /BIDIRECTIONAL */
7220 pv[PRN_BID].ival = 1;
7221 pv[PRN_OUT].ival = 0;
7222 }
7223
7224 /* Initialize defaults based upon current printer settings */
7225 if (printername) {
7226 defname = printername;
7227 switch (printertype) {
7228 case PRT_WIN: pv[PRN_WIN].ival = 1; break;
7229 case PRT_DOS: pv[PRN_DOS].ival = 1; break;
7230 case PRT_PIP: pv[PRN_PIP].ival = 1; break;
7231 case PRT_FIL: pv[PRN_FIL].ival = 1; break;
7232 case PRT_NON: pv[PRN_NON].ival = 1; break;
7233 }
7234 }
7235 #ifdef BPRINT
7236 /* only set the BIDI flag if we are bidi */
7237 if (printbidi)
7238 pv[PRN_BID].ival = 1;
7239
7240 /* serial port parameters may be set for non-bidi devices */
7241 pv[PRN_SPD].ival = pportspeed / 10L;
7242 pv[PRN_PAR].ival = pportparity;
7243 pv[PRN_FLO].ival = pportflow;
7244 #endif /* BPRINT */
7245 if (printtimo)
7246 pv[PRN_TMO].ival = printtimo;
7247 if (printterm) {
7248 pv[PRN_TRM].ival = 1;
7249 makestr(&pv[PRN_TRM].sval,printterm);
7250 }
7251 if (printsep) {
7252 pv[PRN_SEP].ival = 1;
7253 makestr(&pv[PRN_SEP].sval,printsep);
7254 }
7255 if (txt2ps) {
7256 pv[PRN_PS].ival = 1;
7257 pv[PRN_WID].ival = ps_width;
7258 pv[PRN_LEN].ival = ps_length;
7259 } else {
7260 pv[PRN_RAW].ival = 1;
7261 }
7262
7263 /* Set up chained parse functions... */
7264
7265 cmfdbi(&sw, /* First FDB - command switches */
7266 _CMKEY, /* fcode */
7267 "Switch", /* hlpmsg */
7268 "", /* default */
7269 "", /* addtl string data */
7270 nprnswi, /* addtl numeric data 1: tbl size */
7271 4, /* addtl numeric data 2: 4 = cmswi */
7272 xxstring, /* Processing function */
7273 prntab, /* Keyword table */
7274 &cm /* Pointer to next FDB */
7275 );
7276 cmfdbi(&cm, /* Second fdb for confirmation */
7277 _CMCFM, /* fcode */
7278 "", /* hlpmsg */
7279 "", /* default */
7280 "", /* addtl string data */
7281 0, /* addtl numeric data 1 */
7282 0, /* addtl numeric data 2 */
7283 NULL,
7284 NULL,
7285 &of
7286 );
7287 cmfdbi(&of, /* Third FDB for printer name */
7288 _CMOFI, /* fcode */
7289 "Printer or file name", /* hlpmsg */
7290 defname, /* default */
7291 "", /* addtl string data */
7292 0, /* addtl numeric data 1: tbl size */
7293 0, /* addtl numeric data 2: 4 = cmswi */
7294 xxstring, /* Processing function */
7295 NULL, /* Nothing */
7296 NULL
7297 );
7298
7299 while (1) { /* Parse 0 or more switches */
7300 x = cmfdb(&sw); /* Parse switch or other thing */
7301 debug(F101,"setprinter cmfdb","",x);
7302 if (x < 0) /* Error */
7303 goto xsetprn; /* or reparse needed */
7304 if (cmresult.fcode != _CMKEY) /* Break out if not a switch */
7305 break;
7306 if (cmresult.fdbaddr != &sw) /* Advanced usage :-) */
7307 break;
7308 c = cmgbrk(); /* Get break character */
7309 getval = (c == ':' || c == '='); /* to see how they ended the switch */
7310 n = cmresult.nresult; /* Numeric result = switch value */
7311 debug(F101,"setprinter switch","",n);
7312
7313 switch (n) { /* Process the switch */
7314 case PRN_PS: /* Text to Postscript */
7315 pv[PRN_PS].ival = 1;
7316 pv[PRN_BID].ival = 0;
7317 pv[PRN_OUT].ival = 1;
7318 pv[PRN_RAW].ival = 0;
7319 break;
7320
7321 case PRN_RAW: /* Non-Postscript */
7322 pv[PRN_PS].ival = 0;
7323 pv[PRN_RAW].ival = 1;
7324 break;
7325
7326 case PRN_BID: /* Bidirectional */
7327 pv[PRN_BID].ival = 1;
7328 pv[PRN_OUT].ival = 0;
7329 pv[PRN_PS].ival = 0;
7330 pv[PRN_RAW].ival = 1;
7331 break;
7332
7333 case PRN_OUT: /* Output-only */
7334 pv[PRN_OUT].ival = 1;
7335 pv[PRN_BID].ival = 0;
7336 pv[PRN_PS].ival = 0;
7337 pv[PRN_RAW].ival = 1;
7338 break;
7339
7340 case PRN_NON: /* NONE */
7341 typeset++;
7342 pv[n].ival = 1;
7343 pv[PRN_SPD].ival = 0;
7344 pv[PRN_PAR].ival = 0;
7345 pv[PRN_FLO].ival = FLO_KEEP;
7346 break;
7347
7348 #ifdef UNIX
7349 case PRN_WIN:
7350 #endif /* UNIX */
7351 case PRN_DOS: /* DOS printer name */
7352 case PRN_FIL: /* Or filename */
7353 case PRN_PIP:
7354 typeset++;
7355 if (pv[n].sval) free(pv[n].sval);
7356 pv[n].sval = NULL;
7357 pv[PRN_NON].ival = 0; /* Zero any previous selections */
7358 pv[PRN_WIN].ival = 0;
7359 pv[PRN_DOS].ival = 0;
7360 pv[PRN_FIL].ival = 0;
7361 pv[PRN_PIP].ival = 0;
7362 pv[n].ival = 1; /* Flag this one */
7363 if (!getval) break; /* No value wanted */
7364
7365 if (n == PRN_FIL) { /* File, check accessibility */
7366 int wild = 0;
7367 if ((x = cmiofi("Filename","kermit.prn",&s,&wild,xxstring))< 0)
7368 if (x == -9) {
7369 if (zchko(s) < 0) {
7370 printf("Can't create \"%s\"\n",s);
7371 return(x);
7372 }
7373 } else goto xsetprn;
7374 if (iswild(s)) {
7375 printf("?A single file please\n");
7376 return(-9);
7377 }
7378 pv[PRN_SPD].ival = 0;
7379 pv[PRN_PAR].ival = 0;
7380 pv[PRN_FLO].ival = FLO_KEEP;
7381 } else if ((x = cmfld(n == PRN_DOS ? /* Value wanted - parse it */
7382 "DOS printer device name" : /* Help message */
7383 (n == PRN_PIP ?
7384 "Program name" :
7385 "Filename"),
7386 n == PRN_DOS ?
7387 "PRN" : /* Default */
7388 "",
7389 &s,
7390 xxstring
7391 )) < 0)
7392 goto xsetprn;
7393 s = brstrip(s); /* Strip enclosing braces */
7394 while (*s == SP) /* Strip leading blanks */
7395 s++;
7396 if (n == PRN_PIP) { /* If /PIPE: */
7397 if (*s == '|') { /* strip any extraneous pipe sign */
7398 s++;
7399 while (*s == SP)
7400 s++;
7401 }
7402 pv[PRN_SPD].ival = 0;
7403 pv[PRN_PAR].ival = 0;
7404 pv[PRN_FLO].ival = FLO_KEEP;
7405 }
7406 if ((y = strlen(s)) > 0) /* Anything left? */
7407 if (pv[n].sval = (char *) malloc(y+1)) /* Yes, keep it */
7408 strcpy(pv[n].sval,s); /* safe */
7409 break;
7410 #ifdef NT
7411 case PRN_WIN: /* Windows queue name */
7412 typeset++;
7413 if (pv[n].sval) free(pv[n].sval);
7414 pv[n].sval = NULL;
7415 pv[PRN_NON].ival = 0;
7416 pv[PRN_DOS].ival = 0;
7417 pv[PRN_FIL].ival = 0;
7418 pv[n].ival = 1;
7419 pv[PRN_SPD].ival = 0;
7420 pv[PRN_PAR].ival = 0;
7421 pv[PRN_FLO].ival = FLO_KEEP;
7422
7423 if (!getval || !haveque)
7424 break;
7425 if ((x = cmkey(_printtab,nprint,"Print queue name",
7426 _printtab[printdef].kwd,xxstring)) < 0) {
7427 if (x != -2)
7428 goto xsetprn;
7429
7430 if (pv[PRN_WIN].sval) free(pv[PRN_WIN].sval);
7431 s = atmbuf;
7432 if ((y = strlen(s)) > 0)
7433 if (pv[n].sval = (char *)malloc(y+1))
7434 strcpy(pv[n].sval,s); /* safe */
7435 } else {
7436 if (pv[PRN_WIN].sval) free(pv[PRN_WIN].sval);
7437 for (i = 0; i < nprint; i++) {
7438 if (x == printtab[i].kwval) {
7439 s = printtab[i].kwd;
7440 break;
7441 }
7442 }
7443 if ((y = strlen(s)) > 0)
7444 if (pv[n].sval = (char *)malloc(y+1))
7445 strcpy(pv[n].sval,s); /* safe */
7446 }
7447 break;
7448 #endif /* NT */
7449
7450 case PRN_SEP: /* /JOB-HEADER (separator) */
7451 if (pv[n].sval) free(pv[n].sval);
7452 pv[n].sval = NULL;
7453 pv[n].ival = 1;
7454 if (!getval) break;
7455 if ((x = cmifi("Filename","",&s,&y,xxstring)) < 0)
7456 goto xsetprn;
7457 if (y) {
7458 printf("?Wildcards not allowed\n");
7459 x = -9;
7460 goto xsetprn;
7461 }
7462 if ((y = strlen(s)) > 0)
7463 if (pv[n].sval = (char *) malloc(y+1))
7464 strcpy(pv[n].sval,s); /* safe */
7465 break;
7466
7467 case PRN_TMO: /* /TIMEOUT:number */
7468 pv[n].ival = 0;
7469 if (!getval) break;
7470 if ((x = cmnum("Seconds","0",10,&y,xxstring)) < 0)
7471 goto xsetprn;
7472 if (y > 999) {
7473 printf("?Sorry - 999 is the maximum\n");
7474 x = -9;
7475 goto xsetprn;
7476 } else
7477 pv[n].ival = y;
7478 break;
7479
7480 case PRN_TRM: /* /END-OF-JOB:string */
7481 if (pv[n].sval) free(pv[n].sval);
7482 pv[n].sval = NULL;
7483 pv[n].ival = 1;
7484 if (!getval) break;
7485 if ((x = cmfld("String (enclose in braces if it contains spaces)",
7486 "",&s,xxstring)) < 0)
7487 goto xsetprn;
7488 s = brstrip(s);
7489 if ((y = strlen(s)) > 0)
7490 if (pv[n].sval = (char *) malloc(y+1))
7491 strcpy(pv[n].sval,s); /* safe */
7492 break;
7493
7494 #ifdef BPRINT
7495 case PRN_FLO:
7496 if (!getval) break;
7497 if ((x = cmkey(flotab,nflo,
7498 "Serial printer-port flow control",
7499 "rts/cts",xxstring)) < 0)
7500 goto xsetprn;
7501 pv[n].ival = x;
7502 break;
7503
7504 #ifndef NOLOCAL
7505 case PRN_SPD:
7506 if (!getval) break;
7507
7508 /* TN_COMPORT here too? */
7509
7510 if ((x = cmkey(spdtab, /* Speed (no default) */
7511 nspd,
7512 "Serial printer-port interface speed",
7513 "9600",
7514 xxstring)
7515 ) < 0)
7516 goto xsetprn;
7517 pv[n].ival = x;
7518 break;
7519 #endif /* NOLOCAL */
7520
7521 case PRN_PAR:
7522 pv[n].ival = 0;
7523 if (!getval) break;
7524 if ((x = cmkey(partbl,npar,"Serial printer-port parity",
7525 "none",xxstring)) < 0)
7526 goto xsetprn;
7527 pv[n].ival = x;
7528 break;
7529 #endif /* BPRINT */
7530
7531 #ifdef OS2
7532 case PRN_LEN:
7533 if (!getval) break;
7534 if ((x = cmnum("PS page length", "66",10,&y,xxstring)) < 0)
7535 goto xsetprn;
7536 pv[n].ival = y;
7537 break;
7538
7539 case PRN_WID:
7540 if (!getval) break;
7541 if ((x = cmnum("PS page width", "80",10,&y,xxstring)) < 0)
7542 goto xsetprn;
7543 pv[n].ival = y;
7544 break;
7545
7546 case PRN_CS:
7547 pv[n].ival = 0;
7548 if (!getval) break;
7549 if ((y = cmkey(
7550 #ifdef CKOUNI
7551 txrtab,ntxrtab,
7552 #else /* CKOUNI */
7553 ttcstab,ntermc,
7554 #endif /* CKOUNI */
7555 "auto-print/printscreen character-set",
7556 "cp437",xxstring)) < 0)
7557 goto xsetprn;
7558 pv[n].ival = y;
7559 break;
7560 #endif /* OS2 */
7561
7562 default:
7563 printf("?Unexpected switch value - %d\n",cmresult.nresult);
7564 x = -9;
7565 goto xsetprn;
7566 }
7567 }
7568 line[0] = NUL; /* Initialize printer name value */
7569 switch (cmresult.fcode) { /* How did we get here? */
7570 case _CMOFI: /* They typed a filename */
7571 ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Name */
7572 wild = cmresult.nresult; /* Wild flag */
7573 if (!typeset) { /* A printer name without a type */
7574 pv[PRN_NON].ival = 0; /* is supposed to be treated as */
7575 pv[PRN_WIN].ival = 0; /* a DOS or Pipe printer. We */
7576 pv[PRN_FIL].ival = 0; /* clear all the flags and let */
7577 pv[PRN_PIP].ival = 0; /* the code below dope out the */
7578 pv[PRN_DOS].ival = 0; /* type. */
7579 }
7580 #ifdef NT
7581 else if (pv[PRN_WIN].ival && lookup(_printtab,line,nprint,&y)) {
7582 /* invalid Window Queue name */
7583 printf("?invalid Windows Printer Queue name: \"%s\"\r\n",line);
7584 x = -9;
7585 goto xsetprn;
7586 }
7587 #endif /* NT */
7588 if ((x = cmcfm()) < 0) /* Confirm the command */
7589 goto xsetprn;
7590 break;
7591 case _CMCFM: /* They entered the command */
7592 if (pv[PRN_DOS].ival > 0)
7593 ckstrncpy(line,pv[PRN_DOS].sval ? pv[PRN_DOS].sval : "",LINBUFSIZ);
7594 else if (pv[PRN_WIN].ival > 0)
7595 ckstrncpy(line,pv[PRN_WIN].sval ? pv[PRN_WIN].sval : "",LINBUFSIZ);
7596 else if (pv[PRN_FIL].ival > 0)
7597 ckstrncpy(line,pv[PRN_FIL].sval ? pv[PRN_FIL].sval : "",LINBUFSIZ);
7598 else if (pv[PRN_PIP].ival > 0)
7599 ckstrncpy(line,pv[PRN_PIP].sval ? pv[PRN_PIP].sval : "",LINBUFSIZ);
7600 break;
7601 default: /* By mistake */
7602 printf("?Unexpected function code: %d\n",cmresult.fcode);
7603 x = -9;
7604 goto xsetprn;
7605 }
7606
7607 #else /* No PRINTSWI */
7608
7609 if ((x = cmofi("Printer or file name",defname,&s,xxstring)) < 0)
7610 return(x);
7611 if (x > 1) {
7612 printf("?Directory names not allowed\n");
7613 return(-9);
7614 }
7615 while (*s == SP || *s == HT) s++; /* Trim leading whitespace */
7616 ckstrncpy(line,s,LINBUFSIZ); /* Make a temporary safe copy */
7617 if ((x = cmcfm()) < 0) return(x); /* Confirm the command */
7618 #endif /* PRINTSWI */
7619
7620 #ifdef IKSD
7621 if (inserver && (isguest
7622 #ifndef NOSERVER
7623 || !ENABLED(en_pri)
7624 #endif /* NOSERVER */
7625 )) {
7626 printf("Sorry, printing disabled\r\n");
7627 return(success = 0);
7628 }
7629 #endif /* ISKD */
7630
7631 #ifdef PRINTSWI
7632 #ifdef BPRINT
7633 if (printbidi) { /* If bidi printing active */
7634 #ifndef UNIX
7635 bprtstop(); /* Stop it before proceeding */
7636 #endif /* UNIX */
7637 printbidi = 0;
7638 }
7639 if (pv[PRN_SPD].ival > 0) {
7640 portspeed = (long) pv[PRN_SPD].ival * 10L;
7641 if (portspeed == 70L) portspeed = 75L;
7642 }
7643 if (pv[PRN_PAR].ival > 0)
7644 portparity = pv[PRN_PAR].ival;
7645 if (pv[PRN_FLO].ival > 0)
7646 portflow = pv[PRN_FLO].ival;
7647 #endif /* BPRINT */
7648 #endif /* PRINTSWI */
7649
7650 s = line; /* Printer name, if given */
7651
7652 #ifdef OS2ORUNIX
7653 #ifdef PRINTSWI
7654 if (pv[PRN_PIP].ival > 0) { /* /PIPE was given? */
7655 printpipe = 1;
7656 noprinter = 0;
7657 if (*s == '|') { /* It might still have a pipe sign */
7658 s++; /* if name give later */
7659 while (*s == SP) /* so remove it and spaces */
7660 s++;
7661 }
7662 } else
7663 #endif /* PRINTSWI */
7664 if (*s == '|') { /* Or pipe implied by name? */
7665 s++; /* Point past pipe sign */
7666 while (*s == SP) /* Gobble whitespace */
7667 s++;
7668 if (*s) {
7669 printpipe = 1;
7670 noprinter = 0;
7671 }
7672 } else {
7673 printpipe = 0;
7674 }
7675
7676 #ifdef PRINTSWI
7677 #ifdef BPRINT
7678 if (printpipe && pv[PRN_BID].ival > 0) {
7679 printf("?Sorry, pipes not allowed for bidirectional printer\n");
7680 return(-9);
7681 }
7682 #endif /* BPRINT */
7683 #endif /* PRINTSWI */
7684 #endif /* OS2ORUNIX */
7685
7686 #ifdef OS2
7687 if ( pv[PRN_CS].ival > 0 )
7688 prncs = pv[PRN_CS].ival;
7689
7690 if ( pv[PRN_PS].ival > 0 ) {
7691 txt2ps = 1;
7692 ps_width = pv[PRN_WID].ival <= 0 ? 80 : pv[PRN_WID].ival;
7693 ps_length = pv[PRN_LEN].ival <= 0 ? 66 : pv[PRN_LEN].ival;
7694 }
7695 #endif /* OS2 */
7696
7697 y = strlen(s); /* Length of name of new print file */
7698 if (y > 0
7699 #ifdef OS2
7700 && ((y != 3) || (ckstrcmp(s,"PRN",3,0) != 0))
7701 #endif /* OS2 */
7702 ) {
7703 if (printername) { /* Had a print file before? */
7704 free(printername); /* Remove its name */
7705 printername = NULL;
7706 }
7707 printername = (char *) malloc(y + 1); /* Allocate space for it */
7708 if (!printername) {
7709 printf("?Memory allocation failure\n");
7710 return(-9);
7711 }
7712 strcpy(printername,s); /* (safe) Copy new name to new space */
7713 debug(F110,"printername",printername,0);
7714 }
7715
7716 #ifdef PRINTSWI
7717 /* Set printer type from switches that were given explicitly */
7718
7719 if (pv[PRN_NON].ival > 0) { /* No printer */
7720 printertype = PRT_NON;
7721 noprinter = 1;
7722 printpipe = 0;
7723 } else if (pv[PRN_FIL].ival > 0) { /* File */
7724 printertype = PRT_FIL;
7725 noprinter = 0;
7726 printpipe = 0;
7727 } else if (pv[PRN_PIP].ival > 0) { /* Pipe */
7728 printertype = PRT_PIP;
7729 noprinter = 0;
7730 printpipe = 1;
7731 } else if (pv[PRN_WIN].ival > 0) { /* Windows print queue */
7732 printertype = PRT_WIN;
7733 noprinter = 0;
7734 printpipe = 0;
7735 } else if (pv[PRN_DOS].ival > 0) { /* DOS device */
7736 printertype = PRT_DOS;
7737 noprinter = 0;
7738 printpipe = 0;
7739 } else if (line[0]) { /* Name given without switches */
7740 noprinter = 0;
7741 printertype = printpipe ? PRT_PIP : PRT_DOS;
7742 #ifdef NT
7743 /* was the command SET PRINTER windows-queue ? */
7744 y = lookup(_printtab,line,nprint,&x);
7745 if (y >= 0) {
7746 printertype = PRT_WIN;
7747 if (pv[PRN_WIN].sval) free(pv[PRN_WIN].sval);
7748 if (printername) { /* Had a print file before? */
7749 free(printername); /* Remove its name */
7750 printername = NULL;
7751 }
7752 pv[PRN_WIN].sval = NULL;
7753 pv[PRN_WIN].ival = 1;
7754 s = printtab[x].kwd; /* Get full new name */
7755 if ((y = strlen(s)) > 0) {
7756 makestr(&pv[PRN_WIN].sval,s);
7757 makestr(&printername,s);
7758 if (!printername) {
7759 printf("?Memory allocation failure\n");
7760 return(-9);
7761 }
7762 debug(F110,"printername",printername,0);
7763 }
7764 } else if ( y == -2 ) {
7765 /* Ambiguous Print Queue Name */
7766 printf("?Ambiguous printer name provided.\n");
7767 return(-9);
7768 }
7769 #endif /* NT */
7770 }
7771
7772 #ifdef BPRINT
7773 /* Port parameters may be set for non-bidi mode */
7774
7775 pportspeed = portspeed; /* Set parameters */
7776 pportparity = portparity;
7777 pportflow = portflow;
7778
7779 if (pv[PRN_BID].ival > 0) { /* Bidirectional */
7780 #ifdef UNIX
7781 printbidi = 1; /* (just to test parsing...) */
7782 #else
7783 printbidi = bprtstart(); /* Start bidirectional printer */
7784 #endif /* UNIX */
7785 return(success = printbidi);
7786 } else
7787 printbidi = 0; /* Not BPRINTER, unset flag */
7788 #endif /* BPRINT */
7789
7790 if (pv[PRN_TMO].ival > -1) { /* Take care of timeout */
7791 printtimo = pv[PRN_TMO].ival;
7792 }
7793 if (pv[PRN_TRM].ival > 0) { /* Termination string */
7794 if (printterm) {
7795 free(printterm);
7796 printterm = NULL;
7797 }
7798 if (pv[PRN_TRM].sval)
7799 makestr(&printterm,pv[PRN_TRM].sval);
7800 }
7801 if (pv[PRN_SEP].ival > 0) { /* and separator file */
7802 if (printsep) {
7803 free(printsep);
7804 printsep = NULL;
7805 }
7806 if (pv[PRN_SEP].sval)
7807 makestr(&printsep,pv[PRN_SEP].sval);
7808 }
7809 #endif /* PRINTSWI */
7810
7811 #ifdef UNIXOROSK
7812 if (!printpipe
7813 #ifdef PRINTSWI
7814 && !noprinter
7815 #endif /* PRINTSWI */
7816 ) { /* File - check access */
7817 if (zchko(s) < 0) {
7818 printf("?Access denied - %s\n",s);
7819 x = -9;
7820 goto xsetprn;
7821 }
7822 }
7823 #endif /* UNIXOROSK */
7824
7825 x = 1; /* Return code */
7826
7827 xsetprn: /* Common exit */
7828 #ifdef PRINTSWI
7829 for (i = 0; i <= PRN_MAX; i++) { /* Free malloc'd memory */
7830 if (pv[i].sval)
7831 free(pv[i].sval);
7832 }
7833 #endif /* PRINTSWI */
7834 success = (x > 0) ? 1 : 0;
7835 return(x);
7836 }
7837
7838 #ifdef ANYSSH
7839 /* The SET SSH command */
7840
7841 #define SSH_CMD 1 /* SET SSH COMMAND */
7842
7843 #ifdef SSHBUILTIN /* Built-in SET SSH options */
7844 #define SSH_ADD 2 /* Add */
7845 #define SSH_AFW 3 /* Agent-forwarding */
7846 #define SSH_CHI 4 /* Check Host IP */
7847 #define SSH_XFW 5 /* X11-forwarding */
7848 #define SSH_DYF 6 /* Dynamic forwarding */
7849 #define SSH_GWP 7 /* Gatewa portgs */
7850 #define SSH_GSS 8 /* GSSAPI */
7851 #define SSH_KBD 9 /* KBD Interactive Devices */
7852 #define SSH_K4 10 /* Kerberos 4 */
7853 #define SSH_K5 11 /* Kerberos 5 */
7854 #define SSH_SHK 12 /* Strict Host Key Check */
7855 #define SSH_V1 13 /* SSH V1 */
7856 #define SSH_V2 14 /* SSH V2 */
7857 #define SSH_PRP 15 /* Privd port */
7858 #define SSH_CMP 16 /* Compression */
7859 #define SSH_XAL 17 /* X Auth Location */
7860 #define SSH_SHH 18 /* Quiet */
7861 #define SSH_VER 19 /* Version */
7862 #define SSH_VRB 20 /* Verbosity level */
7863 #define SSH_IDF 21 /* Identity File */
7864 #define SSH_CFG 22 /* Use OpenSSH Config */
7865 #define SSH_HBT 23 /* Heartbeat Interval */
7866 #endif /* SSHBUILTIN */
7867
7868 static struct keytab sshtab[] = { /* SET SSH command table */
7869 #ifdef SSHBUILTIN
7870 { "agent-forwarding", SSH_AFW, 0 },
7871 { "check-host-ip", SSH_CHI, 0 },
7872 { "compression", SSH_CMP, 0 },
7873 { "dynamic-forwarding", SSH_DYF, 0 },
7874 { "gateway-ports", SSH_GWP, 0 },
7875 { "gssapi", SSH_GSS, 0 },
7876 { "heartbeat-interval", SSH_HBT, 0 },
7877 { "identity-file", SSH_IDF, 0 },
7878 #ifdef COMMENT
7879 { "kbd-interactive-devices", SSH_KBD, 0 },
7880 #endif /* COMMENT */
7881 { "k4", SSH_K4, CM_INV },
7882 { "k5", SSH_K5, CM_INV },
7883 { "kerberos4", SSH_K4, 0 },
7884 { "kerberos5", SSH_K5, 0 },
7885 { "krb4", SSH_K4, CM_INV },
7886 { "krb5", SSH_K5, CM_INV },
7887 { "privileged-port", SSH_PRP, 0 },
7888 { "quiet", SSH_SHH, 0 },
7889 { "strict-host-key-check", SSH_SHK, 0 },
7890 { "use-openssh-config", SSH_CFG, 0 },
7891 { "v1", SSH_V1, 0 },
7892 { "v2", SSH_V2, 0 },
7893 { "verbose", SSH_VRB, 0 },
7894 { "version", SSH_VER, 0 },
7895 { "x11-forwarding", SSH_XFW, 0 },
7896 { "xauth-location", SSH_XAL, 0 },
7897 #else
7898 #ifdef SSHCMD
7899 { "command", SSH_CMD, 0 },
7900 #endif /* SSHCMD */
7901 #endif /* SSHBUILTIN */
7902 { "", 0, 0 }
7903 };
7904 static int nsshtab = (sizeof(sshtab) / sizeof(struct keytab)) - 1;
7905
7906 #ifdef SSHBUILTIN
7907 static struct keytab sshver[] = { /* SET SSH VERSION command table */
7908 { "1", 1, 0 },
7909 { "2", 2, 0 },
7910 { "automatic", 0, 0 }
7911 };
7912
7913 #define SSHA_CRS 1
7914 #define SSHA_DSA 2
7915 #define SSHA_GSS 3
7916 #define SSHA_HOS 4
7917 #define SSHA_KBD 5
7918 #define SSHA_K4 6
7919 #define SSHA_K5 7
7920 #define SSHA_PSW 8
7921 #define SSHA_PK 9
7922 #define SSHA_SKE 10
7923 #define SSHA_TIS 11
7924 #define SSHA_EXT 12
7925 #define SSHA_SRP 13
7926
7927 static struct keytab ssh2aut[] = { /* SET SSH V2 AUTH command table */
7928 { "external-keyx", SSHA_EXT, 0 },
7929 { "gssapi", SSHA_GSS, 0 },
7930 { "hostbased", SSHA_HOS, 0 },
7931 { "keyboard-interactive", SSHA_KBD, 0 },
7932 { "password", SSHA_PSW, 0 },
7933 { "publickey", SSHA_PK, 0 },
7934 { "srp-gex-sha1", SSHA_SRP, 0 },
7935 { "", 0, 0 }
7936 };
7937 static int nssh2aut = (sizeof(ssh2aut) / sizeof(struct keytab)) - 1;
7938
7939 #define SSHF_LCL 1
7940 #define SSHF_RMT 2
7941
7942 static struct keytab addfwd[] = { /* SET SSH ADD command table */
7943 { "local-port-forward", SSHF_LCL, 0 },
7944 { "remote-port-forward", SSHF_RMT, 0 },
7945 { "", 0, 0 }
7946 };
7947 static int naddfwd = (sizeof(addfwd) / sizeof(struct keytab)) - 1;
7948
7949 #define SSH1_CIF 1
7950 #define SSH1_GNH 2
7951 #define SSH1_UNH 3
7952 #define SSH1_K54 4
7953
7954 #define SSH2_CIF 1
7955 #define SSH2_GNH 2
7956 #define SSH2_UNH 3
7957 #define SSH2_ARK 4
7958 #define SSH2_HKA 5
7959 #define SSH2_MAC 6
7960 #define SSH2_AUT 7
7961
7962 static struct keytab sshv1tab[] = { /* SET SSH V1 command table */
7963 { "cipher", SSH1_CIF, 0 },
7964 { "global-known-hosts-file", SSH1_GNH, 0 },
7965 { "k5-reuse-k4-messages", SSH1_K54, CM_INV },
7966 { "user-known-hosts-file", SSH1_UNH, 0 },
7967 { "", 0, 0 }
7968 };
7969 static int nsshv1tab = (sizeof(sshv1tab) / sizeof(struct keytab)) - 1;
7970
7971 static struct keytab sshv2tab[] = { /* SET SSH V2 command table */
7972 { "authentication", SSH2_AUT, 0 },
7973 { "auto-rekey", SSH2_ARK, 0 },
7974 { "ciphers", SSH2_CIF, 0 },
7975 { "global-known-hosts-file", SSH2_GNH, 0 },
7976 { "hostkey-algorithms", SSH2_HKA, 0 },
7977 { "macs", SSH2_MAC, 0 },
7978 { "user-known-hosts-file", SSH2_UNH, 0 },
7979 { "", 0, 0 }
7980 };
7981 static int nsshv2tab = (sizeof(sshv2tab) / sizeof(struct keytab)) - 1;
7982
7983 #define SSHC_3DES 1 /* 3DES */
7984 #define SSHC_3CBC 2 /* 3DES-CBC */
7985 #define SSHC_A128 3 /* AES128-CBC */
7986 #define SSHC_A192 4 /* AES192-CBC */
7987 #define SSHC_A256 5 /* AES256-CBC */
7988 #define SSHC_ARC4 6 /* ARCFOUR */
7989 #define SSHC_FISH 7 /* BLOWFISH */
7990 #define SSHC_BCBC 9 /* BLOWFISH-CBC */
7991 #define SSHC_C128 8 /* CAST128-CBC */
7992 #define SSHC_1DES 10 /* DES */
7993
7994 static struct keytab ssh1ciphers[] = {
7995 { "3des", SSHC_3DES, 0 },
7996 { "blowfish", SSHC_FISH, 0 },
7997 { "des", SSHC_1DES, 0 },
7998 { "", 0, 0 }
7999 };
8000 static int nssh1ciphers = (sizeof(ssh1ciphers) / sizeof(struct keytab)) - 1;
8001
8002 static struct keytab ssh2ciphers[] = { /* SET SSH V2 CIPHERS command table */
8003 { "3des-cbc", SSHC_3DES, 0 },
8004 { "aes128-cbc", SSHC_A128, 0 },
8005 { "aes192-cbc", SSHC_A192, 0 },
8006 { "aes256-cbc", SSHC_A256, 0 },
8007 { "arcfour", SSHC_ARC4, 0 },
8008 { "blowfish-cbc", SSHC_FISH, 0 },
8009 { "cast128-cbc", SSHC_C128, 0 },
8010 { "rijndael128-cbc", SSHC_A128, 0 },
8011 { "rijndael192-cbc", SSHC_A192, 0 },
8012 { "rijndael256-cbc", SSHC_A256, 0 },
8013 { "", 0, 0 }
8014 };
8015 static int nssh2ciphers = (sizeof(ssh2ciphers) / sizeof(struct keytab)) - 1;
8016
8017 #define SSHM_SHA 1 /* HMAC-SHA1 */
8018 #define SSHM_SHA_96 2 /* HMAC-SHA1-96 */
8019 #define SSHM_MD5 3 /* HMAC-MD5 */
8020 #define SSHM_MD5_96 4 /* HMAC-MD5-96 */
8021 #define SSHM_RIPE 5 /* HMAC-RIPEMD160 */
8022
8023 static struct keytab ssh2macs[] = { /* SET SSH V2 MACS command table */
8024 { "hmac-md5", SSHM_MD5, 0 },
8025 { "hmac-md5-96", SSHM_MD5_96, 0 },
8026 { "hmac-ripemd160", SSHM_RIPE, 0 },
8027 { "hmac-sha1", SSHM_SHA, 0 },
8028 { "hmac-sha1-96", SSHM_SHA_96, 0 },
8029 { "", 0, 0 }
8030 };
8031 static int nssh2macs = (sizeof(ssh2macs) / sizeof(struct keytab)) - 1;
8032
8033 static struct keytab tgtpass[] = {
8034 { "tgt-passing", 1, 0, },
8035 { "", 0, 0 }
8036 };
8037 static int ntgtpass = (sizeof(tgtpass) / sizeof(struct keytab)) - 1;
8038
8039 static struct keytab gssapitab[] = {
8040 { "delegate-credentials", 1, 0, },
8041 { "key-exchange", 2, CM_INV, },
8042 { "", 0, 0 }
8043 };
8044 static int ngssapitab = (sizeof(gssapitab) / sizeof(struct keytab)) - 1;
8045
8046 #define HKA_RSA 1
8047 #define HKA_DSS 2
8048
8049 static struct keytab hkatab[] = {
8050 { "ssh-dss", HKA_DSS, 0, },
8051 { "ssh-rsa", HKA_RSA, 0, },
8052 { "", 0, 0 }
8053 };
8054 static int nhkatab = (sizeof(hkatab) / sizeof(struct keytab)) - 1;
8055
8056 int /* SET SSH variables */
8057 ssh_afw = 0, /* agent forwarding */
8058 ssh_xfw = 0, /* x11 forwarding */
8059 ssh_prp = SET_OFF, /* privileged ports */
8060 ssh_cmp = 1, /* compression */
8061 ssh_shh = 0, /* quiet */
8062 ssh_ver = 0, /* protocol version (auto,1,2) */
8063 ssh_vrb = 2, /* Report errors */
8064 ssh_chkip = 0, /* SSH Check Host IP flag */
8065 ssh_gwp = 0, /* gateway ports */
8066 ssh_dyf = 0, /* dynamic forwarding */
8067 ssh_gsd = 0, /* gssapi delegate credentials */
8068 ssh_k4tgt = 0, /* k4 tgt passing */
8069 ssh_k5tgt = 0, /* k5 tgt passing */
8070 ssh_shk = 2, /* Strict host key (no, yes, ask) */
8071 ssh2_ark = 1, /* Auto re-key */
8072 ssh_cas = 0, /* command as subsys */
8073 ssh_cfg = 0, /* use OpenSSH config? */
8074 ssh_gkx = 1, /* gssapi key exchange */
8075 ssh_k5_is_k4 = 1, /* some SSH v1 use same codes */
8076 ssh_hbt = 0, /* heartbeat (seconds) */
8077 ssh_dummy = 0; /* bottom of list */
8078
8079 char /* The following are to be malloc'd */
8080 * ssh1_cif = NULL, /* v1 cipher */
8081 * ssh2_cif = NULL, /* v2 cipher list */
8082 * ssh2_mac = NULL, /* v2 mac list */
8083 * ssh2_auth = NULL, /* v2 authentication list */
8084 * ssh_hst = NULL, /* hostname */
8085 * ssh_prt = NULL, /* port/service */
8086 * ssh_cmd = NULL, /* command to execute */
8087 * ssh_xal = NULL, /* xauth-location */
8088 * ssh1_gnh = NULL, /* v1 global known hosts file */
8089 * ssh1_unh = NULL, /* v1 user known hosts file */
8090 * ssh2_gnh = NULL, /* v2 global known hosts file */
8091 * ssh2_unh = NULL, /* v2 user known hosts file */
8092 * ssh2_hka = NULL, /* Host Key Algorithms */
8093 * xxx_dummy = NULL;
8094
8095 char * ssh_idf[32] = { /* Identity file list */
8096 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
8097 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
8098 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
8099 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
8100 };
8101 char * ssh_tmp[32] = { /* Temp identity file list */
8102 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
8103 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
8104 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
8105 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
8106 };
8107 int ssh_idf_n = 0;
8108
8109 extern int ssh_pf_lcl_n,
8110 ssh_pf_rmt_n;
8111 extern struct ssh_pf ssh_pf_lcl[32]; /* Port forwarding structs */
8112 extern struct ssh_pf ssh_pf_rmt[32]; /* (declared in ckuusr.c) */
8113 #endif /* SSHBUILTIN */
8114
8115 #ifdef SFTP_BUILTIN
8116 static struct keytab sftptab[] = {
8117 { "end-of-line", XY_SFTP_EOL, 0, },
8118 { "remote-character-set", XY_SFTP_RCS, 0, },
8119 { "", 0, 0 }
8120 };
8121 static int nsftptab = (sizeof(sftptab) / sizeof(struct keytab)) - 1;
8122 #endif /* SFTP_BUILTIN */
8123
8124 VOID
8125 shossh() {
8126 #ifdef SSHBUILTIN
8127 int i, n = 0; /* ADD askmore()! */
8128
8129 printf("\nSSH is built in:\n\n");
8130
8131 printf(" ssh host: %s\n",showstring(ssh_hst));
8132 printf(" ssh port: %s\n",showstring(ssh_prt));
8133 printf(" ssh command: %s\n",showstring(ssh_cmd));
8134 printf(" ssh agent-forwarding: %s\n",showoff(ssh_afw));
8135 printf(" ssh check-host-ip: %s\n",showoff(ssh_chkip));
8136 printf(" ssh compression: %s\n",showoff(ssh_cmp));
8137 printf(" ssh dynamic-forwarding: %s\n",showoff(ssh_dyf));
8138 if (ssh_pf_lcl[0].p1 && ssh_pf_lcl[0].host && ssh_pf_lcl[0].p2) {
8139 printf(" ssh forward-local-port: %d %s %d\n",
8140 ssh_pf_lcl[0].p1, ssh_pf_lcl[0].host, ssh_pf_lcl[0].p2);
8141 for ( n=1;n<ssh_pf_lcl_n;n++ )
8142 printf(" : %d %s %d\n",
8143 ssh_pf_lcl[n].p1, ssh_pf_lcl[n].host, ssh_pf_lcl[n].p2);
8144 } else
8145 printf(" ssh forward-local-port: (none)\n");
8146 if (ssh_pf_rmt[0].p1 && ssh_pf_rmt[0].host && ssh_pf_rmt[0].p2) {
8147 printf(" ssh forward-remote-port: %d %s %d\n",
8148 ssh_pf_rmt[0].p1, ssh_pf_rmt[0].host, ssh_pf_rmt[0].p2);
8149 for ( n=1;n<ssh_pf_rmt_n;n++ )
8150 printf(" : %d %s %d\n",
8151 ssh_pf_rmt[n].p1, ssh_pf_rmt[n].host, ssh_pf_rmt[n].p2);
8152 } else
8153 printf(" ssh forward-remote-port: (none)\n");
8154 printf(" ssh gateway-ports: %s\n",showoff(ssh_gwp));
8155 printf(" ssh gssapi delegate-credentials: %s\n",showoff(ssh_gsd));
8156 printf(" ssh gssapi key-exchange : %s\n",showoff(ssh_gkx));
8157 printf(" ssh identity-file: %d\n",ssh_idf_n);
8158 for (i = 0; i < ssh_idf_n; i++)
8159 printf(" %2d. %s\n",i+1,showstring(ssh_idf[i]));
8160 printf(" ssh heartbeat interval: %d\n", ssh_hbt);
8161 printf(" ssh k4 tgt-passing: %s\n",showoff(ssh_k4tgt));
8162 printf(" ssh k5 tgt-passing: %s\n",showoff(ssh_k5tgt));
8163
8164 printf(" ssh privileged-port: %s\n",showooa(ssh_prp));
8165 printf(" ssh quiet: %s\n",showoff(ssh_shh));
8166 printf(" ssh strict-host-key-check: %d\n",ssh_shk);
8167 printf(" ssh use-openssh-config: %s\n",showoff(ssh_cfg));
8168 printf(" ssh verbose: %d\n",ssh_vrb);
8169 printf(" ssh version: %s\n",
8170 ssh_ver ? ckitoa(ssh_ver) : "automatic"
8171 );
8172 printf(" ssh x11-forwarding: %s\n",showooa(ssh_xfw));
8173 printf(" ssh xauth-location: %s\n",showstring(ssh_xal));
8174 printf("\n");
8175 printf(" ssh v1 cipher: %s\n",showstring(ssh1_cif));
8176 printf(" ssh v1 global-known-hosts-file: %s\n",showstring(ssh1_gnh));
8177 printf(" ssh v1 user-known-hosts-file: %s\n",showstring(ssh1_unh));
8178 printf("\n");
8179 printf(" ssh v2 authentication: %s\n",showstring(ssh2_auth));
8180 printf(" ssh v2 auto-rekey: %s\n",showoff(ssh2_ark));
8181 printf(" ssh v2 ciphers: %s\n",showstring(ssh2_cif));
8182 printf(" ssh v2 command-as-subsystem: %s\n",showoff(ssh_cas));
8183 printf(" ssh v2 global-known-hosts-file: %s\n",showstring(ssh2_gnh));
8184 printf(" ssh v2 hostkey-algorithms: %s\n",showstring(ssh2_hka));
8185 printf(" ssh v2 mac: %s\n",showstring(ssh2_mac));
8186 printf(" ssh v2 user-known-hosts-file: %s\n",showstring(ssh2_unh));
8187 #else
8188 #ifdef SSHCMD
8189 extern char * sshcmd, * defsshcmd;
8190 char * s;
8191 s = sshcmd ? sshcmd : defsshcmd;
8192 printf("\n SSH is external.\n\n");
8193 printf(" ssh command: %s\n",showstring(s));
8194 #endif /* SSHCMD */
8195 #endif /* SSHBUILTIN */
8196 printf("\n");
8197 }
8198
8199 static int
8200 dosetssh() {
8201 #ifdef SSHCMD
8202 extern char * sshcmd;
8203 #endif /* SSHCMD */
8204 #ifdef SSHBUILTIN
8205 #ifndef SSHTEST
8206 extern int sl_ssh_xfw_saved, sl_ssh_ver_saved;
8207 #endif /* SSHTEST */
8208 #endif /* SSHBUILTIN */
8209 int cx, x, y, z;
8210 char * s;
8211
8212 if ((cx = cmkey(sshtab,nsshtab,"","command", xxstring)) < 0)
8213 return(cx);
8214 switch (cx) {
8215 #ifdef SSHCMD
8216 case SSH_CMD: /* Command */
8217 if ((x = cmtxt("Command to start ssh","ssh -e none",
8218 &s,xxstring)) < 0)
8219 return(x);
8220 makestr(&sshcmd,s);
8221 return(success = 1);
8222 #endif /* SSHCMD */
8223
8224 #ifdef SSHBUILTIN
8225 case SSH_AFW: /* Agent-forwarding */
8226 return(success = seton(&ssh_afw));
8227
8228 case SSH_CHI: /* Check Host IP */
8229 return(success = seton(&ssh_chkip));
8230 break;
8231
8232 case SSH_CMP: /* Compression */
8233 return(success = seton(&ssh_cmp));
8234
8235 case SSH_DYF: /* Dynamic Forwarding */
8236 return(success = seton(&ssh_dyf));
8237
8238 case SSH_GWP: /* Gateway ports */
8239 return(success = seton(&ssh_gwp));
8240
8241 case SSH_GSS: /* GSSAPI */
8242 if ((y = cmkey(gssapitab,ngssapitab,"","", xxstring)) < 0)
8243 return(y);
8244 switch (y) {
8245 case 1: /* Delegate credentials */
8246 return(success = seton(&ssh_gsd));
8247 case 2: /* key-exchange */
8248 return(success = seton(&ssh_gkx));
8249 }
8250 if ((x = cmcfm()) < 0)
8251 return(x);
8252 return(success = 0);
8253
8254 #ifdef COMMENT
8255 case SSH_KBD: /* Kbd Interactive Devices */
8256 if ((x = cmcfm()) < 0)
8257 return(x);
8258 /* TO BE FILLED IN */
8259 return(-2);
8260 #endif /* COMMENT */
8261
8262 case SSH_K4: /* Kerberos IV */
8263 case SSH_K5: /* Kerberos V */
8264 if ((y = cmkey(tgtpass,1,"","tgt-passing", xxstring)) < 0)
8265 return(y);
8266 switch (y) {
8267 case 1:
8268 return(success = (cx == SSH_K4) ?
8269 seton(&ssh_k4tgt) : seton(&ssh_k5tgt));
8270 }
8271 if ((x = cmcfm()) < 0)
8272 return(x);
8273 return(success = 0);
8274
8275 case SSH_PRP: /* Privd port */
8276 return(success = seton(&ssh_prp));
8277
8278 case SSH_SHH: /* Quiet */
8279 return(success = seton(&ssh_shh));
8280
8281 case SSH_SHK: /* Strict Host Key Check */
8282 if ((y = cmkey(ooktab,3,"","", xxstring)) < 0)
8283 return(y);
8284 if ((x = cmcfm()) < 0)
8285 return(x);
8286 ssh_shk = y;
8287 return(success = 1);
8288
8289 case SSH_HBT:
8290 x = cmnum("Heartbeat interval, seconds","0",10,&z,xxstring);
8291 if (x < 0) return(x);
8292 if ((x = cmcfm()) < 0) return(x);
8293 ssh_hbt = z;
8294 return(success = 1);
8295
8296 case SSH_V1: /* SSH V1 */
8297 if ((y = cmkey(sshv1tab,nsshv1tab,"","", xxstring)) < 0)
8298 return(y);
8299 switch (y) {
8300 case SSH1_K54:
8301 return(success = seton(&ssh_k5_is_k4));
8302 case SSH1_CIF: /* Not a list */
8303 if ((y = cmkey(ssh1ciphers,nssh1ciphers,"","", xxstring)) < 0)
8304 if (y != -3)
8305 return(y);
8306 if ((x = cmcfm()) < 0) return(x);
8307 if (y == -3) {
8308 makestr(&ssh1_cif,NULL);
8309 } else {
8310 for (x = 0; x < nssh1ciphers; x++)
8311 if (ssh1ciphers[x].kwval == y)
8312 break;
8313 makestr(&ssh1_cif,ssh1ciphers[x].kwd);
8314 }
8315 return(1);
8316 case SSH1_GNH:
8317 case SSH1_UNH:
8318 if ((x = cmifi("Filename","",&s,&z,xxstring)) < 0) {
8319 if (x != -3)
8320 return(x);
8321 } else {
8322 ckstrncpy(line,s,LINBUFSIZ);
8323 if (zfnqfp(line,TMPBUFSIZ,tmpbuf))
8324 ckstrncpy(line,tmpbuf,LINBUFSIZ);
8325 }
8326 s = (x == -3) ? NULL : line;
8327 if ((x = cmcfm()) < 0)
8328 return(x);
8329 switch (y) {
8330 case SSH1_GNH: makestr(&ssh1_gnh,s); break;
8331 case SSH1_UNH: makestr(&ssh1_unh,s); break;
8332 }
8333 return(1);
8334 }
8335
8336 case SSH_V2: /* SSH V2 */
8337 if ((y = cmkey(sshv2tab,nsshv2tab,"","", xxstring)) < 0)
8338 return(y);
8339 switch (y) {
8340 case SSH2_ARK:
8341 return(success = seton(&ssh2_ark));
8342 case SSH2_AUT: { /* Authentication */
8343 #define TMPCNT 12
8344 int i, j, tmp[TMPCNT];
8345 for (i = 0; i < TMPCNT; i++)
8346 tmp[i] = 0;
8347 for (i = 0; i < TMPCNT; i++) {
8348 if ((y = cmkey(ssh2aut,nssh2aut,
8349 "Authentication method","",xxstring)) < 0) {
8350 if (y == -3)
8351 break;
8352 return(y);
8353 }
8354 for (j = 0; j < i; j++) {
8355 if (tmp[j] == y) {
8356 printf("\r\n?Choice has already been used.\r\n");
8357 return(-9);
8358 }
8359 }
8360 tmp[i] = y;
8361 }
8362 if ((z = cmcfm()) < 0)
8363 return(z);
8364
8365 if (ssh2_auth) {
8366 free(ssh2_auth);
8367 ssh2_auth = NULL;
8368 }
8369 if (i > 0) {
8370 int len = 0;
8371 for (j = 0; j < i; j++) {
8372 for (x = 0; x < nssh2aut; x++)
8373 if (ssh2aut[x].kwval == tmp[j] && !ssh2aut[x].flgs)
8374 break;
8375 len += strlen(ssh2aut[x].kwd) + 1;
8376 }
8377 ssh2_auth = malloc(len);
8378 ssh2_auth[0] = '\0';
8379 for (j = 0; j < i; j++) {
8380 for (x = 0; x < nssh2aut; x++)
8381 if (ssh2aut[x].kwval == tmp[j] && !ssh2aut[x].flgs)
8382 break;
8383 ckstrncat(ssh2_auth,ssh2aut[x].kwd,len);
8384 if (j < i - 1)
8385 ckstrncat(ssh2_auth,",",len);
8386 }
8387 }
8388 return(success = 1);
8389 #undef TMPCNT
8390 }
8391 case SSH2_CIF: {
8392 #define TMPCNT 12
8393 int i, j, tmp[TMPCNT];
8394 for (i = 0; i < TMPCNT; i++)
8395 tmp[i] = 0;
8396
8397 for (i = 0; i < TMPCNT; i++) {
8398 if ((y = cmkey(ssh2ciphers,nssh2ciphers,
8399 "","", xxstring)) < 0) {
8400 if (y == -3)
8401 break;
8402 return(y);
8403 }
8404 for (j = 0; j < i; j++) {
8405 if (tmp[j] == y) {
8406 printf("\r\n?Choice has already been used.\r\n");
8407 return(-9);
8408 }
8409 }
8410 tmp[i] = y;
8411 }
8412 if ((z = cmcfm()) < 0)
8413 return(z);
8414
8415 if (ssh2_cif) {
8416 free(ssh2_cif);
8417 ssh2_cif = NULL;
8418 }
8419 if (i > 0) {
8420 int len = 0;
8421 for (j=0; j < i; j++) {
8422 for (x = 0; x < nssh2ciphers; x++)
8423 if (ssh2ciphers[x].kwval == tmp[j] &&
8424 !ssh2ciphers[x].flgs)
8425 break;
8426 len += strlen(ssh2ciphers[x].kwd) + 1;
8427 }
8428 ssh2_cif = malloc(len);
8429 ssh2_cif[0] = '\0';
8430 for (j = 0; j < i; j++) {
8431 for (x = 0; x < nssh2ciphers; x++)
8432 if (ssh2ciphers[x].kwval == tmp[j] && !ssh2ciphers[x].flgs)
8433 break;
8434 ckstrncat(ssh2_cif,ssh2ciphers[x].kwd,len);
8435 if (j < i - 1)
8436 ckstrncat(ssh2_cif,",",len);
8437 }
8438 }
8439 return(success = 1);
8440 #undef TMPCNT
8441 }
8442 case SSH2_MAC: {
8443 #define TMPCNT 12
8444 int i, j, tmp[TMPCNT];
8445 for (i = 0; i < TMPCNT; i++)
8446 tmp[i] = 0;
8447
8448 for (i = 0; i < TMPCNT; i++) {
8449 if ((y = cmkey(ssh2macs,nssh2macs,"","", xxstring)) < 0) {
8450 if (y == -3)
8451 break;
8452 return(y);
8453 }
8454 for (j = 0; j < i; j++) {
8455 if (tmp[j] == y) {
8456 printf("\r\n?Choice has already been used.\r\n");
8457 return(-9);
8458 }
8459 }
8460 tmp[i] = y;
8461 }
8462 if ((z = cmcfm()) < 0)
8463 return(z);
8464
8465 if (ssh2_mac) {
8466 free(ssh2_mac);
8467 ssh2_mac = NULL;
8468 }
8469 if (i > 0) {
8470 int len = 0;
8471 for (j = 0; j < i; j++) {
8472 for (x = 0; x < nssh2macs; x++)
8473 if (ssh2macs[x].kwval == tmp[j] && !ssh2macs[x].flgs)
8474 break;
8475 len += strlen(ssh2macs[x].kwd) + 1;
8476 }
8477 ssh2_mac = malloc(len);
8478 ssh2_mac[0] = '\0';
8479 for (j=0; j < i; j++) {
8480 for (x = 0; x < nssh2macs; x++)
8481 if (ssh2macs[x].kwval == tmp[j] && !ssh2macs[x].flgs)
8482 break;
8483 ckstrncat(ssh2_mac,ssh2macs[x].kwd,len);
8484 if (j < i - 1)
8485 ckstrncat(ssh2_mac,",",len);
8486 }
8487 }
8488 return(success = 1);
8489 #undef TMPCNT
8490 }
8491 case SSH2_HKA: {
8492 #define TMPCNT 12
8493 int i, j, tmp[TMPCNT];
8494 for (i = 0; i < TMPCNT; i++)
8495 tmp[i] = 0;
8496
8497 for (i = 0; i < TMPCNT; i++) {
8498 if ((y = cmkey(hkatab,nhkatab,
8499 "","", xxstring)) < 0) {
8500 if (y == -3)
8501 break;
8502 return(y);
8503 }
8504 for (j = 0; j < i; j++) {
8505 if (tmp[j] == y) {
8506 printf("\r\n?Choice has already been used.\r\n");
8507 return(-9);
8508 }
8509 }
8510 tmp[i] = y;
8511 }
8512 if ((z = cmcfm()) < 0)
8513 return(z);
8514
8515 if (ssh2_hka) {
8516 free(ssh2_hka);
8517 ssh2_hka = NULL;
8518 }
8519 if (i > 0) {
8520 int len = 0;
8521 for (j=0; j < i; j++) {
8522 for (x = 0; x < nhkatab; x++)
8523 if (hkatab[x].kwval == tmp[j] &&
8524 !hkatab[x].flgs)
8525 break;
8526 len += strlen(hkatab[x].kwd) + 1;
8527 }
8528 ssh2_hka = malloc(len);
8529 ssh2_hka[0] = '\0';
8530 for (j = 0; j < i; j++) {
8531 for (x = 0; x < nhkatab; x++)
8532 if (hkatab[x].kwval == tmp[j] && !hkatab[x].flgs)
8533 break;
8534 ckstrncat(ssh2_hka,hkatab[x].kwd,len);
8535 if (j < i - 1)
8536 ckstrncat(ssh2_hka,",",len);
8537 }
8538 }
8539 return(success = 1);
8540 #undef TMPCNT
8541 }
8542 case SSH2_GNH:
8543 case SSH2_UNH:
8544 if ((x = cmifi("Filename","",&s,&z,xxstring)) < 0) {
8545 if (x != -3)
8546 return(x);
8547 } else {
8548 ckstrncpy(line,s,LINBUFSIZ);
8549 if (zfnqfp(line,TMPBUFSIZ,tmpbuf))
8550 ckstrncpy(line,tmpbuf,LINBUFSIZ);
8551 }
8552 s = (x == -3) ? NULL : line;
8553 if ((x = cmcfm()) < 0)
8554 return(x);
8555 switch (y) {
8556 case SSH2_GNH: makestr(&ssh2_gnh,s); break;
8557 case SSH2_UNH: makestr(&ssh2_unh,s); break;
8558 default: return(success = 0);
8559 }
8560 return(success = 1);
8561 }
8562
8563 case SSH_VRB: /* Verbosity level */
8564 y = cmnum("SSH verbosity level, 0-7","2",10,&x,xxstring);
8565 return(setnum(&ssh_vrb,x,y,7));
8566
8567 case SSH_VER: /* Version */
8568 if ((y = cmkey(sshver,3,"","auto", xxstring)) < 0)
8569 return(y);
8570 if ((x = cmcfm()) < 0)
8571 return(x);
8572 ssh_ver = y; /* 0 == AUTO */
8573 #ifndef SSHTEST
8574 sl_ssh_ver_saved = 0;
8575 #endif /* SSHTEST */
8576 return(success = 1);
8577
8578 case SSH_IDF: { /* Identity file */
8579 int i, n;
8580 for (i = 0; i < 32; i++) {
8581 if ((x = cmifi("Filename","",&s,&y,xxstring)) < 0) {
8582 if (x == -3)
8583 break;
8584 return(x);
8585 }
8586 if (!zfnqfp(s,LINBUFSIZ,line))
8587 ckstrncpy(line,s,LINBUFSIZ);
8588 makestr(&ssh_tmp[i],line);
8589 }
8590 n = i;
8591 if ((x = cmcfm()) < 0) {
8592 for (i = 0; i < n; i++)
8593 makestr(&(ssh_tmp[i]),NULL);
8594 return(x);
8595 }
8596 for (i = 0; i < 32; i++) {
8597 makestr(&(ssh_idf[i]),NULL);
8598 if (i < n) {
8599 ssh_idf[i] = ssh_tmp[i];
8600 ssh_tmp[i] = NULL;
8601 } else {
8602 makestr(&(ssh_tmp[i]),NULL);
8603 }
8604 }
8605 ssh_idf_n = n;
8606 return(success = 1);
8607 }
8608 case SSH_XFW: /* X11-forwarding */
8609 success = seton(&ssh_xfw);
8610 #ifndef SSHTEST
8611 if (success)
8612 sl_ssh_xfw_saved = 0;
8613 #endif /* SSHTEST */
8614 return(success);
8615
8616 case SSH_XAL: /* SSH Xauth Location */
8617 if ((x = cmifi("Path to executable", "",&s,&y,xxstring)) < 0) {
8618 if (x != -3)
8619 return(x);
8620 } else {
8621 ckstrncpy(line,s,LINBUFSIZ);
8622 if (zfnqfp(line,TMPBUFSIZ,tmpbuf))
8623 ckstrncpy(line,tmpbuf,LINBUFSIZ);
8624 }
8625 s = (x == -3) ? NULL : line;
8626 if ((x = cmcfm()) < 0) return(x);
8627 makestr(&ssh_xal,s);
8628 return(success = 1);
8629
8630 case SSH_CFG: /* Use OpenSSH Config */
8631 return(success = seton(&ssh_cfg));
8632 #endif /* SSHBUILTIN */
8633
8634 default:
8635 return(-2);
8636 }
8637 }
8638 #endif /* ANYSSH */
8639
8640 #ifdef SFTP_BUILTIN
8641 static int
8642 dosetsftp() {
8643 int cx, x, y, z;
8644 char * s;
8645
8646 if ((cx = cmkey(sftptab,nsftptab,"","", xxstring)) < 0)
8647 return(cx);
8648 switch (cx) {
8649 case XY_SFTP_EOL:
8650 case XY_SFTP_RCS:
8651 default:
8652 return(-2);
8653 }
8654 }
8655 #endif /* SFTP_BUILTIN */
8656
8657 #ifdef KUI
8658 #include "ikui.h"
8659 extern ULONG RGBTable[16];
8660
8661 #define GUI_RGB 1
8662 #define GUI_WIN 2
8663 #define GUI_FON 3
8664 #define GUI_DIA 4
8665 #define GUI_TLB 5
8666 #define GUI_MNB 6
8667 #define GUI_CLS 7
8668
8669 #define GUIW_POS 1
8670 #define GUIW_RES 2
8671 #define GUIW_RUN 3
8672 #define GUIWR_NON 0
8673 #define GUIWR_FON 1
8674 #define GUIWR_DIM 2
8675 #define GUIWN_RES 1
8676 #define GUIWN_MIN 2
8677 #define GUIWN_MAX 3
8678
8679 static struct keytab guitab[] = {
8680 { "close", GUI_CLS, 0 },
8681 { "dialogs", GUI_DIA, 0 },
8682 { "font", GUI_FON, 0 },
8683 { "menubar", GUI_MNB, 0 },
8684 { "rgbcolor", GUI_RGB, 0 },
8685 { "toolbar", GUI_TLB, 0 },
8686 { "window", GUI_WIN, 0 },
8687 { "", 0, 0}
8688 };
8689 static int nguitab = (sizeof(guitab) / sizeof(struct keytab));
8690
8691 static struct keytab guiwtab[] = {
8692 { "position", GUIW_POS, 0 },
8693 { "resize-mode", GUIW_RES, 0 },
8694 { "run-mode", GUIW_RUN, 0 },
8695 { "", 0, 0}
8696 };
8697 static int nguiwtab = (sizeof(guiwtab) / sizeof(struct keytab));
8698
8699 static struct keytab guiwrtab[] = {
8700 { "change-dimensions", GUIWR_DIM, 0 },
8701 { "none", GUIWR_NON, 0 },
8702 { "scale-font", GUIWR_FON, 0 },
8703 { "", 0, 0}
8704 };
8705 static int nguiwrtab = (sizeof(guiwrtab) / sizeof(struct keytab));
8706
8707 static struct keytab guiwntab[] = {
8708 { "maximize", GUIWN_MAX, 0 },
8709 { "minimize", GUIWN_MIN, 0 },
8710 { "restore", GUIWN_RES, 0 },
8711 { "", 0, 0}
8712 };
8713 static int nguiwntab = (sizeof(guiwntab) / sizeof(struct keytab));
8714
8715 static struct keytab rgbtab[] = {
8716 { "black", 0, 0 },
8717 { "blue", 1, 0 },
8718 { "brown", 6, 0 },
8719 { "cyan", 3, 0 },
8720 { "darkgray", 8, 0 },
8721 { "dgray", 8, CM_INV },
8722 { "green", 2, 0 },
8723 { "lblue", 9, CM_INV },
8724 { "lcyan", 11, CM_INV },
8725 { "lgreen", 10, CM_INV },
8726 { "lgray", 7, CM_INV },
8727 { "lightblue", 9, 0 },
8728 { "lightcyan", 11, 0 },
8729 { "lightgreen", 10, 0 },
8730 { "lightgray", 7, 0 },
8731 { "lightmagenta", 13, 0 },
8732 { "lightred", 12, 0 },
8733 { "lmagenta", 13, CM_INV },
8734 { "lred", 12, CM_INV },
8735 { "magenta", 5, 0 },
8736 { "red", 4, 0 },
8737 { "white", 15, 0 },
8738 { "yellow", 14, 0 },
8739
8740 };
8741 int nrgb = (sizeof(rgbtab) / sizeof(struct keytab));
8742
8743 VOID
8744 shogui() {
8745 extern gui_dialog;
8746 extern HWND getHwndKUI();
8747 unsigned char cmdsav = colorcmd;
8748 int i, red, green, blue, lines=0;
8749 char * s;
8750
8751
8752 printf("GUI paramters:\n");
8753 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
8754 printf(" Dialogs: %s\n",showoff(gui_dialog));
8755 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
8756 printf(" Position: %d,%d\n",get_gui_window_pos_x(),
8757 get_gui_window_pos_y());
8758 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
8759 printf(" Resolution: %d x %d\n",GetSystemMetrics(SM_CXSCREEN),
8760 GetSystemMetrics(SM_CYSCREEN));
8761 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
8762 printf(" Run-mode: %s\n",IsIconic(getHwndKUI()) ? "minimized" :
8763 IsZoomed(getHwndKUI()) ? "maximized" : "restored");
8764 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
8765 switch ( get_gui_resize_mode() ) {
8766 case GUIWR_NON:
8767 s = "none";
8768 break;
8769 case GUIWR_FON:
8770 s = "scales font";
8771 break;
8772 case GUIWR_DIM:
8773 s= "changes dimensions";
8774 break;
8775 }
8776 printf(" Resize-mode: %s\n",s);
8777 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
8778 printf("\n");
8779 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
8780
8781 printf("RGB Color Table:\n");
8782 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
8783 printf(" Color Red Green Blue\n");
8784 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
8785 printf(" ------------------------------------------\n");
8786 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
8787 for (i = 0; i < nrgb; i++) {
8788 if (!rgbtab[i].flgs) {
8789 blue = (RGBTable[rgbtab[i].kwval] & 0x00FF0000)>>16;
8790 green = (RGBTable[rgbtab[i].kwval] & 0x0000FF00)>>8;
8791 red = (RGBTable[rgbtab[i].kwval] & 0x000000FF);
8792 printf(" %-18s %3d %3d %3d ",rgbtab[i].kwd,red,green,blue);
8793 colorcmd = rgbtab[i].kwval << 4;
8794 printf("********");
8795 colorcmd = cmdsav;
8796 printf("\n");
8797 if (++lines > cmd_rows - 3) {
8798 if (!askmore())
8799 return;
8800 else
8801 lines = 0;
8802 }
8803 }
8804 }
8805 printf("\n");
8806 }
8807
8808 int
8809 setrgb() {
8810 int cx, red = 0, blue = 0, green = 0, z, x;
8811
8812 if ((cx = cmkey(rgbtab,nrgb,"","",xxstring)) < 0)
8813 return(cx);
8814 if ((z = cmnum("Red value, 0-255","",10,&red,xxstring)) < 0)
8815 return(z);
8816 if ((z = cmnum("Green value, 0-255","",10,&green,xxstring)) < 0)
8817 return(z);
8818 if ((z = cmnum("Blue value, 0-255","",10,&blue,xxstring)) < 0)
8819 return(z);
8820 if ((x = cmcfm()) < 0) return(x);
8821 if (cx > 15 || red > 255 || blue > 255 || green > 255)
8822 return(-2);
8823 RGBTable[cx] = (unsigned)(((unsigned)blue << 16) |
8824 (unsigned)((unsigned)green << 8) |
8825 (unsigned)red);
8826 return(success = 1);
8827 }
8828
8829 /*
8830 Set GUI window position: XY coordinates of upper left corner,
8831 expressed as pixel numbers in the current screen resolution.
8832 (0,0) means put ourselves in the upper left corner.
8833 Can we check for out of bounds?
8834 */
8835
8836 int
8837 setguiwin() {
8838 int cx, x, y, z;
8839 if ((cx = cmkey(guiwtab,nguiwtab,"","",xxstring)) < 0)
8840 return(cx);
8841 switch (cx) {
8842 case GUIW_POS:
8843 if ((z = cmnum("X coordinate (pixel number)","",10,&x,xxstring)) < 0)
8844 return(z);
8845 if ((z = cmnum("Y coordinate (pixel number)","",10,&y,xxstring)) < 0)
8846 return(z);
8847 if ((z = cmcfm()) < 0)
8848 return(z);
8849 if (x < 0 || y < 0) {
8850 printf("?Coordinates must be 0 or greater\n");
8851 return(-9);
8852 }
8853 gui_position(x,y);
8854 return(success = 1);
8855 case GUIW_RES:
8856 if ((x = cmkey(guiwrtab,nguiwrtab,"","",xxstring)) < 0)
8857 return(x);
8858 if ((z = cmcfm()) < 0)
8859 return(z);
8860 gui_resize_mode(x);
8861 return(success = 1);
8862 case GUIW_RUN:
8863 if ((x = cmkey(guiwntab,nguiwntab,"","",xxstring)) < 0)
8864 return(x);
8865 if ((z = cmcfm()) < 0)
8866 return(z);
8867 gui_win_run_mode(x);
8868 return(success = 1);
8869 default:
8870 return(-2);
8871 }
8872 }
8873
8874 int
8875 setguifont() { /* Assumes that CKFLOAT is defined! */
8876
8877 extern struct keytab * term_font;
8878 extern struct keytab * _term_font;
8879 extern int tt_font, tt_font_size, ntermfont;
8880 int x, y, z;
8881 char *s;
8882
8883 if (ntermfont == 0)
8884 BuildFontTable(&term_font, &_term_font, &ntermfont);
8885 if (!(term_font && _term_font && ntermfont > 0)) {
8886 printf("?Internal error: Failure to enumerate fonts\n");
8887 return(-9);
8888 }
8889 if ((x = cmkey(_term_font,ntermfont,"","",xxstring)) < 0)
8890 return(x);
8891 if ((z = cmfld("Height of font in points","12",&s,xxstring)) < 0)
8892 return(z);
8893 if (isfloat(s,0) < 1) { /* (sets floatval) */
8894 printf("?Integer or floating-point number required\n");
8895 return(-9);
8896 }
8897 if (floatval < 0.5) {
8898 printf("?Positive number required\n");
8899 return(-9);
8900 }
8901 if ((z = cmcfm()) < 0)
8902 return(z);
8903 tt_font = x; /* Font index */
8904 tt_font_size = (int)(floatval * 2); /* Font size in half points */
8905 KuiSetProperty(KUI_TERM_FONT, (long)tt_font, (long)tt_font_size);
8906 return(success = 1);
8907 }
8908
8909 VOID
8910 setguidialog(x) int x;
8911 {
8912 extern int gui_dialog;
8913 gui_dialog = x;
8914 KuiSetProperty(KUI_GUI_DIALOGS, (long)x, 0L);
8915 }
8916
8917 VOID
8918 setguimenubar(x) int x;
8919 {
8920 KuiSetProperty(KUI_GUI_MENUBAR, (long)x, 0L);
8921 }
8922
8923 VOID
8924 setguitoolbar(x) int x;
8925 {
8926 KuiSetProperty(KUI_GUI_TOOLBAR, (long)x, 0L);
8927 }
8928
8929 VOID
8930 setguiclose(x) int x;
8931 {
8932 KuiSetProperty(KUI_GUI_CLOSE, (long)x, 0L);
8933 }
8934
8935 int
8936 setgui() {
8937 int cx, x, rc;
8938 if ((cx = cmkey(guitab,nguitab,"","",xxstring)) < 0)
8939 return(cx);
8940 switch (cx) {
8941 case GUI_DIA:
8942 rc = seton(&x);
8943 if (rc >= 0)
8944 setguidialog(x);
8945 return(rc);
8946 case GUI_FON:
8947 return(setguifont());
8948 case GUI_RGB:
8949 return(setrgb());
8950 case GUI_WIN:
8951 return(setguiwin());
8952 case GUI_TLB:
8953 rc = seton(&x);
8954 if (rc >= 0)
8955 setguitoolbar(x);
8956 return(rc);
8957 case GUI_MNB:
8958 rc = seton(&x);
8959 if (rc >= 0)
8960 setguimenubar(x);
8961 return(rc);
8962 case GUI_CLS:
8963 rc = seton(&x);
8964 if (rc >= 0)
8965 setguiclose(x);
8966 return(rc);
8967 default:
8968 return(-2);
8969 }
8970 }
8971 #endif /* KUI */
8972
8973 VOID
8974 setexitwarn(x) int x;
8975 {
8976 xitwarn = x;
8977 #ifdef KUI
8978 KuiSetProperty(KUI_EXIT_WARNING, (long)x, 0L);
8979 #endif /* KUI */
8980 }
8981
8982 #ifndef NOLOCAL
8983 VOID
8984 setdebses(x) int x; {
8985 #ifdef OS2
8986 if ((debses != 0) && (x == 0)) /* It was on and we turned it off? */
8987 os2debugoff(); /* Fix OS/2 coloration */
8988 #endif /* OS2 */
8989 debses = x;
8990 #ifdef KUI
8991 KuiSetProperty(KUI_TERM_DEBUG,x,0);
8992 #endif /* KUI */
8993 }
8994 #endif /* NOLOCAL */
8995
8996 /* D O P R M -- Set a parameter. */
8997 /*
8998 Returns:
8999 -2: illegal input
9000 -1: reparse needed
9001 0: success
9002 */
9003 int
9004 doprm(xx,rmsflg) int xx, rmsflg; {
9005 int i = 0, x = 0, y = 0, z = 0;
9006 long zz = 0L;
9007 char *s = NULL, *p = NULL;
9008 #ifdef OS2
9009 char portbuf[64];
9010 long portspeed = 0L;
9011 int portparity = 0;
9012 int portflow = 0;
9013 #endif /* OS2 */
9014
9015 #ifndef NOSETKEY
9016 #ifdef OS2
9017 if (xx == XYMSK)
9018 return(setmsk());
9019 #endif /* OS2 */
9020 #endif /* NOSETKEY */
9021
9022 if (xx == XYFLAG) { /* SET FLAG */
9023 extern int ooflag;
9024 return(success = seton(&ooflag));
9025 }
9026 if (xx == XYPRTR /* SET PRINTER (or BPRINTER) */
9027 #ifdef BPRINT
9028 || xx == XYBDCP
9029 #endif /* BPRINT */
9030 )
9031 return(setprinter(xx));
9032
9033 switch (xx) {
9034
9035 #ifdef ANYX25 /* SET X25 ... */
9036 case XYX25:
9037 return(setx25());
9038
9039 #ifndef IBMX25
9040 case XYPAD: /* SET PAD ... */
9041 return(setpadp());
9042 #endif /* IBMX25 */
9043 #endif /* ANYX25 */
9044
9045 #ifndef NOXFER
9046 case XYEOL: /* These have all been moved to set send/receive... */
9047 case XYLEN: /* Let the user know what to do. */
9048 case XYMARK:
9049 case XYNPAD:
9050 case XYPADC:
9051 case XYTIMO:
9052 printf("...Use SET SEND or SET RECEIVE instead.\n");
9053 printf("Type HELP SET SEND or HELP SET RECEIVE for more info.\n");
9054 return(success = 0);
9055
9056 case XYATTR: /* File Attribute packets */
9057 return(setat(rmsflg));
9058
9059 case XYIFD: /* Incomplete file disposition */
9060 if ((y = cmkey(ifdatab,3,"","auto",xxstring)) < 0) return(y);
9061 if ((x = cmcfm()) < 0) return(x);
9062 if (rmsflg) {
9063 sstate = setgen('S',
9064 "310",
9065 y == 0 ? "0" : (y == 1 ? "1" : "2"),
9066 ""
9067 );
9068 return((int) sstate);
9069 } else {
9070 keep = y;
9071 return(success = 1);
9072 }
9073 #endif /* NOXFER */
9074
9075 case XYMATCH: /* [ REMOTE ] SET MATCH... */
9076 #ifndef NOXFER
9077 if ((z = cmkey(matchtab,nmatchtab,"","",xxstring)) < 0)
9078 return(z);
9079 if (rmsflg) {
9080 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
9081 if ((x = cmcfm()) < 0) return(x);
9082 switch (z) {
9083 case MCH_DOTF:
9084 return(sstate = setgen('S',"330", y == 0 ? "0" : "1", ""));
9085 case MCH_FIFO:
9086 return(sstate = setgen('S',"331", y == 0 ? "0" : "1", ""));
9087 default:
9088 return(-2);
9089 }
9090 }
9091 #endif /* NOXFER */
9092 switch (z) {
9093 case MCH_FIFO:
9094 return(success = seton(&matchfifo));
9095 case MCH_DOTF:
9096 x = seton(&matchdot);
9097 if (x < 0) return(x);
9098 dir_dots = -1;
9099 return(success = x);
9100 default:
9101 return(-2);
9102 }
9103
9104 #ifndef NOSPL
9105 case XYINPU: /* SET INPUT */
9106 return(setinp());
9107 #endif /* NOSPL */
9108
9109 #ifdef NETCONN
9110 case XYNET: { /* SET NETWORK */
9111
9112 struct FDB k1, k2;
9113
9114 cmfdbi(&k1,_CMKEY,"","","",nnetkey, 0, xxstring, netkey, &k2);
9115 cmfdbi(&k2,_CMKEY,"","","",nnets, 0, xxstring, netcmd, NULL);
9116
9117 #ifdef OS2 /* Hide network-type keywords for networks not installed */
9118 for (z = 0; z < nnets; z++) {
9119 if (netcmd[z].kwval == NET_TCPB && tcp_avail == 0)
9120 netcmd[z].flgs = CM_INV;
9121 #ifdef SSHBUILTIN
9122 if (netcmd[z].kwval == NET_SSH &&
9123 !ck_ssleay_is_installed())
9124 netcmd[z].flgs = CM_INV;
9125 #endif /* SSHBUILTIN */
9126 #ifdef DECNET
9127 else if (netcmd[z].kwval == NET_DEC && dnet_avail == 0)
9128 netcmd[z].flgs = CM_INV;
9129 #endif /* DECNET */
9130 #ifdef CK_NETBIOS
9131 else if (netcmd[z].kwval == NET_BIOS && netbiosAvail == 0)
9132 netcmd[z].flgs = CM_INV;
9133 #endif /* CK_NETBIOS */
9134 #ifdef SUPERLAT
9135 else if (netcmd[z].kwval == NET_SLAT && slat_avail == 0)
9136 netcmd[z].flgs = CM_INV;
9137 #endif /* SUPERLAT */
9138 }
9139 if (tcp_avail) /* Default network type */
9140 ckstrncpy(tmpbuf,"tcp/ip",TMPBUFSIZ);
9141 #ifdef SSHBUILTIN
9142 else if ( ck_ssleay_is_installed() )
9143 ckstrncpy(tmpbuf,"ssh",TMPBUFSIZ);
9144 #endif /* SSHBUILTIN */
9145 #ifdef DECNET
9146 else if (dnet_avail)
9147 ckstrncpy(tmpbuf,"decnet",TMPBUFSIZ);
9148 #endif /* DECNET */
9149 #ifdef SUPERLAT
9150 else if (slat_avail)
9151 ckstrncpy(tmpbuf,"superlat",TMPBUFSIZ);
9152 #endif /* SUPERLAT */
9153 #ifdef CK_NETBIOS
9154 else if (netbiosAvail)
9155 ckstrncpy(tmpbuf,"netbios",TMPBUFSIZ);
9156 #endif /* CK_NETBIOS */
9157 else ckstrncpy(tmpbuf,"named-pipe",TMPBUFSIZ);
9158 #else /* OS2 */
9159 #ifdef TCPSOCKET
9160 ckstrncpy(tmpbuf,"tcp/ip",TMPBUFSIZ);
9161 #else
9162 #ifdef ANYX25
9163 ckstrncpy(tmpbuf,"x.25",TMPBUFSIZ);
9164 #else
9165 ckstrncpy(tmpbuf,"",TMPBUFSIZ);
9166 #endif /* ANYX25 */
9167 #endif /* TCPSOCKET */
9168 #endif /* OS2 */
9169
9170 x = cmfdb(&k1);
9171 if (x < 0) { /* Error */
9172 if (x == -2 || x == -9)
9173 printf("?No keywords match: \"%s\"\n",atmbuf);
9174 return(x);
9175 }
9176 z = cmresult.nresult; /* Keyword value */
9177 if (cmresult.fdbaddr == &k1) { /* Which table? */
9178 #ifndef NOSPL
9179 #ifndef NODIAL
9180 if (z == XYNET_D)
9181 return(parsdir(1));
9182 #endif /* NODIAL */
9183 #endif /* NOSPL */
9184 if ((z = cmkey(netcmd,nnets,"",tmpbuf,xxstring)) < 0)
9185 return(z);
9186 }
9187
9188 #ifdef NETCMD
9189 if (z == NET_CMD && nopush) {
9190 printf("\n?Sorry, access to external commands is disabled\n");
9191 return(-9);
9192 }
9193 #endif /* NETCMD */
9194
9195 #ifndef NOPUSH
9196 #ifdef NETPTY
9197 if (z == NET_PTY && nopush) {
9198 printf("\n?Sorry, access to external commands is disabled\n");
9199 return(-9);
9200 }
9201 #endif /* NETPTY */
9202 #endif /* NOPUSH */
9203
9204 #ifdef OS2
9205 if (z == NET_TCPB && tcp_avail == 0) {
9206 printf(
9207 "\n?Sorry, either TCP/IP is not available on this system or\n\
9208 necessary DLLs did not load. Use SHOW NETWORK to check network status.\n");
9209 return(-9);
9210 #ifdef SSHBUILTIN
9211 } else if (z == NET_SSH && !ck_ssleay_is_installed()) {
9212 printf("\n?Sorry, SSH is not available on this system.\n") ;
9213 return(-9);
9214 #endif /* SSHBUILTIN */
9215 #ifdef CK_NETBIOS
9216 } else if (z == NET_BIOS && netbiosAvail == 0) {
9217 printf("\n?Sorry, NETBIOS is not available on this system.\n") ;
9218 return(-9);
9219 #endif /* CK_NETBIOS */
9220 #ifdef DECNET
9221 } else if (z == NET_DEC && dnet_avail == 0) {
9222 printf("\n?Sorry, DECnet is not available on this system.\n") ;
9223 return(-9);
9224 #endif /* DECNET */
9225 #ifdef SUPERLAT
9226 } else if (z == NET_SLAT && slat_avail == 0) {
9227 printf("\n?Sorry, SuperLAT is not available on this system.\n") ;
9228 return(-9);
9229 #endif /* SUPERLAT */
9230 }
9231 #endif /* OS2 */
9232
9233 #ifdef NPIPEORBIOS
9234 if (z == NET_PIPE || /* Named pipe -- also get pipename */
9235 z == NET_BIOS) { /* NETBIOS -- also get local name */
9236 char *defnam;
9237 #ifdef CK_NETBIOS
9238 char tmpnbnam[NETBIOS_NAME_LEN+1];
9239 #endif /* CK_NETBIOS */
9240 /* Construct default name */
9241 if (z == NET_PIPE) { /* Named pipe */
9242 defnam = "kermit"; /* Default name is always "kermit" */
9243 }
9244 #ifdef CK_NETBIOS
9245 else { /* NetBIOS */
9246 if (NetBiosName[0] != SP) { /* If there is already a name, */
9247 char *p = NULL;
9248 int n; /* use it as the default. */
9249 ckstrncpy(tmpnbnam,NetBiosName,NETBIOS_NAME_LEN+1);
9250 /* convert trailing spaces to NULs */
9251 p = &tmpnbnam[NETBIOS_NAME_LEN-1];
9252 while (*p == SP) {
9253 *p = NUL;
9254 p--;
9255 }
9256 defnam = tmpnbnam;
9257 } else if (*myhost) /* Otherwise use this PC's host name */
9258 defnam = (char *) myhost;
9259 else /* Otherwise use "kermit" */
9260 defnam = "kermit";
9261 }
9262 #endif /* CK_NETBIOS */
9263 if ((y = cmtxt((z == NET_PIPE) ? "name of named-pipe" :
9264 "local NETBIOS name",
9265 defnam, &s, xxstring)) < 0)
9266 return(y);
9267 #ifdef NPIPE
9268 pipename[0] = NUL;
9269 #endif /* NPIPE */
9270 if ((y = (int) strlen(s)) < 1) {
9271 printf("?You must also specify a %s name\n",
9272 (z == NET_PIPE) ? "pipe" : "local NETBIOS" );
9273 return(-9);
9274 }
9275 #ifdef CK_NETBIOS
9276 if (z == NET_BIOS) {
9277 if (!netbiosAvail) {
9278 printf("?NETBIOS is not available on this system.\n") ;
9279 return(-9);
9280 }
9281 if (y - NETBIOS_NAME_LEN > 0) {
9282 printf("?NETBIOS name too long, %ld maximum\n",
9283 NETBIOS_NAME_LEN);
9284 return(-9);
9285 } else if ( !strcmp(s,tmpnbnam) ) {
9286 nettype = z; /* Returning to old connection... */
9287 return(success = 1); /* Done */
9288 } else if (strcmp(" ",NetBiosName)) {
9289 printf("?NETBIOS name already assigned to \"%s\"\n",
9290 NetBiosName);
9291 return(-9);
9292 } else {
9293 NCB ncb;
9294 APIRET rc;
9295 ckstrncpy(NetBiosName,s,16);
9296 for (x = y; x < NETBIOS_NAME_LEN; x++)
9297 NetBiosName[x] = SP;
9298 NetBiosName[NETBIOS_NAME_LEN] = NUL;
9299 printf("Checking \"%s\" as a unique NetBIOS name...\n",
9300 NetBiosName);
9301 rc = NCBAddName( NetbeuiAPI,
9302 &ncb, NetBiosAdapter, NetBiosName );
9303 if (rc) {
9304 printf(
9305 "?Sorry, \"%s\" is already in use by another NetBIOS node.\n",
9306 NetBiosName);
9307 for (x = 0; x < NETBIOS_NAME_LEN; x++)
9308 NetBiosName[x] = SP;
9309 return(-9);
9310 }
9311 }
9312 }
9313 #endif /* CK_NETBIOS */
9314 #ifdef NPIPE
9315 if (z == NET_PIPE)
9316 ckstrncpy(pipename,s,PIPENAML);
9317 #endif /* NPIPE */
9318 } else
9319 #endif /* NPIPEORBIOS */
9320 #ifdef DECNET
9321 if (z == NET_DEC) {
9322 /* Determine if we are using LAT or CTERM */
9323 if ((y = cmkey(dnettab,
9324 ndnet,"DECNET protocol","lat",xxstring)) < 0)
9325 return(y);
9326 if ((x = cmcfm()) < 0) return(x);
9327 ttnproto = y;
9328 } else
9329 #endif /* DECNET */
9330 #ifdef NETDLL
9331 if (z == NET_DLL) {
9332 /* Find out which DLL they are using */
9333 char dllname[256]="";
9334 char * p=NULL;
9335 if ((x = cmifi("Dynamic load library",
9336 "",&p,&y,xxstring)) < 0) {
9337 if (x == -3) {
9338 printf("?Name of DLL required\n");
9339 return(-9);
9340 }
9341 return(x);
9342 }
9343 ckstrncpy(dllname,p,256);
9344 if ((x = cmcfm()) < 0) return(x);
9345
9346 if (netdll_load(dllname) < 0) /* Try to load the dll */
9347 return(success = 0);
9348 else {
9349 nettype = z;
9350 return(success = 1);
9351 }
9352 } else
9353 #endif /* NETDLL */
9354 if ((x = cmcfm()) < 0) return(x);
9355 nettype = z;
9356 if (
9357 #ifdef DECNET
9358 (nettype != NET_DEC) &&
9359 #endif /* DECNET */
9360 #ifdef NPIPE
9361 (nettype != NET_PIPE) &&
9362 #endif /* NPIPE */
9363 #ifdef CK_NETBIOS
9364 (nettype != NET_BIOS) &&
9365 #endif /* CK_NETBIOS */
9366 #ifdef NETFILE
9367 (nettype != NET_FILE) &&
9368 #endif /* NETFILE */
9369 #ifdef NETCMD
9370 (nettype != NET_CMD) &&
9371 #endif /* NETCMD */
9372 #ifdef NETPTY
9373 (nettype != NET_PTY) &&
9374 #endif /* NETPTY */
9375 #ifdef NETDLL
9376 (nettype != NET_DLL) &&
9377 #endif /* NETDLL */
9378 #ifdef SUPERLAT
9379 (nettype != NET_SLAT) &&
9380 #endif /* SUPERLAT */
9381 (nettype != NET_SX25) &&
9382 (nettype != NET_VX25) &&
9383 #ifdef IBMX25
9384 (nettype != NET_IX25) &&
9385 #endif /* IBMX25 */
9386 #ifdef SSHBUILTIN
9387 (nettype != NET_SSH) &&
9388 #endif /* SSHBUILTIN */
9389 (nettype != NET_TCPB)) {
9390 printf("?Network type not supported\n");
9391 return(success = 0);
9392 } else {
9393 return(success = 1);
9394 }
9395 }
9396
9397 #ifndef NOTCPOPTS
9398 #ifdef TCPSOCKET
9399 case XYTCP: {
9400 extern int ttyfd;
9401
9402 if ((z = cmkey(tcpopt,ntcpopt,"TCP option","nodelay",xxstring)) < 0)
9403 return(z);
9404
9405 switch (z) {
9406 #ifndef NOHTTP
9407 case XYTCP_HTTP_PROXY: {
9408 struct FDB sw, tx;
9409 int n, x;
9410 char ubuf[LOGINLEN+1], pbuf[LOGINLEN+1], abuf[256];
9411 ubuf[0] = pbuf[0] = abuf[0] = 0;
9412
9413 cmfdbi(&sw, /* First FDB - switches */
9414 _CMKEY, /* fcode */
9415 "HTTP proxy server host[:port] or switch",
9416 "", /* default */
9417 "", /* addtl string data */
9418 nuserpass, /* addtl numeric data 1: tbl size */
9419 4, /* addtl numeric data 2: 4 = cmswi */
9420 xxstring, /* Processing function */
9421 userpass, /* Keyword table */
9422 &tx /* Pointer to next FDB */
9423 );
9424 cmfdbi(&tx,
9425 _CMTXT, /* fcode */
9426 "HTTP proxy server host[:port]",
9427 "", /* default */
9428 "", /* addtl string data */
9429 0, /* addtl numeric data 1 */
9430 0, /* addtl numeric data 2 */
9431 xxstring,
9432 NULL,
9433 NULL
9434 );
9435 while (1) {
9436 if ((x = cmfdb(&sw)) < 0) {
9437 if (x == -3) {
9438 x = -9;
9439 printf("?Hostname required\n");
9440 }
9441 return(x);
9442 }
9443 if (cmresult.fcode != _CMKEY)
9444 break;
9445 n = cmresult.nresult;
9446 switch (n) {
9447 case UPW_USER:
9448 case UPW_PASS:
9449 case UPW_AGENT:
9450 if ((x = cmfld((n == UPW_USER) ?
9451 "Username" :
9452 ((n == UPW_PASS) ? "Password" : "Agent"),
9453 "", &s, xxstring)) < 0) {
9454 if (x != -3)
9455 return(x);
9456 }
9457 ckstrncpy((n == UPW_USER) ? ubuf :
9458 ((n == UPW_PASS) ? pbuf : abuf), s,
9459 (n == UPW_AGENT) ? 256 : (LOGINLEN+1));
9460 }
9461 }
9462 if (cmresult.fcode != _CMTXT)
9463 return(-2);
9464 s = cmresult.sresult;
9465 if (s) if (!*s) s = NULL;
9466
9467 #ifdef IKSDCONF
9468 if (iksdcf)
9469 return(success = 0);
9470 #endif /* IKSDCONF */
9471 makestr(&tcp_http_proxy_user,ubuf[0]?ubuf:NULL);
9472 makestr(&tcp_http_proxy_pwd,pbuf[0]?pbuf:NULL);
9473 makestr(&tcp_http_proxy_agent,abuf[0]?abuf:NULL);
9474 makestr(&tcp_http_proxy,s);
9475 memset(pbuf,0,sizeof(pbuf));
9476 return(success = 1);
9477 }
9478 #endif /* NOHTTP */
9479 /*
9480 It would have been easy to combine XYTCP_SOCKS_SVR with the previous
9481 one except for the #ifdefs...
9482 */
9483 #ifdef NT
9484 #ifdef CK_SOCKS
9485 case XYTCP_SOCKS_SVR: {
9486 char ubuf[LOGINLEN+1], pbuf[LOGINLEN+1];
9487 char * p = getenv("SOCKS_SERVER");
9488 struct FDB sw, tx;
9489 int n, x;
9490
9491 if (!p) p = "";
9492
9493 cmfdbi(&sw, /* First FDB - switches */
9494 _CMKEY, /* fcode */
9495 "SOCKS server host[:port] or switch",
9496 "", /* default */
9497 "", /* addtl string data */
9498 nuserpass, /* addtl numeric data 1: tbl size */
9499 4, /* addtl numeric data 2: 4 = cmswi */
9500 xxstring, /* Processing function */
9501 userpass, /* Keyword table */
9502 &tx /* Pointer to next FDB */
9503 );
9504 cmfdbi(&tx,
9505 _CMTXT, /* fcode */
9506 "SOCKS server host[:port]",
9507 p, /* default */
9508 "", /* addtl string data */
9509 0, /* addtl numeric data 1 */
9510 0, /* addtl numeric data 2 */
9511 xxstring,
9512 NULL,
9513 NULL
9514 );
9515 while (1) {
9516 if ((x = cmfdb(&sw)) < 0) {
9517 if (x == -3) {
9518 x = -9;
9519 printf("?Hostname required\n");
9520 }
9521 return(x);
9522 }
9523 if (cmresult.fcode != _CMKEY)
9524 break;
9525 n = cmresult.nresult;
9526 switch (n) {
9527 case UPW_USER:
9528 case UPW_PASS:
9529 if ((x = cmfld((n == UPW_USER) ? "Username" : "Password",
9530 "", &s, xxstring)) < 0) {
9531 if (x != -3)
9532 return(x);
9533 }
9534 ckstrncpy((n == UPW_USER) ? ubuf : pbuf, s, LOGINLEN+1);
9535 }
9536 }
9537 if (cmresult.fcode != _CMTXT)
9538 return(-2);
9539 s = cmresult.sresult;
9540 if (s) if (!*s) s = NULL;
9541
9542 #ifdef IKSDCONF
9543 if (iksdcf)
9544 return(success = 0);
9545 #endif /* IKSDCONF */
9546 makestr(&tcp_socks_user,ubuf);
9547 memset(pbuf,0,sizeof(pbuf));
9548 makestr(&tcp_socks_svr,s);
9549 return(success = 1);
9550 }
9551
9552 #ifdef CK_SOCKS_NS
9553 case XYTCP_SOCKS_NS: {
9554 char * p = getenv("SOCKS_NS");
9555 if (!p) p = "";
9556 if ((y = cmtxt("hostname or IP of SOCKS Name Server",p,
9557 &s,xxstring)) < 0)
9558 return(y);
9559 #ifdef IKSDCONF
9560 if (iksdcf) return(success = 0);
9561 #endif /* IKSDCONF */
9562 if (tcp_socks_ns) {
9563 free(tcp_socks_ns); /* Free any previous storage */
9564 tcp_socks_ns = NULL;
9565 }
9566 if (s == NULL || *s == NUL) { /* If none given */
9567 tcp_socks_ns = NULL; /* remove the override string */
9568 return(success = 1);
9569 } else if ((tcp_socks_ns = malloc(strlen(s)+1))) {
9570 strcpy(tcp_socks_ns,s);
9571 return(success = 1);
9572 } else
9573 return(success = 0);
9574 }
9575 #endif /* CK_SOCKS_NS */
9576 #endif /* CK_SOCKS */
9577 #endif /* NT */
9578 case XYTCP_ADDRESS:
9579 if ((y = cmtxt("preferred IP Address for TCP connections","",
9580 &s,xxstring)) < 0)
9581 return(y);
9582 #ifdef IKSDCONF
9583 if (iksdcf) return(success = 0);
9584 #endif /* IKSDCONF */
9585 if (tcp_address) {
9586 free(tcp_address); /* Free any previous storage */
9587 tcp_address = NULL;
9588 }
9589 if (s == NULL || *s == NUL) { /* If none given */
9590 tcp_address = NULL; /* remove the override string */
9591 return(success = 1);
9592 } else if ((tcp_address = malloc(strlen(s)+1))) {
9593 strcpy(tcp_address,s);
9594 return(success = 1);
9595 } else
9596 return(success = 0);
9597 #ifdef SO_KEEPALIVE
9598 case XYTCP_KEEPALIVE:
9599 if ((z = cmkey(onoff,2,"","on",xxstring)) < 0) return(z);
9600 if ((y = cmcfm()) < 0) return(y);
9601 #ifdef IKSDCONF
9602 if (iksdcf) return(success = 0);
9603 #endif /* IKSDCONF */
9604 #ifdef SSHBUILTIN
9605 if (network && nettype == NET_SSH && ssh_sock != -1)
9606 success = keepalive(ssh_sock,z);
9607 else
9608 #endif /* SSHBUILTIN */
9609 success = keepalive(ttyfd,z);
9610 return(success);
9611 #endif /* SO_KEEPALIVE */
9612 #ifdef SO_DONTROUTE
9613 case XYTCP_DONTROUTE:
9614 if ((z = cmkey(onoff,2,"","off",xxstring)) < 0) return(z);
9615 if ((y = cmcfm()) < 0) return(y);
9616 #ifdef IKSDCONF
9617 if (iksdcf) return(success = 0);
9618 #endif /* IKSDCONF */
9619 #ifdef SSHBUILTIN
9620 if (network && nettype == NET_SSH && ssh_sock != -1)
9621 success = dontroute(ssh_sock,z);
9622 else
9623 #endif /* SSHBUILTIN */
9624 success = dontroute(ttyfd,z);
9625 return(success);
9626 #endif /* SO_DONTROUTE */
9627 #ifdef TCP_NODELAY
9628 case XYTCP_NODELAY:
9629 if ((z = cmkey(onoff,2,"","off",xxstring)) < 0) return(z);
9630 if ((y = cmcfm()) < 0) return(y);
9631 #ifdef IKSDCONF
9632 if (iksdcf) return(success = 0);
9633 #endif /* IKSDCONF */
9634 #ifdef SSHBUILTIN
9635 if (network && nettype == NET_SSH && ssh_sock != -1)
9636 success = no_delay(ssh_sock,z);
9637 else
9638 #endif /* SSHBUILTIN */
9639 success = no_delay(ttyfd,z);
9640 return(success);
9641 case XYTCP_NAGLE: /* The inverse of NODELAY */
9642 if ((z = cmkey(onoff,2,"","on",xxstring)) < 0) return(z);
9643 if ((y = cmcfm()) < 0) return(y);
9644 #ifdef IKSDCONF
9645 if (iksdcf) return(success = 0);
9646 #endif /* IKSDCONF */
9647 #ifdef SSHBUILTIN
9648 if (network && nettype == NET_SSH && ssh_sock != -1)
9649 success = no_delay(ssh_sock,z);
9650 else
9651 #endif /* SSHBUILTIN */
9652 success = no_delay(ttyfd,!z);
9653 return(success);
9654 #endif /* TCP_NODELAY */
9655 #ifdef SO_LINGER
9656 case XYTCP_LINGER:
9657 if ((z = cmkey(onoff,2,"","on",xxstring)) < 0)
9658 return(z);
9659 if (z) { /* if on, we need a timeout value */
9660 if ((x = cmnum("Linger timeout in 10th of a millisecond",
9661 "0",10,&y,xxstring)) < 0)
9662 return(x);
9663 } else
9664 y = 0;
9665 if ((x = cmcfm()) < 0)
9666 return(x);
9667 #ifdef IKSDCONF
9668 if (iksdcf) return(success = 0);
9669 #endif /* IKSDCONF */
9670 #ifdef SSHBUILTIN
9671 if (network && nettype == NET_SSH && ssh_sock != -1)
9672 success = ck_linger(ssh_sock,z,y);
9673 else
9674 #endif /* SSHBUILTIN */
9675 success = ck_linger(ttyfd,z,y);
9676 return(success);
9677 #endif /* SO_LINGER */
9678 #ifdef SO_SNDBUF
9679 case XYTCP_SENDBUF:
9680 x = cmnum("Send buffer size, bytes","8192",10,&z,xxstring);
9681 if (x < 0) return(x);
9682 if ((x = cmcfm()) < 0) return(x);
9683 #ifdef IKSDCONF
9684 if (iksdcf) return(success = 0);
9685 #endif /* IKSDCONF */
9686 #ifdef SSHBUILTIN
9687 if (network && nettype == NET_SSH && ssh_sock != -1)
9688 success = sendbuf(ssh_sock,z);
9689 else
9690 #endif /* SSHBUILTIN */
9691 success = sendbuf(ttyfd,z);
9692 return(success);
9693 #endif /* SO_SNDBUF */
9694 #ifdef SO_RCVBUF
9695 case XYTCP_RECVBUF:
9696 x = cmnum("Receive buffer size, bytes","8192",10,&z,xxstring);
9697 if (x < 0) return(x);
9698 if ((x = cmcfm()) < 0) return(x);
9699 #ifdef IKSDCONF
9700 if (iksdcf) return(success = 0);
9701 #endif /* IKSDCONF */
9702
9703 /* Note: The following is not 16-bit safe */
9704
9705 #ifndef QNX16
9706 if (x > 52248) {
9707 printf("?Warning: receive buffers larger than 52248 bytes\n");
9708 printf(" may not be understood by all hosts. Performance\n");
9709 printf(" may suffer.\n");
9710 return(-9);
9711 }
9712 #endif /* QNX16 */
9713 #ifdef SSHBUILTIN
9714 if (network && nettype == NET_SSH && ssh_sock != -1)
9715 success = recvbuf(ssh_sock,z);
9716 else
9717 #endif /* SSHBUILTIN */
9718 success = recvbuf(ttyfd,z);
9719 return(success);
9720 #endif /* SO_RCVBUF */
9721
9722 #ifdef VMS
9723 #ifdef DEC_TCPIP
9724 case XYTCP_UCX: { /* UCX 2.0 port swabbing bug */
9725 extern int ucx_port_bug;
9726 return(success = seton(&ucx_port_bug));
9727 }
9728 #endif /* DEC_TCPIP */
9729 #endif /* VMS */
9730
9731 case XYTCP_RDNS: {
9732 extern int tcp_rdns;
9733 return(success = setonaut(&tcp_rdns));
9734 }
9735
9736 #ifdef CK_DNS_SRV
9737 case XYTCP_DNS_SRV: {
9738 extern int tcp_dns_srv;
9739 return(success = seton(&tcp_dns_srv));
9740 }
9741 #endif /* CK_DNS_SRV */
9742
9743 default:
9744 return(0);
9745 }
9746 }
9747 #endif /* TCPSOCKET */
9748 #endif /* NOTCPOPTS */
9749 #endif /* NETCONN */
9750 }
9751
9752 switch (xx) {
9753
9754 #ifndef NOLOCAL
9755 #ifdef NETCONN
9756 case XYHOST: { /* SET HOST */
9757 z = ttnproto; /* Save protocol in case of failure */
9758 #ifdef DECNET
9759 if (nettype != NET_DEC)
9760 #endif /* DECNET */
9761 ttnproto = NP_NONE;
9762 if ((y = setlin(XYHOST,1,0)) <= 0) { /* Sets success to 1 */
9763 debug(F101,"SET HOST fail mdmtyp","",mdmtyp);
9764 ttnproto = z; /* Failed, restore protocol */
9765 success = 0;
9766 }
9767 didsetlin++;
9768 debug(F101,"SET HOST OK mdmtyp","",mdmtyp);
9769 debug(F101,"SET HOST reliable","",reliable);
9770 return(y);
9771 }
9772 #endif /* NETCONN */
9773
9774 case XYLINE: /* SET LINE (= SET PORT) */
9775 debug(F101,"setlin flow 1","",flow);
9776 x = setlin(xx,1,0);
9777 if (x > -1) didsetlin++;
9778 debug(F101,"SET LINE setlin","",x);
9779 debug(F101,"SET LINE flow","",flow);
9780 debug(F101,"SET LINE local","",local);
9781 debug(F101,"SET LINE reliable","",reliable);
9782 return(x);
9783 #endif /* NOLOCAL */
9784
9785 #ifndef NOSETKEY
9786 case XYKEY: /* SET KEY */
9787 return(dosetkey());
9788 #endif /* NOSETKEY */
9789
9790 #ifndef NOCSETS
9791 case XYLANG: /* Language */
9792 if ((y = cmkey(lngtab,nlng,"","none",xxstring)) < 0)
9793 return(y);
9794 if ((x = cmcfm()) < 0) return(x);
9795
9796 /* Look up language and get associated character sets */
9797 for (i = 0; (i < nlangs) && (langs[i].id != y); i++) ;
9798 if (i >= nlangs) {
9799 printf("?internal error, sorry\n");
9800 return(success = 0);
9801 } /* */
9802 language = i; /* All good, set the language, */
9803 return(success = 1);
9804 #endif /* NOCSETS */
9805
9806 #ifndef MAC
9807 case XYBACK: /* BACKGROUND */
9808 if ((z = cmkey(onoff,2,"","",xxstring)) < 0) return(z);
9809 if ((y = cmcfm()) < 0) return(y);
9810 #ifdef COMMENT
9811 bgset = z; /* 0 = off (foreground) */
9812 #ifdef VMS /* 1 = on (background) */
9813 if (batch && bgset == 0) /* To enable echoing of commands */
9814 ckxech = 1; /* in VMS batch logs */
9815 #endif /* VMS */
9816 #else /* COMMENT */
9817 if (z) { /* 1 = Background */
9818 bgset = 1;
9819 backgrd = 1;
9820 #ifdef VMS
9821 batch = 1;
9822 #endif /* VMS */
9823 } else { /* 0 = Foreground */
9824 bgset = 0;
9825 backgrd = 0;
9826 #ifdef VMS
9827 batch = 0;
9828 #endif /* VMS */
9829 }
9830 #endif /* COMMENT */
9831 success = 1;
9832 bgchk();
9833 return(success);
9834 #endif /* MAC */
9835
9836 case XYQUIE: { /* QUIET */
9837 #ifdef DCMDBUF
9838 extern int * xquiet;
9839 #else
9840 extern int xquiet[];
9841 #endif /* DCMDBUF */
9842 x = seton(&quiet);
9843 if (x < 0) return(x);
9844 xquiet[cmdlvl] = quiet;
9845 return(success = x);
9846 }
9847
9848 #ifndef NOXFER
9849 case XYBUF: { /* BUFFERS */
9850 #ifdef DYNAMIC
9851 int sb, rb;
9852 if ((y = cmnum("Send buffer size","",10,&sb,xxstring)) < 0) {
9853 if (y == -3) printf("?Buffer size required\n");
9854 return(y);
9855 }
9856 if (sb < 0) {
9857 if (*atmbuf == '-')
9858 printf("?Negative numbers can't be used here\n");
9859 else printf("?Integer overflow, use a smaller number please\n");
9860 return(-9);
9861 } else if (sb < 80) {
9862 printf("?Too small\n");
9863 return(-9);
9864 }
9865 if ((y=cmnum("Receive buffer size",ckitoa(sb),10,&rb,xxstring)) < 0)
9866 return(y);
9867 if (rb < 0) {
9868 if (*atmbuf == '-')
9869 printf("?Negative numbers can't be used here\n");
9870 else printf("?Integer overflow, use a smaller number please\n");
9871 return(-9);
9872 } else if (rb < 80) {
9873 printf("?Too small\n");
9874 return(-9);
9875 }
9876 if ((y = cmcfm()) < 0) return(y);
9877 if ((y = inibufs(sb,rb)) < 0) return(y);
9878 y = adjpkl(urpsiz,wslotr,bigrbsiz); /* Maybe adjust packet sizes */
9879 if (y != urpsiz) urpsiz = y;
9880 y = adjpkl(spsiz,wslotr,bigsbsiz);
9881 if (y != spsiz) spsiz = spmax = spsizr = y;
9882 return(success = 1);
9883 #else
9884 printf("?Sorry, not available\n");
9885 return(success = 0);
9886 #endif /* DYNAMIC */
9887 }
9888
9889 case XYCHKT: /* BLOCK-CHECK */
9890 if ((x = cmkey(chktab,nchkt,"","3",xxstring)) < 0) return(x);
9891 if ((y = cmcfm()) < 0) return(y);
9892 if (x == 5) {
9893 bctf = 1;
9894 #ifdef COMMENT
9895 printf("?5 - Not implemented yet\n");
9896 return(success = 0);
9897 #endif /* COMMENT */
9898 }
9899 bctr = x; /* Set local too even if REMOTE SET */
9900
9901 if (rmsflg) {
9902 if (x == 4) {
9903 tmpbuf[0] = 'B';
9904 tmpbuf[1] = '\0';
9905 } else
9906 ckstrncpy(tmpbuf,ckitoa(x),TMPBUFSIZ);
9907 sstate = setgen('S', "400", tmpbuf, "");
9908 return((int) sstate);
9909 } else {
9910 return(success = 1);
9911 }
9912 #endif /* NOXFER */
9913
9914 #ifndef NOLOCAL
9915 #ifndef MAC /* The Mac has no RS-232 */
9916 case XYCARR: /* CARRIER-WATCH */
9917 return(setdcd());
9918 #endif /* MAC */
9919 #endif /* NOLOCAL */
9920 }
9921
9922 #ifdef TNCODE
9923 switch (xx) { /* Avoid long switch statements... */
9924 case XYTELOP: {
9925 int c, n; /* Workers */
9926 int getval = 0; /* Whether to get switch value */
9927 int tnserver = 0; /* Client by default */
9928 int opt = -1; /* Telnet Option */
9929 struct FDB sw, op; /* FDBs for each parse function */
9930 #ifdef CK_AUTHENTICATION
9931 extern int sl_topt_a_s_saved;
9932 extern int sl_topt_a_c_saved;
9933 extern int sl_topt_e_s_saved;
9934 extern int sl_topt_e_c_saved;
9935 #endif /* CK_AUTHENTICATION */
9936 #ifdef IKSD
9937 if (inserver) /* Server by default when IKSD */
9938 tnserver = 1;
9939 #endif /* IKSD */
9940
9941 /* Set up chained parse functions... */
9942
9943 cmfdbi(&op, /* First fdb - telopts*/
9944 _CMKEY, /* fcode */
9945 "/client, /server or", /* hlpmsg */
9946 "", /* default */
9947 "", /* addtl string data */
9948 ntnopt, /* addtl numeric data 1 */
9949 0, /* addtl numeric data 2 */
9950 xxstring,
9951 tnopttab,
9952 &sw
9953 );
9954 cmfdbi(&sw, /* Second FDB - command switches */
9955 _CMKEY, /* fcode */
9956 "", /* hlpmsg */
9957 "", /* default */
9958 "", /* addtl string data */
9959 ntnoptsw, /* addtl numeric data 1: tbl size */
9960 4, /* addtl numeric data 2: 4 = cmswi */
9961 xxstring, /* Processing function */
9962 tnoptsw, /* Keyword table */
9963 NULL /* Pointer to next FDB */
9964 );
9965
9966 while (opt < 0) { /* Parse 0 or more switches */
9967 x = cmfdb(&op); /* Parse switch or other thing */
9968 debug(F101,"XYTELOP cmfdb","",x);
9969 if (x < 0) /* Error */
9970 return(x); /* or reparse needed */
9971 if (cmresult.fcode != _CMKEY) /* Break out if not a switch */
9972 break;
9973 c = cmgbrk(); /* Get break character */
9974 getval = (c == ':' || c == '='); /* see how switch ended */
9975 if (getval && !(cmresult.kflags & CM_ARG)) {
9976 printf("?This switch does not take arguments\n");
9977 return(-9);
9978 }
9979 z = cmresult.nresult; /* Numeric result = switch value */
9980 debug(F101,"XYTELOP switch","",z);
9981
9982 switch (z) { /* Process the switch */
9983 case CK_TN_CLIENT:
9984 tnserver = 0;
9985 break;
9986 case CK_TN_SERVER:
9987 tnserver = 1;
9988 break;
9989 case CK_TN_EC:
9990 opt = TELOPT_ECHO;
9991 break;
9992 case CK_TN_TT:
9993 opt = TELOPT_TTYPE;
9994 break;
9995 case CK_TN_BM:
9996 opt = TELOPT_BINARY;
9997 break;
9998 case CK_TN_ENV:
9999 opt = TELOPT_NEWENVIRON;
10000 break;
10001 case CK_TN_LOC:
10002 opt = TELOPT_SNDLOC;
10003 break;
10004 case CK_TN_AU:
10005 opt = TELOPT_AUTHENTICATION;
10006 break;
10007 case CK_TN_FX:
10008 opt = TELOPT_FORWARD_X;
10009 break;
10010 case CK_TN_ENC:
10011 opt = TELOPT_ENCRYPTION;
10012 break;
10013 case CK_TN_IKS:
10014 opt = TELOPT_KERMIT;
10015 break;
10016 case CK_TN_TLS:
10017 opt = TELOPT_START_TLS;
10018 break;
10019 case CK_TN_XD:
10020 opt = TELOPT_XDISPLOC;
10021 break;
10022 case CK_TN_NAWS:
10023 opt = TELOPT_NAWS;
10024 break;
10025 case CK_TN_SGA:
10026 opt = TELOPT_SGA;
10027 break;
10028 case CK_TN_PHR:
10029 opt = TELOPT_PRAGMA_HEARTBEAT;
10030 break;
10031 case CK_TN_PSP:
10032 opt = TELOPT_SSPI_LOGON;
10033 break;
10034 case CK_TN_PLG:
10035 opt = TELOPT_PRAGMA_LOGON;
10036 break;
10037 case CK_TN_SAK:
10038 opt = TELOPT_IBM_SAK;
10039 break;
10040 case CK_TN_CPC:
10041 opt = TELOPT_COMPORT;
10042 break;
10043 case CK_TN_LOG:
10044 opt = TELOPT_LOGOUT;
10045 break;
10046 case CK_TN_FLW:
10047 opt = TELOPT_LFLOW;
10048 break;
10049 default:
10050 printf("?Unexpected value - %d\n",z);
10051 return(-9);
10052 }
10053 #ifdef COMMENT
10054 if (cmresult.fdbaddr == &op)
10055 break;
10056 #endif /* COMMENT */
10057 }
10058 switch (opt) {
10059 case TELOPT_ECHO: /* Options only the Server WILL */
10060 case TELOPT_FORWARD_X:
10061 case TELOPT_SEND_URL:
10062 case TELOPT_IBM_SAK:
10063 case TELOPT_LOGOUT:
10064 if ((x = cmkey(tnnegtab,
10065 ntnnegtab,
10066 "desired server state",
10067 TELOPT_MODE(tnserver?TELOPT_DEF_S_ME_MODE(opt):TELOPT_DEF_C_U_MODE(opt)),
10068 xxstring)
10069 ) < 0)
10070 return(x);
10071 if ((z = cmcfm()) < 0)
10072 return(z);
10073 if (tnserver) {
10074 TELOPT_DEF_S_ME_MODE(opt) = x;
10075 TELOPT_ME_MODE(opt) = x;
10076 } else {
10077 TELOPT_DEF_C_U_MODE(opt) = x;
10078 TELOPT_U_MODE(opt) = x;
10079 }
10080 break;
10081
10082 case TELOPT_TTYPE: /* Options only the Client WILL */
10083 case TELOPT_NEWENVIRON:
10084 case TELOPT_SNDLOC:
10085 case TELOPT_AUTHENTICATION:
10086 case TELOPT_START_TLS:
10087 case TELOPT_XDISPLOC:
10088 case TELOPT_NAWS:
10089 case TELOPT_LFLOW:
10090 case TELOPT_COMPORT:
10091 if ((x = cmkey(tnnegtab,
10092 ntnnegtab,
10093 "desired client state",
10094 TELOPT_MODE(!tnserver?TELOPT_DEF_S_U_MODE(opt):TELOPT_DEF_C_ME_MODE(opt)),
10095 xxstring)
10096 ) < 0)
10097 return(x);
10098 if ((z = cmcfm()) < 0)
10099 return(z);
10100 if (tnserver) {
10101 TELOPT_DEF_S_U_MODE(opt) = x;
10102 TELOPT_U_MODE(opt) = x;
10103 #ifdef CK_AUTHENTICATION
10104 if (opt == TELOPT_AUTHENTICATION)
10105 sl_topt_a_s_saved = 0;
10106 #endif /* CK_AUTHENTICATION */
10107 } else {
10108 TELOPT_DEF_C_ME_MODE(opt) = x;
10109 TELOPT_ME_MODE(opt) = x;
10110 #ifdef CK_AUTHENTICATION
10111 if (opt == TELOPT_AUTHENTICATION)
10112 sl_topt_a_c_saved = 0;
10113 #endif /* CK_AUTHENTICATION */
10114 }
10115 break;
10116
10117 default:
10118 if ((x = cmkey(tnnegtab,
10119 ntnnegtab,
10120 tnserver ?
10121 "desired server state" :
10122 "desired client state",
10123 TELOPT_MODE(tnserver?TELOPT_DEF_S_ME_MODE(opt):TELOPT_DEF_C_ME_MODE(opt)),
10124 xxstring
10125 )
10126 ) < 0)
10127 return(x);
10128 if ((y = cmkey(tnnegtab,
10129 ntnnegtab,
10130 !tnserver ? "desired server state" :
10131 "desired client state",
10132 TELOPT_MODE(!tnserver?TELOPT_DEF_S_U_MODE(opt):TELOPT_DEF_C_U_MODE(opt)),
10133 xxstring
10134 )
10135 ) < 0)
10136 return(y);
10137 if ((z = cmcfm()) < 0)
10138 return(z);
10139 if (tnserver) {
10140 TELOPT_DEF_S_ME_MODE(opt) = x;
10141 TELOPT_ME_MODE(opt) = x;
10142 TELOPT_DEF_S_U_MODE(opt) = y;
10143 TELOPT_U_MODE(opt) = y;
10144 #ifdef CK_ENCRYPTION
10145 if (opt == TELOPT_ENCRYPTION)
10146 sl_topt_e_s_saved = 0;
10147 #endif /* CK_ENCRYPTION */
10148 } else {
10149 TELOPT_DEF_C_ME_MODE(opt) = x;
10150 TELOPT_ME_MODE(opt) = x;
10151 TELOPT_DEF_C_U_MODE(opt) = y;
10152 TELOPT_U_MODE(opt) = y;
10153 #ifdef CK_ENCRYPTION
10154 if (opt == TELOPT_ENCRYPTION)
10155 sl_topt_e_c_saved = 0;
10156 #endif /* CK_ENCRYPTION */
10157 }
10158 }
10159 return(success = 1);
10160 }
10161
10162 case XYTEL: /* TELNET */
10163 if ((z = cmkey(tntab,ntn,"parameter for TELNET negotiations", "",
10164 xxstring)) < 0)
10165 return(z);
10166 switch (z) {
10167 case CK_TN_EC: /* ECHO */
10168 if ((x = cmkey(rltab,nrlt,
10169 "initial TELNET echoing state",
10170 "local",xxstring)) < 0)
10171 return(x);
10172 if ((y = cmcfm()) < 0) return(y);
10173 tn_duplex = x;
10174 return(success = 1);
10175
10176 case CK_TN_RE: /* REMOTE-ECHO */
10177 return(success = seton(&tn_rem_echo));
10178
10179 case CK_TN_DB: /* DEBUG */
10180 return(success = seton(&tn_deb));
10181
10182 case CK_TN_TT: /* TERMINAL TYPE */
10183 if ((y = cmtxt("terminal type for TELNET connections","",
10184 &s,xxstring)) < 0)
10185 return(y);
10186 if (tn_term) {
10187 free(tn_term); /* Free any previous storage */
10188 tn_term = NULL;
10189 }
10190 if (s == NULL || *s == NUL) { /* If none given */
10191 tn_term = NULL; /* remove the override string */
10192 return(success = 1);
10193 } else if ((tn_term = malloc(strlen(s)+1))) {
10194 strcpy(tn_term,s);
10195 return(success = 1);
10196 } else return(success = 0);
10197
10198 #ifdef CK_FORWARD_X
10199 case CK_TN_FX: /* FORWARD-X */
10200 if ((x=cmkey(tnfwdxtab,ntnfwdx,"","xauthority-file",xxstring)) < 0)
10201 return(x);
10202 switch (x) {
10203 case 0: { /* Xauthority-File */
10204 x = cmifi("Full path of .Xauthority file","",&s,&y,xxstring);
10205 if (x < 0 && x != -3)
10206 return(x);
10207 makestr(&tn_fwdx_xauthority,s);
10208 return(success = 1);
10209 }
10210 case 1: { /* No-Encryption */
10211 extern int fwdx_no_encrypt;
10212 return(success = seton(&fwdx_no_encrypt));
10213 }
10214 }
10215 return(success = 0);
10216 #endif /* CK_FORWARD_X */
10217
10218 case CK_TN_NL: /* TELNET NEWLINE-MODE */
10219 if ((x = cmkey(tn_nlmtab,ntn_nlm,"","nvt",xxstring)) < 0)
10220 return(x);
10221 if (x == TN_NL_BIN) {
10222 if ((x = cmkey(tnlmtab,ntnlm,"","raw",xxstring)) < 0)
10223 return(x);
10224 if ((y = cmcfm()) < 0)
10225 return(y);
10226 tn_b_nlm = x;
10227 return(success = 1);
10228 } else if (x == TN_NL_NVT) {
10229 if ((x = cmkey(tnlmtab,ntnlm,"","on",xxstring)) < 0)
10230 return(x);
10231 if ((y = cmcfm()) < 0)
10232 return(y);
10233 tn_nlm = x;
10234 return(success = 1);
10235 } else {
10236 if ((y = cmcfm()) < 0)
10237 return(y);
10238 tn_nlm = x;
10239 return(success = 1);
10240 }
10241
10242 case CK_TN_XF: /* BINARY-TRANSFER-MODE */
10243 if ((z = cmkey(onoff,2,"","on",xxstring)) < 0) return(z);
10244 if ((y = cmcfm()) < 0) return(y);
10245 tn_b_xfer = z;
10246 return(success = 1);
10247
10248 case CK_TN_NE: /* NO-ENCRYPT-DURING-XFER */
10249 if ((z = cmkey(onoff,2,"","on",xxstring)) < 0) return(z);
10250 if ((y = cmcfm()) < 0) return(y);
10251 #ifdef CK_APC
10252 /* Don't let this be set remotely */
10253 if (apcactive == APC_LOCAL ||
10254 (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH)))
10255 return(success = 0);
10256 #endif /* CK_APC */
10257 tn_no_encrypt_xfer = z;
10258 return(success = 1);
10259
10260 case CK_TN_BM: /* BINARY-MODE */
10261 if ((x = cmkey(tnnegtab,ntnnegtab,"","refused",xxstring)) < 0)
10262 return(x);
10263 if ((y = cmcfm()) < 0)
10264 return(y);
10265 TELOPT_DEF_S_ME_MODE(TELOPT_BINARY) = x;
10266 TELOPT_DEF_S_U_MODE(TELOPT_BINARY) = x;
10267 TELOPT_DEF_C_ME_MODE(TELOPT_BINARY) = x;
10268 TELOPT_DEF_C_U_MODE(TELOPT_BINARY) = x;
10269 return(success = 1);
10270
10271 #ifdef IKS_OPTION
10272 case CK_TN_IKS: /* KERMIT */
10273 if ((x = cmkey(tnnegtab,ntnnegtab,"DO","accept",xxstring)) < 0)
10274 return(x);
10275 if ((y = cmkey(tnnegtab,ntnnegtab,"WILL","accept",xxstring)) < 0)
10276 return(y);
10277 if ((z = cmcfm()) < 0)
10278 return(z);
10279 TELOPT_DEF_S_ME_MODE(TELOPT_KERMIT) = y;
10280 TELOPT_DEF_S_U_MODE(TELOPT_KERMIT) = x;
10281 TELOPT_DEF_C_ME_MODE(TELOPT_KERMIT) = y;
10282 TELOPT_DEF_C_U_MODE(TELOPT_KERMIT) = x;
10283 return(success = 1);
10284 #endif /* IKS_OPTION */
10285
10286 #ifdef CK_SSL
10287 case CK_TN_TLS: /* START_TLS */
10288 if ((x = cmkey(tnnegtab,ntnnegtab,"me","accept",xxstring)) < 0)
10289 return(x);
10290 if ((y = cmkey(tnnegtab,ntnnegtab,"u","accept",xxstring)) < 0)
10291 return(y);
10292 if ((z = cmcfm()) < 0)
10293 return(z);
10294 TELOPT_DEF_S_ME_MODE(TELOPT_START_TLS) = x;
10295 TELOPT_DEF_S_U_MODE(TELOPT_START_TLS) = y;
10296 TELOPT_DEF_C_ME_MODE(TELOPT_START_TLS) = x;
10297 TELOPT_DEF_C_U_MODE(TELOPT_START_TLS) = y;
10298 return(success = 1);
10299 #endif /* CK_SSL */
10300
10301 #ifdef CK_NAWS
10302 case CK_TN_NAWS: /* NAWS */
10303 if ((x = cmkey(tnnegtab,ntnnegtab,"me","accept",xxstring)) < 0)
10304 return(x);
10305 if ((y = cmkey(tnnegtab,ntnnegtab,"u","accept",xxstring)) < 0)
10306 return(y);
10307 if ((z = cmcfm()) < 0)
10308 return(z);
10309 TELOPT_DEF_S_ME_MODE(TELOPT_NAWS) = x;
10310 TELOPT_DEF_S_U_MODE(TELOPT_NAWS) = y;
10311 TELOPT_DEF_C_ME_MODE(TELOPT_NAWS) = x;
10312 TELOPT_DEF_C_U_MODE(TELOPT_NAWS) = y;
10313 return(success = 1);
10314 #endif /* CK_NAWS */
10315
10316 #ifdef CK_AUTHENTICATION
10317 case CK_TN_AU: /* AUTHENTICATION */
10318 if ((x = cmkey(tnauthtab,ntnauth,"","",xxstring)) < 0)
10319 return(x);
10320 if (x == TN_AU_FWD) {
10321 extern int forward_flag;
10322 return(success = seton(&forward_flag));
10323 } else if (x == TN_AU_TYP) {
10324 extern int auth_type_user[];
10325 extern int sl_auth_type_user[];
10326 extern int sl_auth_saved;
10327 int i, j, atypes[AUTHTYPLSTSZ];
10328
10329 for (i = 0; i < AUTHTYPLSTSZ; i++) {
10330 if ((y = cmkey(autyptab,nautyp,"",
10331 i == 0 ? "automatic" : "" ,
10332 xxstring)) < 0) {
10333 if (y == -3)
10334 break;
10335 return(y);
10336 }
10337 if (i > 0 && (y == AUTHTYPE_AUTO || y == AUTHTYPE_NULL)) {
10338 printf(
10339 "\r\n?Choice may only be used in first position.\r\n");
10340 return(-9);
10341 }
10342 for (j = 0; j < i; j++) {
10343 if (atypes[j] == y) {
10344 printf("\r\n?Choice has already been used.\r\n");
10345 return(-9);
10346 }
10347 }
10348 atypes[i] = y;
10349 if (y == AUTHTYPE_NULL || y == AUTHTYPE_AUTO) {
10350 i++;
10351 break;
10352 }
10353 }
10354 if (i < AUTHTYPLSTSZ)
10355 atypes[i] = AUTHTYPE_NULL;
10356 if ((z = cmcfm()) < 0)
10357 return(z);
10358 sl_auth_saved = 0;
10359 for (i = 0; i < AUTHTYPLSTSZ; i++) {
10360 auth_type_user[i] = atypes[i];
10361 sl_auth_type_user[i] = 0;
10362 }
10363 } else if (x == TN_AU_HOW) {
10364 if ((y = cmkey(auhowtab,nauhow,"","any",xxstring)) < 0)
10365 return(y);
10366 if ((z = cmcfm()) < 0)
10367 return(z);
10368 tn_auth_how = y;
10369 } else if (x == TN_AU_ENC) {
10370 if ((y = cmkey(auenctab,nauenc,"","encrypt",xxstring)) < 0)
10371 return(y);
10372 if ((z = cmcfm()) < 0)
10373 return(z);
10374 tn_auth_enc = y;
10375 } else {
10376 if ((y = cmcfm()) < 0)
10377 return(y);
10378 TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = x;
10379 TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = x;
10380 }
10381 return(success = 1);
10382 #endif /* CK_AUTHENTICATION */
10383
10384 #ifdef CK_ENCRYPTION
10385 case CK_TN_ENC: { /* ENCRYPTION */
10386 int c, tmp = -1;
10387 int getval = 0;
10388 static struct keytab * tnetbl = NULL;
10389 static int ntnetbl = 0;
10390
10391 if ((y = cmkey(tnenctab,ntnenc,"","",xxstring)) < 0)
10392 return(y);
10393 switch (y) {
10394 case TN_EN_TYP:
10395 x = ck_get_crypt_table(&tnetbl,&ntnetbl);
10396 debug(F101,"ck_get_crypt_table x","",x);
10397 debug(F101,"ck_get_crypt_table n","",ntnetbl);
10398 if (x < 1 || !tnetbl || ntnetbl < 1) /* Didn't get it */
10399 x = 0;
10400 if (!x) {
10401 printf("?Oops, types not loaded\n");
10402 return(-9);
10403 }
10404 if ((x = cmkey(tnetbl,ntnetbl,"type of encryption",
10405 "automatic",xxstring)) < 0)
10406 return(x);
10407 if ((z = cmcfm()) < 0)
10408 return(z);
10409 cx_type = x;
10410 sl_cx_type = 0;
10411 break;
10412 case TN_EN_START:
10413 if ((z = cmcfm()) < 0)
10414 return(z);
10415 #ifdef CK_APC
10416 /* Don't let this be set remotely */
10417 if (apcactive == APC_LOCAL ||
10418 apcactive == APC_REMOTE && !(apcstatus & APC_UNCH))
10419 return(success = 0);
10420 #endif /* CK_APC */
10421 ck_tn_enc_start();
10422 break;
10423 case TN_EN_STOP:
10424 if ((z = cmcfm()) < 0)
10425 return(z);
10426 #ifdef CK_APC
10427 /* Don't let this be set remotely */
10428 if (apcactive == APC_LOCAL ||
10429 apcactive == APC_REMOTE && !(apcstatus & APC_UNCH))
10430 return(success = 0);
10431 #endif /* CK_APC */
10432 ck_tn_enc_stop();
10433 break;
10434 default:
10435 if ((z = cmcfm()) < 0)
10436 return(z);
10437 TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = y;
10438 TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = y;
10439 TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = y;
10440 TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = y;
10441 }
10442 return(success = 1);
10443 }
10444 #endif /* CK_ENCRYPTION */
10445
10446 case CK_TN_BUG: /* BUG */
10447 if ((x = cmkey(tnbugtab,4,"",
10448 "binary-me-means-u-too",xxstring)) < 0)
10449 return(x);
10450 if ((z = cmkey(onoff,2,"","off",xxstring)) < 0) return(z);
10451 if ((y = cmcfm()) < 0) return(y);
10452 switch (x) {
10453 case 0:
10454 tn_b_meu = z;
10455 break;
10456 case 1:
10457 tn_b_ume = z;
10458 break;
10459 case 2:
10460 tn_infinite = z;
10461 break;
10462 case 3:
10463 tn_sb_bug = z;
10464 break;
10465 case 4:
10466 tn_auth_krb5_des_bug = z;
10467 break;
10468 }
10469 return(success = 1);
10470
10471 #ifdef CK_ENVIRONMENT
10472 case CK_TN_XD: /* XDISPLOC */
10473 if ((x = cmkey(tnnegtab,ntnnegtab,"me","accept",xxstring)) < 0)
10474 return(x);
10475 if ((y = cmkey(tnnegtab,ntnnegtab,"u","accept",xxstring)) < 0)
10476 return(y);
10477 if ((z = cmcfm()) < 0)
10478 return(z);
10479 TELOPT_DEF_S_ME_MODE(TELOPT_XDISPLOC) = x;
10480 TELOPT_DEF_S_U_MODE(TELOPT_XDISPLOC) = y;
10481 TELOPT_DEF_C_ME_MODE(TELOPT_XDISPLOC) = x;
10482 TELOPT_DEF_C_U_MODE(TELOPT_XDISPLOC) = y;
10483 return(success = 1);
10484
10485 case CK_TN_ENV: {
10486 char * msg = "value of telnet environment variable";
10487 extern int tn_env_flg;
10488 extern char tn_env_acct[], tn_env_disp[], tn_env_job[],
10489 tn_env_prnt[], tn_env_sys[];
10490 extern char * tn_loc;
10491 if ((x = cmkey(tnenvtab,ntnenv,"","",xxstring)) < 0)
10492 return(x);
10493 if (x == TN_ENV_UVAR) { /* User variables */
10494 char * uvar=NULL;
10495 char * uval=NULL;
10496 char * env;
10497 extern char * tn_env_uservar[8][2];
10498
10499 /* Get the user variable name */
10500 if ((x = cmfld("Name of Environment Variable","",&s,
10501 xxstring)) < 0)
10502 return(x);
10503 makestr(&uvar,s);
10504
10505 env = getenv(uvar);
10506 if (!env) env = "";
10507
10508 if ((x = cmtxt("Value of Environment Variable",env,
10509 &s,xxstring)) < 0)
10510 return(x);
10511 if (*s)
10512 makestr(&uval,s);
10513
10514 /* Now that we have the variable and perhaps a value */
10515 /* there are three possibilities: (1) new variable */
10516 /* and associated value; (2) variable already exists */
10517 /* but we have a new value; (3) variable already */
10518 /* exists but no new value therefore the user wants */
10519 /* to clear variable. */
10520
10521 /* Try to find an existing variable */
10522 for (x = 0; x < 8; x++) {
10523 if (!ckstrcmp(tn_env_uservar[x][0],uvar,-1,0)) {
10524 if (uval) {
10525 free(tn_env_uservar[x][1]);
10526 tn_env_uservar[x][1] = uval;
10527 free(uvar);
10528 return(success = 1);
10529 } else {
10530 free(tn_env_uservar[x][0]);
10531 tn_env_uservar[x][0] = NULL;
10532 free(tn_env_uservar[x][1]);
10533 tn_env_uservar[x][1] = NULL;
10534 free(uvar);
10535 return(success = 1);
10536 }
10537 }
10538 }
10539
10540 /* Couldn't find one; look for empty location to insert */
10541 for (x = 0; x < 8; x++) {
10542 if (!tn_env_uservar[x][0]) {
10543 tn_env_uservar[x][0] = uvar;
10544 tn_env_uservar[x][1] = uval;
10545 return(success = 1);
10546 }
10547 }
10548 printf("?Sorry, no space for variable.\n");
10549 return(success = 0);
10550 }
10551 if (x == TN_ENV_OFF || x == TN_ENV_ON) {
10552 if ((y = cmcfm()) < 0) return(y);
10553 #ifdef IKSD
10554 if (inserver) {
10555 printf("?Sorry, command disabled.\r\n");
10556 return(success = 0);
10557 }
10558 #endif /* IKSD */
10559 tn_env_flg = x == TN_ENV_OFF ? 0 : 1;
10560 return(success = 1);
10561 }
10562
10563 /* Not ON/OFF - Get the value */
10564 z = cmdgquo();
10565 cmdsquo(0);
10566 if ((y = cmtxt(msg, "", &s, xxstring)) < 0) {
10567 cmdsquo(z);
10568 return(y);
10569 }
10570 cmdsquo(z);
10571 #ifdef IKSD
10572 if (inserver)
10573 return(success = 0);
10574 #endif /* IKSD */
10575 if ((int)strlen(s) > 63) {
10576 printf("Sorry, too long\n");
10577 return(-9);
10578 }
10579 switch (x) {
10580 case TN_ENV_USR:
10581 ckstrncpy(uidbuf,s,UIDBUFLEN);
10582 sl_uid_saved = 0;
10583 break;
10584 case TN_ENV_ACCT:
10585 ckstrncpy(tn_env_acct,s,64);
10586 break;
10587 case TN_ENV_DISP:
10588 ckstrncpy(tn_env_disp,s,64);
10589 break;
10590 case TN_ENV_JOB:
10591 ckstrncpy(tn_env_job,s,64);
10592 break;
10593 case TN_ENV_PRNT:
10594 ckstrncpy(tn_env_prnt,s,64);
10595 break;
10596 case TN_ENV_SYS:
10597 ckstrncpy(tn_env_sys,s,64);
10598 break;
10599 case TN_ENV_LOC:
10600 if (!*s) s = NULL;
10601 makestr(&tn_loc,s);
10602 break;
10603 case TN_ENV_UVAR:
10604 printf("\n?Not yet implemented\n");
10605 break;
10606 }
10607 return(success = 1);
10608 }
10609 #endif /* CK_ENVIRONMENT */
10610
10611 #ifdef CK_SNDLOC
10612 case CK_TN_LOC: { /* LOCATION */
10613 extern char * tn_loc;
10614 if ((y = cmtxt("Location string","",&s,xxstring)) < 0)
10615 return(y);
10616 if (!*s) s = NULL;
10617 makestr(&tn_loc,s);
10618 return(success = 1);
10619 }
10620 #endif /* CK_SNDLOC */
10621 case CK_TN_SFU: /* Microsoft SFU compatibility */
10622 if ((z = cmkey(onoff,2,"","on",xxstring)) < 0) return(z);
10623 if ((y = cmcfm()) < 0) return(y);
10624 tn_sfu = z;
10625 return(success = 1);
10626 break;
10627
10628 case CK_TN_WAIT: /* WAIT-FOR-NEGOTIATIONS */
10629 if ((z = cmkey(onoff,2,"","on",xxstring)) < 0) return(z);
10630 if ((y = cmcfm()) < 0) return(y);
10631 #ifdef IKSD
10632 if (inserver &&
10633 #ifdef IKSDCONF
10634 iksdcf
10635 #else
10636 1
10637 #endif /* IKSDCONF */
10638 ) {
10639 printf("?Sorry, command disabled.\r\n");
10640 return(success = 0);
10641 }
10642 #endif /* IKSD */
10643 tn_wait_flg = z;
10644 sl_tn_saved = 0;
10645 return(success = 1);
10646
10647 case CK_TN_DL: /* DELAY SUBNEGOTIATIONS */
10648 if ((z = cmkey(onoff,2,"","on",xxstring)) < 0) return(z);
10649 if ((y = cmcfm()) < 0) return(y);
10650 #ifdef IKSD
10651 if (inserver &&
10652 #ifdef IKSDCONF
10653 iksdcf
10654 #else
10655 1
10656 #endif /* IKSDCONF */
10657 ) {
10658 printf("?Sorry, command disabled.\r\n");
10659 return(success = 0);
10660 }
10661 #endif /* IKSD */
10662 tn_delay_sb = z;
10663 return(success = 1);
10664
10665 case CK_TN_PUID: { /* PROMPT-FOR-USERID */
10666 int i,len;
10667 if ((y = cmtxt("Prompt string","",&s,xxstring)) < 0)
10668 return(y);
10669 s = brstrip(s);
10670 /* we must check to make sure there are no % fields */
10671 len = strlen(s);
10672 for (i = 0; i < len; i++) {
10673 if (s[i] == '%') {
10674 if (s[i+1] != '%') {
10675 printf("%% fields are not used in this command.\n");
10676 return(-9);
10677 }
10678 i++;
10679 }
10680 }
10681 makestr(&tn_pr_uid,s);
10682 return(success = 1);
10683 }
10684 default:
10685 return(-2);
10686 }
10687 }
10688 #endif /* TNCODE */
10689
10690 switch (xx) {
10691 #ifndef NOSPL
10692 case XYCOUN: /* SET COUNT */
10693 x = cmnum("Positive number","0",10,&z,xxstring);
10694 if (x < 0) return(x);
10695 if ((x = cmcfm()) < 0) return(x);
10696 if (z < 0) {
10697 printf("?A positive number, please\n");
10698 return(0);
10699 }
10700 debug(F101,"XYCOUN: z","",z);
10701 return(success = setnum(&count[cmdlvl],z,0,10000));
10702 #endif /* NOSPL */
10703
10704 #ifndef NOSPL
10705 case XYCASE:
10706 return(success = seton(&inpcas[cmdlvl]));
10707 #endif /* NOSPL */
10708
10709 case XYCMD: /* COMMAND ... */
10710 if ((y = cmkey(scmdtab,nbytt,"","",xxstring)) < 0)
10711 return(y);
10712 switch (y) {
10713 case SCMD_CBR:
10714 if ((y = cmcfm()) < 0)
10715 return(y);
10716 concb((char)escape);
10717 return(success = 1);
10718
10719 case SCMD_BSZ:
10720 if ((y = cmnum("bytesize for command characters, 7 or 8","7",10,&x,
10721 xxstring)) < 0)
10722 return(y);
10723 if (x != 7 && x != 8) {
10724 printf("\n?The choices are 7 and 8\n");
10725 return(success = 0);
10726 }
10727 if ((y = cmcfm()) < 0) return(y);
10728 if (x == 7) cmdmsk = 0177;
10729 else if (x == 8) cmdmsk = 0377;
10730 return(success = 1);
10731 #ifdef CK_RECALL
10732 case SCMD_RCL:
10733 if ((y = cmnum("maximum number of commands in recall buffer","10",
10734 10,&x,xxstring)) < 0)
10735 return(y);
10736 if ((y = cmcfm()) < 0) return(y);
10737 return(success = cmrini(x));
10738 #endif /* CK_RECALL */
10739 #ifdef CK_RECALL
10740 case SCMD_RTR:
10741 return(success = seton(&cm_retry));
10742 #endif /* CK_RECALL */
10743 case SCMD_MOR: /* More-prompting */
10744 success = seton(&xaskmore);
10745 if (success)
10746 saveask = xaskmore;
10747 return(success);
10748 case SCMD_QUO:
10749 if ((x = seton(&y)) < 0) return(x);
10750 cmdsquo(y); /* Do it the right way */
10751 cmd_quoting = y; /* Also keep a global copy */
10752 /* Set string-processing function */
10753 #ifdef datageneral
10754 xxstring = y ? zzstring : (xx_strp) NULL;
10755 #else
10756 #ifdef CK_ANSIC
10757 xxstring = y ? zzstring : (xx_strp) NULL;
10758 #else
10759 xxstring = y ? zzstring : (xx_strp) NULL;
10760 #endif /* CK_ANSIC */
10761 #endif /* datageneral */
10762 return(success = 1);
10763
10764 #ifdef OS2
10765 #ifndef NOLOCAL
10766 case SCMD_COL: { /* Command-screen colors */
10767 int fg, bg;
10768 fg = cmkey(ttyclrtab, nclrs,
10769 "foreground color and then background color",
10770 "white",
10771 xxstring);
10772 if (fg < 0)
10773 return(fg);
10774 if ((bg = cmkey(ttyclrtab,nclrs,
10775 "background color","black",xxstring)) < 0)
10776 return(bg);
10777 if ((y = cmcfm()) < 0)
10778 return(y);
10779 colorcmd = fg | bg << 4;
10780 return(success = 1);
10781 }
10782 case SCMD_SCR: /* Command Scrollback size */
10783 if ((y = cmnum("COMMAND scrollback buffer size, lines","512",10,&x,
10784 xxstring)) < 0)
10785 return(y);
10786 /* The max number of lines is the RAM */
10787 /* we can actually dedicate to a */
10788 /* scrollback buffer given the maximum */
10789 /* process memory space of 512MB */
10790 if (x < 256 || x > 2000000L) {
10791 printf("\n?The size must be between 256 and 2,000,000.\n");
10792 return(success = 0);
10793 }
10794 if ((y = cmcfm()) < 0) return(y);
10795 tt_scrsize[VCMD] = x;
10796 VscrnInit( VCMD );
10797 return(success = 1);
10798
10799 case SCMD_WID: {
10800 if ((y = cmnum("Number of columns in display window",
10801 "80",10,&x,xxstring)) < 0)
10802 return(y);
10803 if ((y = cmcfm()) < 0) return(y);
10804
10805 os2_setcmdwidth(x);
10806 return(success = 1);
10807 }
10808 case SCMD_HIG:
10809 if ((y = cmnum("Number of rows in display window",
10810 "24",10,&x,xxstring)) < 0)
10811 return(y);
10812 if ((y = cmcfm()) < 0) return(y);
10813 os2_setcmdheight(x);
10814 return(success = 1);
10815
10816 case SCMD_STA: {
10817 extern int marginbot;
10818 if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
10819 if ((x = cmcfm()) < 0) return(x);
10820 if (y != tt_status[VCMD]) {
10821 /* Might need to fixup the margins */
10822 tt_status[VCMD] = y;
10823 if (y) {
10824 tt_szchng[VCMD] = 2;
10825 tt_rows[VCMD]--;
10826 cmd_rows--;
10827 VscrnInit(VCMD); /* Height set here */
10828 printf("\n");
10829 } else {
10830 tt_szchng[VCMD] = 1;
10831 tt_rows[VCMD]++;
10832 cmd_rows++;
10833 VscrnInit(VCMD); /* Height set here */
10834 }
10835 }
10836 return(success = 1);
10837 }
10838
10839 case SCMD_CUR: {
10840 int row, col;
10841 position * ppos;
10842
10843 ppos = VscrnGetCurPos(VCMD);
10844 #ifdef NT
10845 #define itoa _itoa
10846 #endif /* NT */
10847 itoa(ppos->y+1, tmpbuf, 10);
10848 if ((y = cmnum("row (1-based)",tmpbuf,10,&row,xxstring)) < 0)
10849 return(y);
10850
10851 itoa(ppos->x+1, tmpbuf, 10);
10852 if ((y = cmnum("col (1-based)",tmpbuf,10,&col,xxstring)) < 0)
10853 return(y);
10854 if ((x = cmcfm()) < 0) return(x);
10855
10856 lgotoxy( VCMD, col, row ) ;
10857 VscrnIsDirty( VCMD );
10858 return(success=1);
10859 }
10860 #endif /* NOLOCAL */
10861 #else
10862 case SCMD_WID:
10863 y = cmnum("Command screen width, characters","80",10,&x,xxstring);
10864 return(setnum(&cmd_cols,x,y,1024));
10865
10866 case SCMD_HIG:
10867 y = cmnum("Command screen height, rows","24",10,&x,xxstring);
10868 return(setnum(&cmd_rows,x,y,1024));
10869 #endif /* OS2 */
10870
10871 case SCMD_INT:
10872 return(seton(&cmdint));
10873
10874 #ifdef CK_AUTODL
10875 case SCMD_ADL:
10876 return(seton(&cmdadl));
10877 #endif /* CK_AUTODL */
10878
10879 #ifdef DOUBLEQUOTING
10880 case SCMD_DBQ: {
10881 extern int dblquo;
10882 return(seton(&dblquo));
10883 }
10884 #endif /* DOUBLEQUOTING */
10885
10886 case SCMD_ERR:
10887 y = cmnum("Error message verbosity level, 0-3","1",10,&x,xxstring);
10888 return(setnum(&cmd_err,x,y,3));
10889
10890 case SCMD_VAR:
10891 return(setvareval());
10892
10893 default:
10894 return(-2);
10895 }
10896 }
10897
10898 switch (xx) {
10899
10900 case XYDFLT: /* SET DEFAULT = CD */
10901 return(success = docd(XXCWD));
10902
10903 case XYDEBU: /* SET DEBUG { on, off, session } */
10904 if ((y = cmkey(dbgtab,ndbg,"","",xxstring)) < 0)
10905 return(y);
10906 if (y == DEB_TIM)
10907 #ifdef COMMENT
10908 return(seton(&debtim) < 0 ? x : (success = 1));
10909 #else
10910 /* why this change? */
10911 return(success = seton(&debtim));
10912 #endif /* COMMENT */
10913
10914 #ifdef IKSD
10915 if (inserver && isguest) {
10916 printf("?Sorry, command disabled.\r\n");
10917 return(success = 0);
10918 }
10919 #endif /* IKSD */
10920
10921 switch (y) {
10922 case DEB_LEN:
10923 y = cmnum("Max length for debug log strings","",10,&x,xxstring);
10924 if ((z = setnum(&debxlen,x,y,-1)) < 0)
10925 return(z);
10926 if ((x = cmcfm()) < 0)
10927 return(x);
10928 return(success = 1);
10929
10930 case DEB_OFF:
10931 if ((x = cmcfm()) < 0)
10932 return(x);
10933 #ifndef NOLOCAL
10934 setdebses(0);
10935 #endif /* NOLOCAL */
10936 #ifdef DEBUG
10937 if (deblog) doclslog(LOGD);
10938 #endif /* DEBUG */
10939 return(success = 1);
10940
10941 case DEB_ON:
10942 if ((x = cmcfm()) < 0)
10943 return(x);
10944 #ifdef DEBUG
10945 deblog = debopn("debug.log", 0);
10946 return(success = deblog ? 1 : 0);
10947 #else
10948 printf("?Sorry, debug log feature not enabled\n");
10949 return(success = 0);
10950 #endif /* DEBUG */
10951 case DEB_SES:
10952 if ((x = cmcfm()) < 0)
10953 return(x);
10954 #ifndef NOLOCAL
10955 setdebses(1);
10956 #endif /* NOLOCAL */
10957 return(success = 1);
10958
10959 case DEB_MSG: /* Debug messages 2010/03/12 */
10960 if ((y = cmkey(ooetab,nooetab,"","on",xxstring)) < 0) return(y);
10961 if ((x = cmcfm()) < 0) return(x);
10962 debmsg = y;
10963 return(1);
10964 }
10965 break;
10966
10967 #ifndef NOXFER
10968 case XYDELA: /* SET DELAY */
10969 y = cmnum("Number of seconds before starting to send",
10970 "5",10,&x,xxstring);
10971 if (x < 0) x = 0;
10972 return(success = setnum(&ckdelay,x,y,999));
10973 #endif /* NOXFER */
10974
10975 default:
10976 break;
10977 }
10978
10979 switch (xx) {
10980 #ifdef CK_TAPI
10981 case XYTAPI:
10982 return(settapi());
10983 #endif /* CK_TAPI */
10984 #ifndef NODIAL
10985 case XYDIAL: /* SET MODEM or SET DIAL */
10986 return(setdial(-1));
10987 case XYMODM:
10988 return(setmodem());
10989 #ifdef COMMENT
10990 /* not implemented yet */
10991 case XYANSWER: /* SET ANSWER */
10992 return(setanswer());
10993 #endif /* COMMENT */
10994 #endif /* NODIAL */
10995
10996 #ifndef NOLOCAL
10997 case XYDUPL: /* SET DUPLEX */
10998 if ((y = cmkey(dpxtab,2,"","full",xxstring)) < 0) return(y);
10999 if ((x = cmcfm()) < 0) return(x);
11000 duplex = y;
11001 return(success = 1);
11002
11003 case XYLCLE: /* LOCAL-ECHO (= DUPLEX) */
11004 return(success = seton(&duplex));
11005
11006 case XYESC: /* SET ESCAPE */
11007 return(success = setcc(ckitoa(DFESC),&escape));
11008 #endif /* NOLOCAL */
11009
11010 case XYEXIT: /* SET EXIT */
11011 if ((z = cmkey(xittab,nexit,"","",xxstring)) < 0)
11012 return(z);
11013 switch (z) {
11014 case 0: /* STATUS */
11015 y = cmnum("EXIT status code","",10,&x,xxstring);
11016 return(success = setnum(&xitsta,x,y,-1));
11017 case 1: /* WARNING */
11018 if ((z = cmkey(xitwtab,nexitw,"","",xxstring)) < 0)
11019 return(z);
11020 if ((y = cmcfm()) < 0) return(y);
11021 setexitwarn(z);
11022 return(success = 1);
11023 case 2:
11024 success = seton(&exitonclose);
11025 #ifdef TCPSOCKET
11026 if (success) tn_exit = exitonclose;
11027 #endif /* TCPSOCKET */
11028 return(success);
11029 case 3: {
11030 extern int exithangup;
11031 return((success = seton(&exithangup)));
11032 }
11033 case 4: { /* MESSAGE 2013-03-13 */
11034 if ((z = cmkey(ooetab,nooetab,"","on",xxstring)) < 0)
11035 return(z);
11036 if ((y = cmcfm()) < 0) return(y);
11037 exitmsg = z;
11038 return(success = 1);
11039 }
11040 default:
11041 return(-2);
11042 } /* End of SET EXIT switch() */
11043 default:
11044 break;
11045 }
11046 switch (xx) {
11047
11048 case XYFILE: /* SET FILE */
11049 return(setfil(rmsflg));
11050
11051 case XYFLOW: { /* FLOW-CONTROL */
11052 extern int cxflow[];
11053 struct FDB k1, k2;
11054 int tncomport = 0;
11055 char * m;
11056
11057 #ifdef TN_COMPORT
11058 if (network && istncomport())
11059 tncomport = 1;
11060 #endif /* TN_COMPORT */
11061
11062 if (tncomport) {
11063 m = "Flow control type, one of the following:\n\
11064 dtr/cd dtr/cts keep none rts/cts xon/xoff\n\
11065 or connection type";
11066 } else {
11067 /* All this is because chained FDB's don't give chained help yet */
11068 m =
11069 #ifdef Plan9
11070 #ifdef CK_RTSCTS
11071 "Flow control type, one of the following:\n\
11072 keep none rts/cts\n\
11073 or connection type",
11074 #else
11075 "Flow control type, one of the following:\n\
11076 keep none\n\
11077 or connection type";
11078 #endif /* CK_RTSCTS */
11079 #else
11080 #ifdef CK_RTSCTS
11081 #ifdef CK_DTRCD
11082 #ifdef CK_DTRCTS
11083 "Flow control type, one of the following:\n\
11084 dtr/cd dtr/cts keep none rts/cts xon/xoff\n\
11085 or connection type";
11086 #else /* CK_DTRCTS */
11087 "Flow control type, one of the following:\n\
11088 dtr/cd keep none rts/cts xon/xoff\n\
11089 or connection type";
11090 #endif /* CK_DTRCTS */
11091 #else /* CK_DTRCD */
11092 #ifdef CK_DTRCTS
11093 "Flow control type, one of the following:\n\
11094 dtr/cts keep none rts/cts xon/xoff\n\
11095 or connection type";
11096 #else /* CK_DTRCTS */
11097 "Flow control type, one of the following:\n\
11098 keep none rts/cts xon/xoff\n\
11099 or connection type";
11100 #endif /* CK_DTRCTS */
11101 #endif /* CK_DTRCD */
11102 #else
11103 "Flow control type, one of the following:\n\
11104 keep none xon/xoff\n\
11105 or connection type";
11106 #endif /* CK_RTSCTS */
11107 #endif /* Plan9 */
11108 }
11109 cmfdbi(&k1,_CMKEY,m,"","",ncxtypesw, 4, xxstring, cxtypesw, &k2);
11110 cmfdbi(&k2,
11111 _CMKEY,
11112 "",
11113 "",
11114 "",
11115 #ifdef TN_COMPORT
11116 (tncomport ? ntnflo : nflo),
11117 #else
11118 nflo,
11119 #endif /* TN_COMPORT */
11120 0,
11121 xxstring,
11122 #ifdef TN_COMPORT
11123 (tncomport ? tnflotab : flotab),
11124 #else
11125 flotab,
11126 #endif /* TN_COMPORT */
11127 NULL
11128 );
11129 x = cmfdb(&k1);
11130 if (x < 0) { /* Error */
11131 if (x == -2 || x == -9)
11132 printf("?No keywords or switches match: \"%s\"\n",atmbuf);
11133 return(x);
11134 }
11135 z = cmresult.nresult; /* Keyword value */
11136 if (cmresult.fdbaddr == &k2) { /* Flow-control type keyword table */
11137 if ((x = cmcfm()) < 0) /* Set it immediately */
11138 return(x);
11139 flow = z;
11140 debug(F101,"set flow","",flow);
11141 #ifdef CK_SPEED
11142 if (flow == FLO_XONX) /* Xon/Xoff forces prefixing */
11143 ctlp[XON] = ctlp[XOFF] = ctlp[XON+128] = ctlp[XOFF+128] = 1;
11144 #endif /* CK_SPEED */
11145 autoflow = (flow == FLO_AUTO);
11146 return(success = 1); /* Done */
11147 }
11148 debug(F101,"set flow /blah 1","",z); /* SET FLOW /for-what */
11149 if ((y = cmkey(flotab,nflo,"Flow control type","none",xxstring)) < 0)
11150 return(y);
11151 if ((x = cmcfm()) < 0)
11152 return(x);
11153 debug(F101,"set flow /blah 2","",y);
11154 if (y == FLO_AUTO) {
11155 printf(
11156 "?Sorry, \"automatic\" can not be assigned to a connection type.\n");
11157 return(-9);
11158 } else if (z >= 0 && z <= CXT_MAX)
11159 cxflow[z] = y;
11160 debug(F101,"set flow","",flow);
11161 debug(F101,"set flow autoflow","",autoflow);
11162 return(success = 1);
11163 }
11164
11165 case XYHAND: /* HANDSHAKE */
11166 if ((y = cmkey(hshtab,nhsh,"","none",xxstring)) < 0) return(y);
11167 if (y == 998) {
11168 if ((x = cmnum("ASCII value","",10,&y,xxstring)) < 0)
11169 return(x);
11170 if ((y < 1) || ((y > 31) && (y != 127))) {
11171 printf("?Character must be in ASCII control range\n");
11172 return(-9);
11173 }
11174 }
11175 if ((x = cmcfm()) < 0) return(x);
11176 turn = (y > 0127) ? 0 : 1;
11177 turnch = y;
11178 return(success = 1);
11179
11180 #ifndef NOSPL
11181 case XYMACR: /* SET MACRO */
11182 if ((y = cmkey(smactab,2,"","",xxstring)) < 0) return(y);
11183 switch (y) {
11184 case 0: return(success = seton(&mecho));
11185 case 1: return(success = seton(&merror[cmdlvl]));
11186 default: return(-2);
11187 }
11188 #endif /* NOSPL */
11189
11190 case XYMSGS:
11191 #ifdef VMS
11192 if ((z = cmkey(onoff,2,"","",xxstring)) < 0) return(z);
11193 if ((y = cmcfm()) < 0) return(y);
11194 vms_msgs = z;
11195 printf("Sorry, SET MESSAGES not implemented yet\n");
11196 return(success = 0);
11197 #endif /* VMS */
11198 default:
11199 break;
11200 }
11201
11202 switch (xx) {
11203
11204 case XYPARI: /* PARITY */
11205 if ((y = cmkey(partbl,npar,"","none",xxstring)) < 0)
11206 return(y);
11207
11208 /* If parity not none, then we also want 8th-bit prefixing */
11209
11210 #ifdef HWPARITY
11211 if (y == 'H') { /* Hardware */
11212 if ((x = cmkey(hwpartbl,nhwpar,"","even",xxstring)) < 0)
11213 return(x);
11214 }
11215 #endif /* HWPARITY */
11216
11217 if ((z = cmcfm()) < 0)
11218 return(z);
11219
11220 #ifdef HWPARITY
11221 if (y == 'H') { /* 8 data bits plus hardware parity */
11222 parity = 0;
11223 #ifndef NOXFER
11224 ebqflg = 0;
11225 #endif /* NOXFER */
11226 hwparity = x;
11227 } else { /* 7 data bits + software parity */
11228 hwparity = 0;
11229 #endif /* HWPARITY */
11230 parity = y;
11231 #ifndef NOXFER
11232 ebqflg = (parity) ? 1 : 0;
11233 #endif /* NOXFER */
11234 #ifdef HWPARITY
11235 }
11236 #endif /* HWPARITY */
11237
11238 #ifdef TN_COMPORT
11239 if (network && istncomport())
11240 tnsettings(parity, 0);
11241 #endif /* TN_COMPORT */
11242
11243 return(success = 1);
11244
11245 #ifndef NOFRILLS
11246 case XYPROM: /* SET PROMPT */
11247 /*
11248 Note: xxstring not invoked here. Instead, it is invoked every time the
11249 prompt is issued. This allows the prompt string to contain variables
11250 that can change, like \v(dir), \v(time), etc.
11251 */
11252 ckmakmsg(line, /* Default might have trailing space */
11253 LINBUFSIZ,
11254 "{",
11255 inserver ? ikprompt : ckprompt,
11256 "}",
11257 NULL
11258 );
11259 if ((x = cmtxt("Program's command prompt",line,&s,NULL)) < 0)
11260 return(x);
11261 s = brstrip(s); /* Remove enclosing braces, if any */
11262 cmsetp(s); /* Set the prompt */
11263 return(success = 1);
11264 #endif /* NOFRILLS */
11265
11266 #ifndef NOXFER
11267 case XYRETR: /* RETRY: per-packet retry limit */
11268 y = cmnum("Maximum retries per packet","10",10,&x,xxstring);
11269 if (x < 0) x = 0;
11270 if ((x = setnum(&maxtry,x,y,999)) < 0) return(x);
11271 #ifdef COMMENT
11272 if (maxtry <= wslotr) {
11273 printf("?Retry limit must be greater than window size\n");
11274 return(success = 0);
11275 }
11276 #endif /* COMMENT */
11277 if (rmsflg) {
11278 sstate = setgen('S', "403", ckitoa(maxtry), "");
11279 return((int) sstate);
11280 } else return(success = x);
11281 #endif /* NOXFER */
11282
11283 #ifndef NOSERVER
11284 case XYSERV: /* SET SERVER items */
11285 if ((y = cmkey(srvtab,nsrvt,"","",xxstring)) < 0) return(y);
11286 switch (y) {
11287 case XYSERI:
11288 if ((y = cmnum("Number of seconds, or 0 for no idle timeout",
11289 "0",10,&x,xxstring)) < 0)
11290 return(y);
11291 if (x < 0)
11292 x = 0;
11293 if ((y = cmcfm()) < 0)
11294 return(y);
11295 #ifndef OS2
11296 srvtim = 0;
11297 #endif /* OS2 */
11298 srvidl = x;
11299 return(success = 1);
11300 case XYSERT:
11301 if ((y = cmnum("Interval for server NAKs, 0 = none",
11302 ckitoa(DSRVTIM),
11303 10,&x, xxstring)) < 0)
11304 return(y);
11305 if (x < 0) {
11306 printf(
11307 "\n?Specify a positive number, or 0 for no server NAKs\n");
11308 return(0);
11309 }
11310 if ((y = cmcfm()) < 0) return(y);
11311 if (rmsflg) {
11312 sstate = setgen('S', "404", ckitoa(x), "");
11313 return((int) sstate);
11314 } else {
11315 #ifndef OS2
11316 srvidl = 0;
11317 #endif /* OS2 */
11318 srvtim = x; /* Set the server timeout variable */
11319 return(success = 1);
11320 }
11321 case XYSERD: /* SERVER DISPLAY */
11322 return(success = seton(&srvdis)); /* ON or OFF... */
11323
11324 #ifndef NOSPL
11325 case XYSERP: /* SERVER GET-PATH */
11326 return(parsdir(2));
11327 #endif /* NOSPL */
11328
11329 case XYSERL: /* SERVER LOGIN */
11330 return(cklogin());
11331
11332 case XYSERC: /* SERVER CD-MESSAGE */
11333 x = rmsflg ?
11334 cmkey(onoff,2,"","",xxstring) :
11335 cmkey(cdmsg,3,"","",xxstring);
11336 if (x < 0)
11337 return(x);
11338 if (x == 2) { /* CD-MESSAGE FILE */
11339 if ((x = cmtxt("Name of file","",&s,NULL)) < 0)
11340 return(x);
11341 if (!*s) {
11342 s = NULL;
11343 srvcdmsg = 0;
11344 }
11345 makestr(&cdmsgstr,s);
11346 makelist(cdmsgstr,cdmsgfile,8);
11347 return(success = 1);
11348 }
11349 if ((y = cmcfm()) < 0) /* CD-MESSAGE ON/OFF */
11350 return(y);
11351 if (rmsflg) {
11352 sstate = setgen('S', "420", x ? "1" : "0", "");
11353 return((int) sstate);
11354 } else {
11355 if (x > 0)
11356 srvcdmsg |= 1;
11357 else
11358 srvcdmsg &= 2;
11359 return(success = 1);
11360 }
11361 case XYSERK: /* SERVER KEEPALIVE */
11362 return(success = seton(&srvping)); /* ON or OFF... */
11363
11364 default:
11365 return(-2);
11366 }
11367 #endif /* NOSERVER */
11368 }
11369
11370 switch (xx) {
11371 #ifdef UNIX
11372 #ifndef NOJC
11373 case XYSUSP: /* SET SUSPEND */
11374 seton(&xsuspend); /* on or off... */
11375 return(success = 1);
11376 #endif /* NOJC */
11377 #endif /* UNIX */
11378
11379 case XYTAKE: /* SET TAKE */
11380 if ((y = cmkey(taktab,4,"","",xxstring)) < 0) return(y);
11381 switch (y) {
11382 case 0: return(success = seton(&techo));
11383 #ifndef NOSPL
11384 case 1: return(success = seton(&takerr[cmdlvl]));
11385 #else
11386 case 1: return(success = seton(&takerr[tlevel]));
11387 #endif /* NOSPL */
11388 case 2: techo = 0; return(success = 1); /* For compatibility with */
11389 case 3: techo = 1; return(success = 1); /* MS-DOS Kermit */
11390 default: return(-2);
11391 }
11392
11393 #ifndef NOSCRIPT
11394 case XYSCRI: /* SET SCRIPT */
11395 if ((y = cmkey(scrtab,1,"","echo",xxstring)) < 0) return(y);
11396 switch (y) {
11397 case 0: return(success = seton(&secho));
11398 default: return(-2);
11399 }
11400 #endif /* NOSCRIPT */
11401
11402 default:
11403 break;
11404 }
11405
11406 #ifndef NOLOCAL
11407 switch (xx) {
11408 case XYTERM: /* SET TERMINAL */
11409 x = settrm();
11410 success = (x > 0) ? 1 : 0;
11411 return(x);
11412
11413 #ifdef NT
11414 case XYWIN95: /* SET WIN95 workarounds */
11415 x = setwin95();
11416 success = (x > 0 ? 1 : 0);
11417 return(x);
11418 #endif /* NT */
11419
11420 #ifdef OS2
11421 case XYDLR: /* SET DIALER workarounds */
11422 x = setdialer();
11423 success = (x > 0 ? 1 : 0);
11424 return(x);
11425
11426 case XYTITLE: /* SET TITLE of window */
11427 x = settitle();
11428 success = (x > 0 ? 1 : 0);
11429 return(x);
11430 #endif /* OS2 */
11431
11432 #ifdef OS2MOUSE
11433 case XYMOUSE: /* SET MOUSE */
11434 return(success = setmou());
11435 #endif /* OS2MOUSE */
11436
11437 case XYBELL: /* SET BELL */
11438 return(success = setbell());
11439
11440 #ifdef OS2
11441 case XYPRTY:
11442 return(success = setprty() );
11443 #endif /* OS2 */
11444
11445 default:
11446 break;
11447 }
11448 #endif /* NOLOCAL */
11449
11450 switch (xx) {
11451
11452 /* SET SEND/RECEIVE protocol parameters. */
11453
11454 #ifndef NOXFER
11455 case XYRECV:
11456 case XYSEND:
11457 return(setsr(xx,rmsflg));
11458 #endif /* NOXFER */
11459
11460 #ifndef NOLOCAL
11461 case XYSESS: /* SESSION-LOG */
11462 if ((x = cmkey(sfttab,nsfttab,"type of file",
11463 #ifdef OS2
11464 "binary",
11465 #else /* OS2 */
11466 "text",
11467 #endif /* OS2 */
11468 xxstring
11469 )
11470 ) < 0)
11471 return(x);
11472 if ((y = cmcfm()) < 0)
11473 return(y);
11474 if (x == 999) { /* TIMESTAMPED-TEXT */
11475 sessft = XYFT_T; /* Implies text */
11476 slogts = 1; /* and timestamps */
11477 } else if (x == 998) { /* NULL-PADDED-LINES */
11478 slognul = 1; /* adds NUL after ^J */
11479 } else { /* A regular type */
11480 sessft = x; /* The type */
11481 slogts = 0; /* No timestampes */
11482 }
11483 return(success = 1);
11484
11485 case XYSPEE: /* SET SPEED */
11486 lp = line;
11487 if (local && !network) {
11488 ckmakmsg(lp,
11489 LINBUFSIZ,
11490 "Transmission rate for ",
11491 ttname,
11492 " (bits per second)",
11493 NULL
11494 );
11495 } else {
11496 ckstrncpy(lp,
11497 "Serial-port speed (bits per second)",
11498 LINBUFSIZ
11499 );
11500 }
11501 zz = -1L;
11502
11503 #ifdef TN_COMPORT
11504 if (network && istncomport())
11505 x = cmkey(tnspdtab,ntnspd,line,"",xxstring);
11506 else
11507 #endif /* TN_COMPORT */
11508 x = cmkey(spdtab,nspd,line,"",xxstring);
11509 if (x < 0) {
11510 if (x == -3) printf("?value required\n");
11511 #ifdef USETCSETSPEED
11512 /* In this case, any number can be tried */
11513 /* There's a parse error message but the request still goes thru */
11514 if (rdigits(atmbuf))
11515 zz = atol(atmbuf);
11516 else
11517 #endif /* USETCSETSPEED */
11518 return(x);
11519 }
11520 if ((y = cmcfm()) < 0) return(y);
11521 #ifdef IKSD
11522 if (inserver) {
11523 printf("?Sorry, command disabled.\r\n");
11524 return(success = 0);
11525 }
11526 #endif /* IKSD */
11527 if (!local) {
11528 printf("?SET SPEED has no effect without prior SET LINE\n");
11529 return(success = 0);
11530 } else if (network
11531 #ifdef TN_COMPORT
11532 && !istncomport()
11533 #endif /* TN_COMPORT */
11534 ) {
11535 printf("\n?Speed cannot be set for network connections\n");
11536 return(success = 0);
11537 }
11538
11539 /*
11540 Note: This way of handling speeds is not 16-bit safe for speeds greater
11541 than 230400. The argument to ttsspd() should have been a long.
11542 */
11543 #ifdef USETCSETSPEED
11544 if (zz > -1L)
11545 x = zz / 10L;
11546 #endif /* USETCSETSPEED */
11547 zz = (long) x * 10L;
11548 if (zz == 130L) zz = 134L;
11549 if (zz == 70L) zz = 75L; /* (see spdtab[] definition) */
11550 if (ttsspd(x) < 0) { /* Call ttsspd with cps, not bps! */
11551 printf("?Unsupported line speed - %ld\n",zz);
11552 return(success = 0);
11553 } else {
11554 #ifdef CK_TAPI
11555 if (!tttapi || tapipass)
11556 speed = ttgspd(); /* Read it back */
11557 else
11558 speed = zz;
11559 #else /* CK_TAPI */
11560 speed = ttgspd(); /* Read it back */
11561 #endif /* CK_TAPI */
11562 if (speed != zz) { /* Call ttsspd with cps, not bps! */
11563 printf("?SET SPEED fails, speed is %ld\n",speed);
11564 return(success = 0);
11565 }
11566 if (pflag && !xcmdsrc) {
11567 if (speed == 8880)
11568 printf("%s, 75/1200 bps\n",ttname);
11569 else if (speed == 134)
11570 printf("%s, 134.5 bps\n",ttname);
11571 else
11572 printf("%s, %ld bps\n",ttname,speed);
11573 }
11574 return(success = 1);
11575 }
11576 #endif /* NOLOCAL */
11577
11578 #ifndef NOXFER
11579 case XYXFER: /* SET TRANSFER */
11580 if ((y = cmkey(rmsflg ? rtstab : tstab, /* (or REMOTE SET TRANSFER) */
11581 rmsflg ? nrts : nts,
11582 "","character-set",xxstring)) < 0) return(y);
11583 switch (y) {
11584 #ifdef XFRCAN
11585 case XYX_CAN: /* CANCELLATION */
11586 if ((z = cmkey(onoff,2,"","",xxstring)) < 0) return(z);
11587 if (z == 0) { /* OFF */
11588 if ((y = cmcfm()) < 0) return(y);
11589 xfrcan = 0;
11590 } else {
11591 if ((y = cmnum("ASCII code for cancellation character",
11592 "3",10,&x,
11593 xxstring)) < 0)
11594 return(y);
11595 if (x > 31 && x != 127) {
11596 printf("Cancel character must be 0-31 or 127\n");
11597 return(-9);
11598 }
11599 if ((y = cmnum("How many required to cause cancellation",
11600 "2",10,&z, xxstring)) < 0)
11601 return(y);
11602 if (z < 2) {
11603 printf("Number must be 2 or greater\n");
11604 return(-9);
11605 }
11606 if ((y = cmcfm()) < 0) return(y);
11607 xfrcan = 1; /* CANCELLATION ON */
11608 xfrchr = x; /* Using this character */
11609 xfrnum = z; /* Needing this many of them */
11610 }
11611 return(success = 1);
11612 #endif /* XFRCAN */
11613
11614 #ifndef NOCSETS
11615 case XYX_CSE: /* CHARACTER-SET */
11616 if ((y = cmkey(tcstab,ntcs,"","transparent",xxstring)) < 0)
11617 return(y);
11618 if ((x = cmcfm()) < 0) return(x);
11619 if (rmsflg) {
11620 sstate = setgen('S', "405", tcsinfo[y].designator, "");
11621 return((int) sstate);
11622 } else {
11623 extern int s_cset, fcharset, axcset[], tcs_save;
11624 tslevel = (y == TC_TRANSP) ? 0 : 1; /* transfer syntax level */
11625 xfrxla = tslevel;
11626 tcharset = y; /* transfer character set */
11627 /* SEND CHARACTER-SET AUTO */
11628 if (tslevel > 0 && s_cset == XMODE_A)
11629 if (y > -1 && y <= MAXTCSETS)
11630 if (axcset[y] > -1 && axcset[y] > MAXFCSETS)
11631 fcharset = axcset[y]; /* Auto-pick file charset */
11632 setxlatype(tcharset,fcharset); /* Translation type */
11633 tcs_save = -1;
11634 return(success = 1);
11635 }
11636 #endif /* NOCSETS */
11637
11638 case XYX_LSH: /* LOCKING-SHIFT */
11639 if ((y = cmkey(lstab,nls,"","on",xxstring)) < 0)
11640 return(y);
11641 if ((x = cmcfm()) < 0) return(x);
11642 lscapr = (y == 1) ? 1 : 0; /* ON: requested = 1 */
11643 lscapu = (y == 2) ? 2 : 0; /* FORCED: used = 1 */
11644 return(success = 1);
11645
11646 /* #ifdef CK_XYZ */
11647 case XYX_PRO: /* Protocol */
11648 #ifndef OS2
11649 if (inserver) {
11650 printf("?Sorry, only Kermit protocol is available\n");
11651 return(-9);
11652 }
11653 #endif /* OS2 */
11654 return(setproto());
11655 /* #endif */ /* CK_XYZ */
11656
11657 case XYX_MOD: /* Mode */
11658 if ((y = cmkey(xfrmtab,2,"","automatic",xxstring)) < 0)
11659 return(y);
11660 if ((x = cmcfm()) < 0) return(x);
11661 if (rmsflg) {
11662 sstate = setgen('S', "410", y == XMODE_A ? "0" : "1", "");
11663 return((int)sstate);
11664 }
11665 g_xfermode = y;
11666 xfermode = y;
11667 #ifdef NEWFTP
11668 if (ftpisopen()) { /* If an FTP connection is open */
11669 extern int ftp_xfermode; /* change its transfer mode too */
11670 ftp_xfermode = xfermode;
11671 }
11672 #endif /* NEWFTP */
11673 return(success = 1);
11674
11675 #ifndef NOLOCAL
11676 case XYX_DIS: /* Display */
11677 return(doxdis(1)); /* 1 == Kermit */
11678 #endif /* NOLOCAL */
11679
11680 case XYX_SLO: /* Slow-start */
11681 return(seton(&slostart));
11682
11683 #ifndef NOSPL
11684 case XYX_CRC: /* CRC */
11685 return(seton(&docrc));
11686 #endif /* NOSPL */
11687
11688 case XYX_BEL: /* Bell */
11689 return(seton(&xfrbel));
11690
11691 #ifdef PIPESEND
11692 case XYX_PIP: /* Pipes */
11693 #ifndef NOPUSH
11694 if (nopush) {
11695 #endif /* NOPUSH */
11696 printf("Sorry, access to pipes is disabled\n");
11697 return(-9);
11698 #ifndef NOPUSH
11699 } else
11700 #endif /* NOPUSH */
11701 return(seton(&usepipes));
11702 #endif /* PIPESEND */
11703
11704 case XYX_INT: /* Interruption */
11705 return(seton(&xfrint));
11706
11707 case XYX_XLA:
11708 return(seton(&xfrxla)); /* Translation */
11709
11710 case XYX_MSG: {
11711 extern char * xfrmsg;
11712 if ((x = cmtxt("Prompt string","",&s,xxstring)) < 0)
11713 return(x);
11714 if (!*s) s = NULL;
11715 makestr(&xfrmsg,s);
11716 return(success = 1);
11717
11718 }
11719 case XYX_RPT: {
11720 extern int whereflg;
11721 return(seton(&whereflg));
11722 }
11723 default:
11724 return(-2);
11725 }
11726 #endif /* NOXFER */
11727 }
11728
11729 switch (xx) {
11730
11731 #ifndef NOXMIT
11732 case XYXMIT: /* SET TRANSMIT */
11733 return(setxmit());
11734 #endif /* NOXMIT */
11735
11736 #ifndef NOXFER
11737 #ifndef NOCSETS
11738 case XYUNCS: /* UNKNOWN-CHARACTER-SET */
11739 if ((y = cmkey(ifdtab,2,"","discard",xxstring)) < 0) return(y);
11740 if ((x = cmcfm()) < 0) return(x);
11741 unkcs = y;
11742 return(success = 1);
11743 #endif /* NOCSETS */
11744 #endif /* NOXFER */
11745
11746 #ifndef NOPUSH
11747 #ifdef UNIX
11748 case XYWILD: /* WILDCARD-EXPANSION */
11749 if ((y = cmkey(wildtab,nwild,
11750 "Wildcard expansion option","on",xxstring)) < 0)
11751 return(y);
11752 if ((z = cmkey(wdottab,
11753 2,
11754 "whether to match filenames that start with \".\"",
11755 "/no-match-dot-files",
11756 xxstring)
11757 ) < 0)
11758 return(z);
11759 if ((x = cmcfm()) < 0) return(x);
11760 if (nopush) {
11761 if (y > 0) {
11762 printf("Shell expansion is disabled\n");
11763 return(success = 0);
11764 }
11765 }
11766 switch (y) {
11767 case WILD_ON:
11768 wildena = 1;
11769 break;
11770 case WILD_OFF:
11771 wildena = 0;
11772 break;
11773 case WILD_KER:
11774 wildxpand = 0; /* These are the previous */
11775 break; /* hardwired values */
11776 case WILD_SHE:
11777 wildxpand = 1;
11778 break;
11779 }
11780 matchdot = z;
11781 return(success = 1);
11782 #endif /* UNIX */
11783 #endif /* NOPUSH */
11784
11785 #ifndef NOXFER
11786 case XYWIND: /* WINDOW-SLOTS */
11787 if (protocol == PROTO_K) {
11788 y = cmnum("Window size for Kermit protocol, 1 to 32",
11789 "1", 10, &x, xxstring);
11790 y = setnum(&z,x,y,MAXWS); /* == 32 */
11791 }
11792 #ifdef CK_XYZ
11793 else if (protocol == PROTO_Z) {
11794 y = cmnum("Window size for ZMODEM protocol, 0 to 65535",
11795 "0", 10, &x, xxstring);
11796 y = setnum(&z,x,y,65535);
11797 }
11798 #endif /* CK_XYZ */
11799 else {
11800 y = cmnum("Window size for current protocol",
11801 "", 10, &x, xxstring);
11802 y = setnum(&z,x,y,65472); /* Doesn't matter - we won't use it */
11803 }
11804 if (y < 0) return(y);
11805 if (protocol == PROTO_K) {
11806 if (z < 1)
11807 z = 1;
11808 }
11809 #ifdef CK_XYZ
11810 else if (protocol == PROTO_Z) {
11811 /* Zmodem windowing is closer to Kermit packet length */
11812 /* than Kermit window size. If Window size is zero */
11813 /* an end of frame and CRC is sent only at the end of */
11814 /* the file (default). Otherwise, an End of Frame */
11815 /* and CRC are sent after Window Size number of bytes */
11816 if (z < 0) /* Disable windowing */
11817 z = 0;
11818 } else {
11819 printf("?SET WINDOW does not apply to %s protocol\n",
11820 ptab[protocol].p_name
11821 );
11822 }
11823 #endif /* CK_XYZ */
11824
11825 #ifdef COMMENT
11826 /* This is taken care of automatically now in protocol negotiation */
11827 if (maxtry < z) {
11828 printf("?Window slots must be less than retry limit\n");
11829 return(success = 0);
11830 }
11831 #endif /* COMMENT */
11832 if (protocol == PROTO_K && rmsflg) { /* Set remote window size */
11833 wslotr = z; /* Set local window size too */
11834 ptab[protocol].winsize = wslotr;
11835 sstate = setgen('S', "406", ckitoa(z), "");
11836 return((int) sstate);
11837 }
11838 wslotr = z; /* Set requested window size here */
11839 ptab[protocol].winsize = wslotr; /* and in protocol-specific table */
11840 if (protocol == PROTO_K) { /* And for Kermit only... */
11841 swcapr = (wslotr > 1) ? 1 : 0; /* set window bit in capas word */
11842 if (wslotr > 1) { /* Window size > 1? */
11843 /* Maybe adjust packet size */
11844 y = adjpkl(urpsiz,wslotr,bigrbsiz);
11845 if (y != urpsiz) { /* Did it change? */
11846 urpsiz = y;
11847 if (msgflg)
11848 printf(
11849 " Adjusting receive packet-length to %d for %d window slots\n",
11850 urpsiz,
11851 wslotr
11852 );
11853 }
11854 }
11855 }
11856 return(success = 1);
11857 #endif /* NOXFER */
11858 }
11859
11860 switch (xx) {
11861
11862 #ifndef NOSPL
11863 case XYOUTP: /* OUTPUT command parameters */
11864 if ((y = cmkey(outptab,noutptab,"OUTPUT command parameter","pacing",
11865 xxstring)) < 0)
11866 return(y);
11867 switch(y) { /* Which parameter */
11868 case OUT_PAC: /* PACING */
11869 y = cmnum("Milliseconds to pause between each OUTPUT character",
11870 "100", 10,&x,xxstring);
11871 y = setnum(&z,x,y,16383); /* Verify and get confirmation */
11872 if (y < 0) return(y);
11873 if (z < 0) z = 0; /* (save some space) */
11874 pacing = z;
11875 return(success = 1);
11876 case OUT_ESC: /* Special-escapes */
11877 return(seton(&outesc));
11878 default: /* (shouldn't happen) */
11879 return(-2);
11880 }
11881 #endif /* NOSPL */
11882
11883 #ifdef CK_SPEED
11884 case XYQCTL: {
11885 short *p;
11886 int zz;
11887 if ((z = cmkey(ctltab,2, "control-character prefixing option",""
11888 ,xxstring)) < 0)
11889 return(z);
11890 /* Make space for a temporary copy of the prefixing table */
11891
11892 p = (short *)malloc(256 * sizeof(short));
11893 if (!p) {
11894 printf("?Internal error - malloc failure\n");
11895 return(-9);
11896 }
11897 for (i = 0; i < 256; i++) p[i] = ctlp[i]; /* Copy current table */
11898
11899 switch (z) {
11900 case 0: /* UNPREFIXED control character */
11901 case 1: /* PREFIXED control character */
11902 while (1) { /* Collect a list of numbers */
11903 #ifndef NOSPL
11904 x_ifnum = 1; /* Turn off complaints from eval() */
11905 #endif /* NOSPL */
11906 if ((x = cmnum((z == 0) ?
11907 "\n Numeric ASCII value of control character that needs NO prefix,\n\
11908 or the word \"all\", or carriage return to complete the list" :
11909 "\n Numeric ASCII value of control character that MUST BE prefixed,\n\
11910 or the word \"all\", or carriage return to complete the list",
11911 "",10,&y,xxstring
11912 )) < 0) {
11913 #ifndef NOSPL
11914 x_ifnum = 0;
11915 #endif /* NOSPL */
11916 if (x == -3) {
11917 if ((x = cmcfm()) < 0) return(x);
11918 break;
11919 }
11920 if (x == -2) {
11921 if (p) { free((char *)p); p = NULL; }
11922 debug(F110,"SET CONTROL atmbuf",atmbuf,0);
11923 if (!ckstrcmp(atmbuf,"all",3,0) || /* "ALL" */
11924 !ckstrcmp(atmbuf,"al",2,0) ||
11925 !ckstrcmp(atmbuf,"a",1,0)) {
11926 if ((x = cmcfm()) < 0) /* Get confirmation */
11927 return(x);
11928 prefixing = z ? PX_ALL : PX_NON;
11929 setprefix(prefixing);
11930 return(success = 1);
11931 } else { /* Not number, not ALL */
11932 printf(
11933 "?Please specify a number or the word ALL\n");
11934 return(-9);
11935 }
11936 } else {
11937 if (p) free((char *)p);
11938 return(x);
11939 }
11940 }
11941 #ifndef NOSPL
11942 x_ifnum = 0;
11943 #endif /* NOSPL */
11944 #ifdef UNPREFIXZERO
11945 zz = 0;
11946 #else
11947 #ifndef OS2
11948 zz = 1 - z;
11949 #else
11950 zz = 0; /* Allow 0 (but only for Zmodem) */
11951 #endif /* OS2 */
11952 #endif /* UNPREFIXZERO */
11953
11954 /* printf("x = %d, y = %d, z = %d, zz = %d\n", x,y,z,zz); */
11955
11956 if ((y > 31 && y < 127) || /* A specific numeric value */
11957 (y > 159 && y < 255) || /* Check that it is a valid */
11958 (y < zz) || /* control code. */
11959 (y > 255)) {
11960 printf("?Values allowed are: %d-31, 127-159, 255\n",zz);
11961 if (p) free((char *)p);
11962 return(-9);
11963 }
11964 x = y & 127; /* Get 7-bit value */
11965 if (z == 0) { /* If they are saying it is safe... */
11966 /* If flow control is Xon/Xoff */
11967 if (((flow == FLO_XONX) &&
11968 /* XON & XOFF chars not safe. */
11969 (x == XON || x == XOFF))
11970 ) {
11971 if (msgflg)
11972 printf(
11973 "Sorry, not while Xon/Xoff is in effect.\n");
11974 if (p) free((char *)p);
11975 return(-9);
11976 }
11977 #ifdef TNCODE
11978 else if (network && IS_TELNET()
11979 && (y == CR ||
11980 (unsigned) y == (unsigned) 255)) {
11981 if (msgflg)
11982 printf("Sorry, not on a TELNET connection.\n");
11983 if (p) free((char *)p);
11984 return(-9);
11985 }
11986 #endif /* TNCODE */
11987 }
11988 p[y] = (char) z; /* All OK, set flag */
11989 } /* End of while loop */
11990 /*
11991 Get here only if they have made no mistakes. Copy temporary table back to
11992 permanent one, then free temporary table and return successfully.
11993 */
11994 for (i = 0; i < 256; i++) ctlp[i] = p[i];
11995 if (p) free((char *)p);
11996 if (z > 0) clearrq = 0; /* 199 (see SET PREFIXING) */
11997 return(success = 1);
11998 default:
11999 return(-2);
12000 }
12001 }
12002 #endif /* CK_SPEED */
12003 }
12004
12005 switch (xx) {
12006
12007 #ifndef NOXFER
12008 case XYREPT:
12009 if ((y = cmkey(rpttab,2,
12010 "repeat-count compression parameter","",xxstring)) < 0)
12011 return(y);
12012 switch(y) {
12013 case 0:
12014 return(success = seton(&rptena)); /* REPEAT COUNTS = ON, OFF */
12015 case 1: /* REPEAT MININUM number */
12016 printf("(not implemented yet, nothing happens)\n");
12017 return(-9);
12018 case 2: /* REPEAT PREFIX char */
12019 if ((x = cmnum("ASCII value","",10,&z,xxstring)) < 0)
12020 return(x);
12021 if ((x = cmcfm()) < 0) return(x);
12022 if ((z > 32 && z < 63) || (z > 95 && z < 127)) {
12023 if (y == 1) rptmin = (CHAR) z; else myrptq = (CHAR) z;
12024 return(success = 1);
12025 } else {
12026 printf("?Illegal value for prefix character\n");
12027 return(-9);
12028 }
12029 }
12030 #endif /* NOXFER */
12031
12032 #ifndef NOSPL
12033 case XYALRM: {
12034 #ifndef COMMENT
12035 int yy;
12036 long zz;
12037 zz = -1L;
12038 yy = x_ifnum;
12039 x_ifnum = 1; /* Turn off internal complaints */
12040 y = cmnum("Seconds from now, or time of day as hh:mm:ss",
12041 "0" ,10, &x, xxstring);
12042 x_ifnum = yy;
12043 if (y < 0) {
12044 if (y == -2) { /* Invalid number or expression */
12045 zz = tod2sec(atmbuf); /* Convert to secs since midnight */
12046 if (zz < 0L) {
12047 printf("?Number, expression, or time of day required\n");
12048 return(-9);
12049 } else {
12050 char now[32]; /* Current time */
12051 char *p;
12052 long tnow;
12053 p = now;
12054 ztime(&p);
12055 tnow = atol(p+11) * 3600L +
12056 atol(p+14) * 60L + atol(p+17);
12057 if (zz < tnow) /* User's time before now */
12058 zz += 86400L; /* So make it tomorrow */
12059 zz -= tnow; /* Seconds from now. */
12060 }
12061 } else
12062 return(y);
12063 }
12064 if (x < 0) {
12065 printf("?Alarm time is in the past.\n");
12066 return(-9);
12067 }
12068 if ((y = cmcfm()) < 0) return(y);
12069 if (zz > -1L) { /* Time of day given? */
12070 x = zz;
12071 if (zz != (long) x) {
12072 printf(
12073 "Sorry, arithmetic overflow - hh:mm:ss not usable on this platform.\n"
12074 );
12075 return(-9);
12076 }
12077 }
12078 return(setalarm((long)x));
12079 }
12080 #else
12081 /*
12082 This is to allow long values where int and long are not the same, e.g.
12083 on 16-bit systems. But something is wrong with it.
12084 */
12085 if ((y = cmtxt("seconds from now", "0", &s, xxstring)) < 0)
12086 return(y);
12087 if (rdigits(s)) {
12088 return(setalarm(atol(s)));
12089 } else {
12090 printf("%s - not a number\n",s);
12091 return(-9);
12092 }
12093 #endif /* COMMENT */
12094 #endif /* NOSPL */
12095
12096 #ifndef NOXFER
12097 case XYPROTO:
12098 return(setproto());
12099 #endif /* NOXFER */
12100
12101 /*
12102 C-Kermit unprefixes control characters automatically on network connections
12103 if CLEAR-CHANNEL is ON, which it is by default. But not all network
12104 connections are transparent to all control characters. For example, the
12105 DEC-20, even when you TELNET to it, is sensitive to Ctrl-O and Ctrl-T.
12106 If you tell C-Kermit to SET CONTROL PREFIX 15 and/or 20, it doesn't help
12107 because CLEAR-CHANNEL is still in effect. If the user goes to the trouble
12108 to set up some prefixing, then Kermit should do what the user said. In
12109 C-Kermit 7.1 Alpha.03 we change the code to set clearrq to 0 if the user
12110 gives a SET PREFIXING or SET CONTROL PREFIX command.
12111 */
12112
12113 #ifdef CK_SPEED
12114 case XYPREFIX: {
12115 #ifdef COMMENT
12116 extern int clearrq;
12117 #endif /* COMMENT */
12118 if ((z = cmkey(pfxtab, 4, "control-character prefixing option",
12119 "", xxstring)) < 0)
12120 return(z);
12121 if ((x = cmcfm()) < 0) return(x);
12122 clearrq = 0; /* 199 */
12123 setprefix(z);
12124 #ifdef COMMENT
12125 if (hints && (z == PX_ALL || z == PX_CAU) && clearrq) {
12126 printf("Hint: Use SET CLEAR-CHANNEL OFF to disable negotiation of\n");
12127 printf(" SET PREFIXING NONE during file transfers on reliable\n");
12128 printf(" connections.\n");
12129 }
12130 #endif /* COMMENT */
12131 return(success = 1);
12132 }
12133 #endif /* CK_SPEED */
12134
12135 #ifndef NOSPL
12136 case XYLOGIN:
12137 if ((z = cmkey(logintab, 3, "value for login script","userid",
12138 xxstring)) < 0)
12139 return(z);
12140 x = cmdgquo();
12141 if (z == LOGI_PSW)
12142 cmdsquo(0);
12143 if ((y = cmtxt("text","",&s, (z == LOGI_PSW) ? NULL : xxstring)) < 0) {
12144 cmdsquo(x);
12145 return(y);
12146 }
12147 cmdsquo(x);
12148 #ifdef IKSD
12149 if (inserver)
12150 return(success = 0);
12151 #endif /* IKSD */
12152 s = brstrip(s);
12153 if ((int)strlen(s) > 63) {
12154 printf("Sorry, too long\n");
12155 return(-9);
12156 }
12157 switch(z) {
12158 case LOGI_UID:
12159 ckstrncpy(uidbuf,s,UIDBUFLEN);
12160 sl_uid_saved = 0;
12161 break;
12162 case LOGI_PSW:
12163 ckstrncpy(pwbuf,s,PWBUFL);
12164 if (pwbuf[0]) {
12165 pwflg = 1;
12166 #ifdef OS2
12167 pwcrypt = 1;
12168 #else /* OS2 */
12169 pwcrypt = 0;
12170 #endif /* OS2 */
12171 }
12172 break;
12173 case LOGI_PRM:
12174 ckstrncpy(prmbuf,s,PWBUFL);
12175 }
12176 return(success = 1);
12177 #endif /* NOSPL */
12178 }
12179
12180 switch (xx) {
12181
12182 case XYSTARTUP:
12183 if ((y = cmkey(ifdtab,2,"","discard",xxstring)) < 0) return(y);
12184 if ((x = cmcfm()) < 0) return(x);
12185 DeleteStartupFile = (y != 0) ? 0 : 1;
12186 return(success = 1);
12187
12188 case XYTMPDIR:
12189 x = cmdir("Name of temporary directory","",&s,xxstring);
12190 if (x == -3)
12191 s = "";
12192 else if (x < 0)
12193 return(x);
12194 ckstrncpy(tmpbuf,s,TMPBUFSIZ);
12195 if ((x = cmcfm()) < 0) return(x);
12196 #ifdef UNIX
12197 if (tmpbuf[0]) {
12198 extern int zchkod;
12199 char tmpname[MAXPATHLEN+1];
12200 char * p = tmpname;
12201 int x;
12202 zchkod = 1; /* Hack for asking zchko() if */
12203 x = zchko(tmpbuf); /* a directory is writeable */
12204 zchkod = 0;
12205 if (x < 0) printf("WARNING: %s does not appear to be writable\n");
12206 zfnqfp(tmpbuf,MAXPATHLEN,p); /* Get and store full pathname */
12207 makestr(&tempdir,tmpname);
12208 }
12209 #else /* No API for getting full pathname in other OS's */
12210 makestr(&tempdir,tmpbuf);
12211 #endif /* UNIX */
12212 return(tempdir ? 1 : 0);
12213
12214 #ifndef NOXFER
12215 case XYDEST: /* DESTINATION */
12216 return(setdest());
12217 #endif /* NOXFER */
12218
12219 #ifndef NOPUSH
12220 #ifndef NOFRILLS
12221
12222 /* Editor, Browser, and FTP Client */
12223
12224 case XYEDIT: /* EDITOR */
12225 #ifdef IKSD
12226 if (inserver) {
12227 printf("?Sorry, command disabled.\r\n");
12228 return(success = 0);
12229 }
12230 #endif /* IKSD */
12231 #ifdef CK_APC
12232 /* Don't let this be set remotely */
12233 if (apcactive == APC_LOCAL ||
12234 (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH)))
12235 return(success = 0);
12236 #endif /* CK_APC */
12237
12238 #ifdef OS2ORUNIX
12239 {
12240 char *p = getenv("PATH");
12241 char *e;
12242 e = editor[0] ? (char *) editor : getenv("EDITOR");
12243 if (!e) e = "";
12244 if (p)
12245 x = cmifip("Name of preferred editor",e,&s,&y,0,p,xxstring);
12246 else
12247 x = cmifi("Full path of preferred editor",e,&s,&y,xxstring);
12248 if (x < 0 && x != -3)
12249 return(x);
12250 }
12251 #else
12252 #ifdef VMS
12253 if ((y = cmtxt("DCL command for editing", "edit", &s, NULL)) < 0) {
12254 if (x != -3)
12255 return(x);
12256 }
12257 #else
12258 if ((x = cmifi("Full path of preferred editor","",&s,&y,xxstring))<0) {
12259 if (x != -3)
12260 return(x);
12261 }
12262 #endif /* VMS */
12263 #endif /* OS2ORUNIX */
12264 #ifdef VMS
12265 ckstrncpy(editor,s,CKMAXPATH);
12266 editopts[0] = NUL;
12267 #else
12268 if (y != 0) {
12269 printf("?A single file please\n");
12270 return(-2);
12271 }
12272 ckstrncpy(line,s,LINBUFSIZ);
12273 if ((x = cmtxt("editor command-line options","",&s,NULL)) < 0)
12274 return(x);
12275 ckstrncpy(tmpbuf,s,TMPBUFSIZ);
12276 if ((z = cmcfm()) < 0) return(z);
12277 if (line[0]) {
12278 zfnqfp(line,CKMAXPATH,editor);
12279 ckstrncpy(editopts,tmpbuf,128);
12280 } else {
12281 editor[0] = NUL;
12282 editopts[0] = NUL;
12283 }
12284 #endif /* VMS */
12285 return(success = 1);
12286
12287 #ifndef NOFTP
12288 #ifndef SYSFTP
12289 #ifdef TCPSOCKET
12290 case XYFTPX:
12291 return(dosetftp()); /* SET FTP */
12292 #endif /* TCPSOCKET */
12293 #endif /* SYSFTP */
12294 #endif /* NOFTP */
12295
12296 #ifdef BROWSER
12297 #ifndef NOFTP
12298 #ifdef SYSFTP
12299 case XYFTP: /* SET FTP-CLIENT */
12300 #endif /* SYSFTP */
12301 #endif /* NOFTP */
12302 case XYBROWSE: /* SET BROWSER */
12303 {
12304 char *p = getenv("PATH");
12305 char *app = (char *) browser, *opts = (char *) browsopts;
12306 #ifndef NOFTP
12307 #ifdef SYSFTP
12308 extern char ftpapp[], ftpopts[];
12309 if (xx == XYFTP) {
12310 app = (char *)ftpapp;
12311 opts = (char *)ftpopts;
12312 }
12313 #endif /* SYSFTP */
12314 #endif /* NOFTP */
12315 #ifdef IKSD
12316 if (inserver) {
12317 printf("?Sorry, command disabled.\r\n");
12318 return(success = 0);
12319 }
12320 #endif /* IKSD */
12321 #ifdef CK_APC
12322 /* Don't let this be set remotely */
12323 if (apcactive == APC_LOCAL ||
12324 (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH)))
12325 return(success = 0);
12326 #endif /* CK_APC */
12327 #ifdef OS2ORUNIX
12328 if (p)
12329 x = cmifip(xx == XYBROWSE ?
12330 "Name of preferred browser" :
12331 "Name of preferred ftp client",
12332 #ifdef OS2
12333 xx == XYFTP ? "ftp.exe" : ""
12334 #else
12335 xx == XYFTP ? "ftp" : ""
12336 #endif /* OS2 */
12337 ,&s,&y,0,p,xxstring
12338 );
12339 else
12340 x = cmifi(xx == XYBROWSE ?
12341 "Full path of preferred browser" :
12342 "Full path of preferred ftp client",
12343 "",&s,&y,xxstring
12344 );
12345 if (x < 0 && x != -3)
12346 return(x);
12347 #else
12348 #ifdef VMS
12349 if ((x = cmtxt("DCL command to start your preferred Web browser",
12350 "", &s, NULL)) < 0) {
12351 if (x != -3)
12352 return(x);
12353 }
12354 #else
12355 if ((x = cmifi("Full path of preferred browser","",&s,&y,xxstring)
12356 ) < 0) {
12357 if (x != -3)
12358 return(x);
12359 }
12360 #endif /* VMS */
12361 #endif /* OS2ORUNIX */
12362 #ifdef VMS
12363 ckstrncpy(app,s,CKMAXPATH);
12364 *opts = NUL;
12365 #else
12366 if (y != 0) {
12367 printf("?A single file please\n");
12368 return(-2);
12369 }
12370 ckstrncpy(line,s,LINBUFSIZ);
12371 if ((x = cmtxt(xx == XYBROWSE ?
12372 "browser command-line options" :
12373 "ftp client command-line options",
12374 "",&s,NULL)
12375 ) < 0)
12376 return(x);
12377 ckstrncpy(tmpbuf,s,TMPBUFSIZ);
12378 if ((z = cmcfm()) < 0) return(z);
12379 if (line[0]) {
12380 zfnqfp(line,CKMAXPATH,app);
12381 ckstrncpy(opts, tmpbuf, 128);
12382 } else {
12383 *app = NUL;
12384 *opts = NUL;
12385 }
12386 #endif /* VMS */
12387 return(success = 1);
12388 }
12389 #endif /* BROWSER */
12390 #endif /* NOFRILLS */
12391 #endif /* NOPUSH */
12392
12393 #ifdef CK_CTRLZ
12394 case XYEOF: { /* SET EOF */
12395 extern int eofmethod; extern struct keytab eoftab[];
12396 if ((x = cmkey(eoftab,3,"end-of-file detection method","",
12397 xxstring)) < 0)
12398 return(x);
12399 if ((y = cmcfm()) < 0)
12400 return(y);
12401 eofmethod = x;
12402 return(success = 1);
12403 }
12404 #endif /* CK_CTRLZ */
12405
12406 case XYRELY: { /* SET RELIABLE */
12407 if ((x = cmkey(ooatab,3,"","automatic",xxstring)) < 0)
12408 return(x);
12409 if ((y = cmcfm()) < 0) return(y);
12410 reliable = x;
12411 setreliable = (x != SET_AUTO);
12412 debug(F101,"SET RELIABLE reliable","",reliable);
12413 return(success = 1);
12414 }
12415
12416 #ifdef STREAMING
12417 case XYSTREAM: { /* SET STREAMING */
12418 extern int streamrq;
12419 if ((x = cmkey(ooatab,3,"","automatic",xxstring)) < 0)
12420 return(x);
12421 if ((y = cmcfm()) < 0) return(y);
12422 streamrq = x;
12423 return(success = 1);
12424 }
12425 #endif /* STREAMING */
12426
12427 #ifdef CKSYSLOG
12428 case XYSYSL: {
12429 if ((x = cmkey(syslogtab,nsyslog,"","",xxstring)) < 0)
12430 return(x);
12431 if ((y = cmcfm()) < 0) return(y);
12432 #ifdef IKSD
12433 if (inserver &&
12434 #ifdef IKSDCONF
12435 iksdcf
12436 #else
12437 1
12438 #endif /* IKSDCONF */
12439 ) {
12440 printf("?Sorry, command disabled.\n");
12441 return(success = 0);
12442 }
12443 #endif /* IKSD */
12444 #ifdef CK_APC
12445 /* Don't let this be set remotely */
12446 if (apcactive == APC_LOCAL ||
12447 (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH)))
12448 return(success = 0);
12449 #endif /* CK_APC */
12450 ckxsyslog = x;
12451 return(success = 1);
12452 }
12453 #endif /* CKSYSLOG */
12454
12455 #ifdef TLOG
12456 case XYTLOG: { /* SET TRANSACTION-LOG */
12457 extern int tlogsep;
12458 if ((x = cmkey(vbtab,nvb,"","verbose",xxstring)) < 0)
12459 return(x);
12460 if (x == 0) {
12461 if ((y = cmtxt("field separator",",",&s,NULL)) < 0) return(y);
12462 s = brstrip(s);
12463 if (*s) {
12464 if (s[1]) {
12465 printf("?A single character, please.\n");
12466 return(-9);
12467 } else if ((*s >= '0' && *s <= '9') ||
12468 (*s >= 'A' && *s <= 'Z') ||
12469 (*s >= 'a' && *s <= 'z')) {
12470 printf("?A non-alphanumeric character, please.\n");
12471 return(-9);
12472 } else
12473 tlogsep = *s;
12474 }
12475 } else {
12476 if ((y = cmcfm()) < 0) return(y);
12477 }
12478 #ifdef IKSD
12479 if (inserver && isguest) {
12480 printf("?Sorry, command disabled.\n");
12481 return(success = 0);
12482 }
12483 #endif /* IKSD */
12484 #ifdef CK_APC
12485 /* Don't let this be set remotely */
12486 if (apcactive == APC_LOCAL ||
12487 (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH)))
12488 return(success = 0);
12489 #endif /* CK_APC */
12490 tlogfmt = x;
12491 return(success = 1);
12492 }
12493 #endif /* TLOG */
12494
12495 case XYCLEAR: { /* SET CLEARCHANNEL */
12496 if ((x = cmkey(ooatab,3,"","automatic",xxstring)) < 0)
12497 return(x);
12498 if ((y = cmcfm()) < 0) return(y);
12499 clearrq = x;
12500 return(success = 1);
12501 }
12502
12503 #ifdef CK_AUTHENTICATION
12504 case XYAUTH: { /* SET AUTHENTICATION */
12505 #ifdef CK_KERBEROS
12506 int kv = 0;
12507 extern struct krb_op_data krb_op;
12508 #endif /* CK_KERBEROS */
12509 char * p = NULL;
12510 if ((x =
12511 cmkey(setauth,nsetauth,"authentication type","",xxstring)) < 0)
12512 return(x);
12513 switch (x) {
12514 #ifdef CK_KERBEROS
12515 case AUTH_KRB4: kv = 4; break; /* Don't assume values are same */
12516 case AUTH_KRB5: kv = 5; break;
12517 #endif /* CK_KERBEROS */
12518 #ifdef CK_SRP
12519 case AUTH_SRP: break;
12520 #endif /* CK_SRP */
12521 #ifdef CK_SSL
12522 case AUTH_SSL:
12523 case AUTH_TLS:
12524 break;
12525 #endif /* CK_SSL */
12526 default:
12527 printf("?Authorization type not supported yet - \"%s\"\n",
12528 atmbuf);
12529 return(-9);
12530 }
12531 #ifdef IKSD
12532 if (inserver &&
12533 #ifdef IKSDCONF
12534 iksdcf
12535 #else
12536 1
12537 #endif /* IKSDCONF */
12538 ) {
12539 if ((y = cmcfm()) < 0) return(y);
12540 printf("?Sorry, command disabled.\n");
12541 return(success = 0);
12542 }
12543 #endif /* IKSD */
12544 #ifdef CK_APC
12545 /* Don't let this be set remotely */
12546 if (apcactive == APC_LOCAL ||
12547 apcactive == APC_REMOTE && !(apcstatus & APC_UNCH)) {
12548 if ((y = cmcfm()) < 0) return(y);
12549 return(success = 0);
12550 }
12551 #endif /* CK_APC */
12552
12553 switch(x) {
12554 #ifdef CK_KERBEROS
12555 case AUTH_KRB4:
12556 case AUTH_KRB5: {
12557 if ((x = cmkey(kv == 4 ? k4tab : k5tab,
12558 kv == 4 ? nk4tab : nk5tab,
12559 "Kerberos parameter","",xxstring)) < 0) {
12560 return(x);
12561 }
12562 s = "";
12563 switch (x) {
12564 #ifdef KRB4
12565 case XYKRBDBG:
12566 if (kv == 4) {
12567 if ((y = seton(&k4debug)) < 0)
12568 return(y);
12569 #ifdef NT
12570 ck_krb4_debug(k4debug);
12571 #endif /* NT */
12572 } else {
12573 return(-9);
12574 }
12575 break;
12576 #endif /* KRB4 */
12577 case XYKRBLIF:
12578 if ((y = cmnum("TGT lifetime","600",10,&z,xxstring)) < 0)
12579 return(y);
12580 break;
12581 case XYKRBPRE:
12582 if (kv == 4) {
12583 if ((y = seton(&krb4_d_preauth)) < 0)
12584 return(y);
12585 } else {
12586 return(-9);
12587 }
12588 break;
12589 case XYKRBINS:
12590 if ((y = cmtxt("Instance name","",&s,xxstring)) < 0)
12591 return(y);
12592 break;
12593 case XYKRBFWD:
12594 if (kv == 5) {
12595 if ((y = seton(&krb5_d_forwardable)) < 0)
12596 return(y);
12597 } else {
12598 return(-9);
12599 }
12600 break;
12601 case XYKRBPRX:
12602 if (kv == 5) {
12603 if ((y = seton(&krb5_d_proxiable)) < 0)
12604 return(y);
12605 } else {
12606 return(-9);
12607 }
12608 break;
12609 case XYKRBRNW:
12610 if ((y = cmnum("TGT renewable lifetime",
12611 "0",10,&z,xxstring)) < 0)
12612 return(y);
12613 break;
12614 case XYKRBADR:
12615 if (kv == 5) {
12616 if ((y = seton(&krb5_checkaddrs)) < 0)
12617 return(y);
12618 } else {
12619 if ((y = seton(&krb4_checkaddrs)) < 0)
12620 return(y);
12621 }
12622 break;
12623 case XYKRBNAD:
12624 if (kv == 5) {
12625 if ((y = seton(&krb5_d_no_addresses)) < 0)
12626 return(y);
12627 }
12628 break;
12629 case XYKRBADD:
12630 if (kv == 5) {
12631 char * tmpaddrs[KRB5_NUM_OF_ADDRS];
12632 for (i = 0; i < KRB5_NUM_OF_ADDRS; i++)
12633 tmpaddrs[i] = NULL;
12634
12635 if ((y =
12636 cmfld("List of IP addresses","",&s,xxstring)) < 0)
12637 return(y);
12638 makelist(s,tmpaddrs,KRB5_NUM_OF_ADDRS);
12639 if ((y = cmcfm()) < 0) {
12640 for (i = 0; i < KRB5_NUM_OF_ADDRS; i++) {
12641 if (tmpaddrs[i] != NULL)
12642 free(tmpaddrs[i]);
12643 }
12644 return(y);
12645 }
12646 for (i = 0;
12647 i < KRB5_NUM_OF_ADDRS && tmpaddrs[i];
12648 i++) {
12649 if (inet_addr(tmpaddrs[i]) == 0xffffffff) {
12650 printf("invalid ip address: %s\n",
12651 tmpaddrs[i]);
12652 for (i = 0; i < KRB5_NUM_OF_ADDRS; i++) {
12653 if (tmpaddrs[i] != NULL)
12654 free(tmpaddrs[i]);
12655 }
12656 return(-9);
12657 }
12658 }
12659 for (i = 0;
12660 i < KRB5_NUM_OF_ADDRS && krb5_d_addrs[i];
12661 i++) {
12662 if (krb5_d_addrs[i])
12663 free(krb5_d_addrs[i]);
12664 krb5_d_addrs[i] = NULL;
12665 }
12666 for (i = 0;
12667 i < KRB5_NUM_OF_ADDRS && tmpaddrs[i];
12668 i++) {
12669 krb5_d_addrs[i] = tmpaddrs[i];
12670 tmpaddrs[i] = NULL;
12671 }
12672 krb5_d_addrs[i] = NULL;
12673 return(success = 1);
12674 }
12675 break;
12676
12677 case XYKRBGET:
12678 if (kv == 5) {
12679 if ((y = seton(&krb5_autoget)) < 0)
12680 return(y);
12681 } else {
12682 if ((y = seton(&krb4_autoget)) < 0)
12683 return(y);
12684 }
12685 break;
12686 case XYKRBDEL:
12687 if ((z = cmkey(kdestab,nkdestab,
12688 "Auto Destroy Tickets",
12689 "never",xxstring)) < 0)
12690 return(z);
12691 break;
12692 case XYKRBPR:
12693 if ((y = cmtxt("User ID",uidbuf,&s,xxstring)) < 0)
12694 return(y);
12695 break;
12696 case XYKRBRL:
12697 if ((y = cmtxt("Name of realm","",&s,xxstring)) < 0)
12698 return(y);
12699 break;
12700 case XYKRBKTB:
12701 y = cmifi("Filename","",&s,&z,xxstring);
12702 if (y != -3) {
12703 if (y < 0)
12704 return(y);
12705 if (z) {
12706 printf("?Wildcards not allowed\n");
12707 return(-9);
12708 }
12709 }
12710 break;
12711 case XYKRBCC:
12712 if ((y = cmofi("Filename","",&s,xxstring)) < 0)
12713 return(y);
12714 break;
12715 case XYKRBSRV:
12716 if ((y = cmtxt("Name of service to use in ticket",
12717 (kv == 4 ? "rcmd" : "host"),
12718 &s,
12719 xxstring
12720 )) < 0)
12721 return(y);
12722 break;
12723 case XYKRBK5K4:
12724 if (kv == 5) {
12725 if ((y = seton(&krb5_d_getk4)) < 0)
12726 return(y);
12727 } else {
12728 return(-9);
12729 }
12730 break;
12731 case XYKRBPRM: /* Prompt */
12732 if ((z = cmkey(krbprmtab,2,"","",xxstring)) < 0)
12733 return(z);
12734 if ((y = cmtxt((z == KRB_PW_PRM) ?
12735 "Text of prompt;\nmay contain \"%s\" to be replaced by principal name" :
12736 "Text of prompt",
12737 "",
12738 &s,
12739 xxstring
12740 )
12741 ) < 0)
12742 return(y);
12743 break;
12744 }
12745 ckstrncpy(line,s,LINBUFSIZ);
12746 s = line;
12747 if ((y = cmcfm()) < 0)
12748 return(y);
12749 #ifdef IKSD
12750 if (inserver &&
12751 #ifdef IKSDCONF
12752 iksdcf
12753 #else /* IKSDCONF */
12754 1
12755 #endif /* IKSDCONF */
12756 )
12757 return(success = 0);
12758 #endif /* IKSD */
12759
12760 switch (x) { /* Copy value to right place */
12761 case XYKRBLIF: /* Lifetime */
12762 if (kv == 4)
12763 krb4_d_lifetime = z;
12764 else
12765 krb5_d_lifetime = z;
12766 break;
12767 case XYKRBRNW:
12768 if (kv == 5)
12769 krb5_d_renewable = z;
12770 break;
12771 case XYKRBPR: /* Principal */
12772 s = brstrip(s); /* Strip braces around. */
12773 if (kv == 4)
12774 makestr(&krb4_d_principal,s);
12775 else
12776 makestr(&krb5_d_principal,s);
12777 break;
12778 case XYKRBINS: /* Instance */
12779 if (kv == 4)
12780 makestr(&krb4_d_instance,s);
12781 else
12782 makestr(&krb5_d_instance,s);
12783 break;
12784 case XYKRBRL: /* Realm */
12785 if (kv == 4)
12786 makestr(&krb4_d_realm,s);
12787 else
12788 makestr(&krb5_d_realm,s);
12789 break;
12790 case XYKRBKTB: /* Key Table */
12791 if (kv == 4)
12792 makestr(&k4_keytab,s);
12793 else
12794 makestr(&k5_keytab,s);
12795 break;
12796 case XYKRBCC: /* Credentials cache */
12797 makestr(&krb5_d_cc,s);
12798 break;
12799 case XYKRBSRV: /* Service Name */
12800 if (kv == 4)
12801 makestr(&krb4_d_srv,s);
12802 else
12803 makestr(&krb5_d_srv,s);
12804 break;
12805 case XYKRBDEL:
12806 if (kv == 5)
12807 krb5_autodel = z;
12808 else
12809 krb4_autodel = z;
12810 break;
12811 case XYKRBPRM: /* Prompt */
12812 s = brstrip(s);
12813 switch (z) {
12814 case KRB_PW_PRM: { /* Password */
12815 /* Check that there are no more than */
12816 /* two % fields and % must followed by 's'. */
12817 int i,n,len;
12818 len = strlen(s);
12819 for (i = 0, n = 0; i < len; i++) {
12820 if (s[i] == '%') {
12821 if (s[i+1] != '%') {
12822 if (s[i+1] != 's') {
12823 printf(
12824 "Only %%s fields are permitted.\n"
12825 );
12826 return(-9);
12827 }
12828 if (++n > 2) {
12829 printf(
12830 "Only two %%s fields are permitted.\n");
12831 return(-9);
12832 }
12833 }
12834 i++;
12835 }
12836 }
12837 if (kv == 5)
12838 makestr(&k5pwprompt,s);
12839 else
12840 makestr(&k4pwprompt,s);
12841 break;
12842 }
12843 case KRB_PR_PRM: { /* Principal */
12844 /* Check to make sure there are no % fields */
12845 int i,len;
12846 len = strlen(s);
12847 for (i = 0; i < len; i++) {
12848 if (s[i] == '%') {
12849 if (s[i+1] != '%') {
12850 printf(
12851 "%% fields are not used in this command.\n");
12852 return(-9);
12853 }
12854 i++;
12855 }
12856 }
12857 if (kv == 5)
12858 makestr(&k5prprompt,s);
12859 else
12860 makestr(&k4prprompt,s);
12861 break;
12862 }
12863 }
12864 }
12865 break;
12866 }
12867 #endif /* CK_KERBEROS */
12868 #ifdef CK_SRP
12869 case AUTH_SRP: {
12870 if ((x = cmkey(srptab, nsrptab,
12871 "SRP parameter","",xxstring)) < 0) {
12872 return(x);
12873 }
12874 s = "";
12875 switch (x) {
12876 case XYSRPPRM: /* Prompt */
12877 if ((z = cmkey(srpprmtab,1,"","",xxstring)) < 0)
12878 return(z);
12879 if ((y = cmtxt(
12880 "Text of prompt;\nmay contain one \"%s\" to be replaced by the username",
12881 "",
12882 &s,
12883 xxstring
12884 )
12885 ) < 0)
12886 return(y);
12887 break;
12888 }
12889 ckstrncpy(line,s,LINBUFSIZ);
12890 s = line;
12891 if ((y = cmcfm()) < 0)
12892 return(y);
12893 switch (x) { /* Copy value to right place */
12894 case XYSRPPRM: /* Prompt */
12895 s = brstrip(s);
12896 switch (z) {
12897 case SRP_PW_PRM: { /* Password */
12898 /* Check %s fields */
12899 int i,n,len;
12900 len = strlen(s);
12901 for (i = 0, n = 0; i < len; i++) {
12902 if (s[i] == '%') {
12903 if (s[i+1] != '%') {
12904 if (s[i+1] != 's') {
12905 printf(
12906 "Only %%s fields are permitted.\n");
12907 return(-9);
12908 }
12909 if (++n > 1) {
12910 printf(
12911 "Only one %%s field is permitted.\n");
12912 return(-9);
12913 }
12914 }
12915 i++;
12916 }
12917 }
12918 makestr(&srppwprompt,s);
12919 break;
12920 }
12921 }
12922 }
12923 break;
12924 }
12925 #endif /* CK_SRP */
12926 #ifdef CK_SSL
12927 case AUTH_SSL:
12928 case AUTH_TLS: {
12929 if ((z = cmkey(ssltab, nssltab,
12930 (x == AUTH_SSL ? "SSL parameter" : "TLS parameter"),
12931 "",xxstring)) < 0)
12932 return(z);
12933 s = "";
12934 switch (z) {
12935 case XYSSLRCFL: /* SSL/TLS RSA Certs file */
12936 case XYSSLRCCF: /* SSL/TLS RSA Certs Chain file */
12937 case XYSSLRKFL: /* SSL/TLS RSA Key File */
12938 case XYSSLDCFL: /* SSL/TLS DSA Certs file */
12939 case XYSSLDCCF: /* SSL/TLS DSA Certs Chain file */
12940 case XYSSLDKFL: /* SSL/TLS DH Key File */
12941 case XYSSLDPFL: /* SSL/TLS DH Param File */
12942 case XYSSLCRL: /* SSL/TLS CRL File */
12943 case XYSSLVRFF: /* SSL/TLS Verify File */
12944 case XYSSLRND: /* SSL/TLS Random File */
12945 y = cmifi("Filename","",&s,&x,xxstring);
12946 if (y != -3) {
12947 if (y < 0)
12948 return(y);
12949 if (x) {
12950 printf("?Wildcards not allowed\n");
12951 return(-9);
12952 }
12953 }
12954 ckstrncpy(line,s,LINBUFSIZ);
12955 s = line;
12956 s = brstrip(s);
12957 if ((y = cmcfm()) < 0)
12958 return(y);
12959 switch (z) {
12960 case XYSSLRCFL: /* SSL/TLS RSA Certs file */
12961 if (!s[0] && ssl_rsa_cert_file) {
12962 free(ssl_rsa_cert_file);
12963 ssl_rsa_cert_file = NULL;
12964 } else if (s[0]) {
12965 makestr(&ssl_rsa_cert_file,s);
12966 if (!ssl_rsa_key_file)
12967 makestr(&ssl_rsa_key_file,s);
12968 }
12969 break;
12970 case XYSSLRCCF: /* SSL/TLS RSA Certs Chain file */
12971 if (!s[0] && ssl_rsa_cert_chain_file) {
12972 free(ssl_rsa_cert_chain_file);
12973 ssl_rsa_cert_chain_file = NULL;
12974 } else if (s[0]) {
12975 makestr(&ssl_rsa_cert_chain_file,s);
12976 }
12977 break;
12978 case XYSSLRKFL: /* SSL/TLS RSA Key File */
12979 if (!s[0] && ssl_rsa_key_file) {
12980 free(ssl_rsa_key_file);
12981 ssl_rsa_key_file = NULL;
12982 } else if (s[0]) {
12983 makestr(&ssl_rsa_key_file,s);
12984 }
12985 break;
12986 case XYSSLDCFL: /* SSL/TLS DSA Certs file */
12987 if (!s[0] && ssl_dsa_cert_file) {
12988 free(ssl_dsa_cert_file);
12989 ssl_dsa_cert_file = NULL;
12990 } else if (s[0]) {
12991 makestr(&ssl_dsa_cert_file,s);
12992 if (!ssl_dh_key_file)
12993 makestr(&ssl_dh_key_file,s);
12994 }
12995 break;
12996 case XYSSLDCCF: /* SSL/TLS DSA Certs Chain file */
12997 if (!s[0] && ssl_dsa_cert_chain_file) {
12998 free(ssl_dsa_cert_chain_file);
12999 ssl_dsa_cert_chain_file = NULL;
13000 } else if (s[0]) {
13001 makestr(&ssl_dsa_cert_chain_file,s);
13002 }
13003 break;
13004 case XYSSLDKFL: /* SSL/TLS DH Key File */
13005 if (!s[0] && ssl_dh_key_file) {
13006 free(ssl_dh_key_file);
13007 ssl_dh_key_file = NULL;
13008 } else if (s[0]) {
13009 makestr(&ssl_dh_key_file,s);
13010 }
13011 break;
13012 case XYSSLDPFL: /* SSL/TLS DH Param File */
13013 if (!s[0] && ssl_dh_param_file) {
13014 free(ssl_dh_param_file);
13015 ssl_dh_param_file = NULL;
13016 } else if (s[0]) {
13017 makestr(&ssl_dh_param_file,s);
13018 }
13019 break;
13020 case XYSSLCRL: /* SSL/TLS CRL File */
13021 if (!s[0] && ssl_crl_file) {
13022 free(ssl_crl_file);
13023 ssl_crl_file = NULL;
13024 } else if (s[0]) {
13025 makestr(&ssl_crl_file,s);
13026 }
13027 break;
13028 case XYSSLVRFF: /* SSL/TLS Verify File */
13029 if (!s[0] && ssl_verify_file) {
13030 free(ssl_verify_file);
13031 ssl_verify_file = NULL;
13032 } else if (s[0]) {
13033 makestr(&ssl_verify_file,s);
13034 }
13035 break;
13036 case XYSSLRND: /* SSL/TLS Random File */
13037 if (!s[0] && ssl_rnd_file) {
13038 free(ssl_rnd_file);
13039 ssl_rnd_file = NULL;
13040 } else if (s[0]) {
13041 makestr(&ssl_rnd_file,s);
13042 }
13043 break;
13044 }
13045 break;
13046
13047 case XYSSLCRLD:
13048 case XYSSLVRFD: {
13049 char * d = NULL;
13050 if (z == XYSSLVRFD)
13051 d= getenv("SSL_CERT_DIR");
13052 if (d == NULL)
13053 d = "";
13054 if ((y = cmdir("Directory",d,&s,xxstring)) < 0)
13055 if (y != -3)
13056 return(y);
13057 ckstrncpy(line,s,LINBUFSIZ);
13058 s = line;
13059 s = brstrip(s);
13060 if ((y = cmcfm()) < 0)
13061 return(y);
13062 switch(z) {
13063 case XYSSLCRLD:
13064 if (!s[0] && ssl_crl_dir) {
13065 free(ssl_crl_dir);
13066 ssl_crl_dir = NULL;
13067 } else if (s[0]) {
13068 makestr(&ssl_crl_dir,s);
13069 }
13070 break;
13071 case XYSSLVRFD:
13072 if (!s[0] && ssl_verify_dir) {
13073 free(ssl_verify_dir);
13074 ssl_verify_dir = NULL;
13075 } else if (s[0]) {
13076 makestr(&ssl_verify_dir,s);
13077 }
13078 break;
13079 }
13080 break;
13081 }
13082 case XYSSLCOK: /* SSL/TLS Certs-Ok flag */
13083 if ((y = seton(&ssl_certsok_flag)) < 0)
13084 return(y);
13085 break;
13086 case XYSSLDBG: /* SSL/TLS Debug flag */
13087 if ((y = seton(&ssl_debug_flag)) < 0)
13088 return(y);
13089 break;
13090 case XYSSLON: /* SSL/TLS Only flag */
13091 switch (x) {
13092 case AUTH_SSL:
13093 if ((y = seton(&ssl_only_flag)) < 0)
13094 return(y);
13095 break;
13096 case AUTH_TLS:
13097 if ((y = seton(&tls_only_flag)) < 0)
13098 return(y);
13099 break;
13100 }
13101 break;
13102 case XYSSLVRB: /* SSL/TLS Verbose flag */
13103 if ((y = seton(&ssl_verbose_flag)) < 0)
13104 return(y);
13105 break;
13106 case XYSSLVRF: /* SSL/TLS Verify flag */
13107 if ((x = cmkey(sslvertab, nsslvertab,
13108 "SSL/TLS verify mode",
13109 "peer-cert",xxstring)) < 0)
13110 return(x);
13111 if ((y = cmcfm()) < 0)
13112 return(y);
13113 ssl_verify_flag = x;
13114 break;
13115 case XYSSLDUM:
13116 if ((y = seton(&ssl_dummy_flag)) < 0)
13117 return(y);
13118 break;
13119 case XYSSLCL: { /* SSL/TLS Cipher List */
13120 #ifdef COMMENT
13121 /* This code is used to generate a colon delimited */
13122 /* list of the ciphers currently in use to be used */
13123 /* as the default for cmtxt(). However, a better */
13124 /* default is simply the magic keyword "ALL". */
13125 CHAR def[1024] = "";
13126 if (ssl_con != NULL) {
13127 CHAR * p = NULL, *q = def;
13128 int i, len;
13129
13130 for (i = 0; ; i++) {
13131 p = (CHAR *) SSL_get_cipher_list(ssl_con,i);
13132 if (p == NULL)
13133 break;
13134 len = strlen(p);
13135 if (q+len+1 >= def+1024)
13136 break;
13137 if (i != 0)
13138 *q++ = ':';
13139 strcpy(q,p);
13140 q += len;
13141 }
13142 }
13143 #endif /* COMMENT */
13144 char * p = getenv("SSL_CIPHER");
13145 if (!p)
13146 p = "ALL";
13147 if ((y = cmtxt(
13148 "Colon-delimited list of ciphers or ALL (case-sensitive)",
13149 p,
13150 &s,
13151 xxstring
13152 )
13153 ) < 0)
13154 return(y);
13155 makestr(&ssl_cipher_list,s);
13156 if (ssl_con == NULL) {
13157 SSL_library_init();
13158 ssl_ctx = (SSL_CTX *)
13159 /* Changed in 9.0.305 Alpha.03 from NetBSD 'rhialto' */
13160 /* from: SSL_CTX_new((SSL_METHOD *)TLSv1_method()); to:...*/
13161 SSL_CTX_new((SSL_METHOD *)SSLv23_method());
13162 if (ssl_ctx != NULL)
13163 ssl_con= (SSL *) SSL_new(ssl_ctx);
13164 }
13165 if (ssl_con) {
13166 SSL_set_cipher_list(ssl_con,ssl_cipher_list);
13167 }
13168 break;
13169 }
13170 }
13171 break;
13172 }
13173 #endif /* CK_SSL */
13174 default:
13175 break;
13176 }
13177 return(success = 1);
13178 }
13179 #endif /* CK_AUTHENTICATION */
13180
13181 #ifndef NOSPL
13182 case XYFUNC:
13183 if ((x = cmkey(functab,nfunctab,"","diagnostics",xxstring)) < 0)
13184 return(x);
13185 switch (x) {
13186 case FUNC_DI: return(seton(&fndiags));
13187 case FUNC_ER: return(seton(&fnerror));
13188 default: return(-2);
13189 }
13190 #endif /* NOSPL */
13191
13192 case XYSLEEP: /* SET SLEEP / PAUSE */
13193 if ((x = cmkey(sleeptab,1,"","cancellation",xxstring)) < 0)
13194 return(x);
13195 return(seton(&sleepcan));
13196
13197 case XYCD: /* SET CD */
13198 if ((x = cmkey(cdtab,ncdtab,"","",xxstring)) < 0)
13199 return(x);
13200 switch (x) {
13201 case XYCD_H: { /* SET CD HOME */
13202 extern char * myhome;
13203 if ((y = cmdir("Directory name",zhome(),&s,xxstring)) < 0)
13204 return(y);
13205 makestr(&myhome,s);
13206 return(success = 1);
13207 }
13208 case XYCD_M: /* SET CD MESSAGE */
13209 if ((x = cmkey(cdmsg,ncdmsg,"","",xxstring)) < 0)
13210 return(x);
13211 if (x == 2) { /* CD MESSAGE FILE */
13212 if ((x = cmtxt("Name of file","",&s,NULL)) < 0)
13213 return(x);
13214 if (!*s) {
13215 s = NULL;
13216 #ifndef NOXFER
13217 srvcdmsg = 0;
13218 #endif /* NOXFER */
13219 }
13220 makestr(&cdmsgstr,s);
13221 makelist(cdmsgstr,cdmsgfile,8);
13222 return(success = 1);
13223 }
13224
13225 if ((y = cmcfm()) < 0) return(y); /* CD-MESSAGE ON/OFF */
13226 #ifndef NOXFER
13227 if (x > 0)
13228 srvcdmsg |= 2;
13229 else
13230 srvcdmsg &= 1;
13231 #endif /* NOXFER */
13232 return(success = 1);
13233
13234 case XYCD_P: { /* SET CD PATH */
13235 extern char * ckcdpath;
13236 if ((x = cmtxt("CD PATH string","",&s,xxstring)) < 0)
13237 return(x);
13238 makestr(&ckcdpath,s);
13239 return(success = 1);
13240 }
13241 }
13242
13243 #ifndef NOLOCAL
13244 #ifdef STOPBITS
13245 case XYSTOP: /* STOP-BITS */
13246 if ((x = cmkey(stoptbl,2,"Stop bits for serial device","",
13247 xxstring)) < 0)
13248 return(x);
13249 if ((y = cmcfm()) < 0)
13250 return(y);
13251 if (x > 0 && x < 3) {
13252 stopbits = x;
13253 #ifdef TN_COMPORT
13254 if (network && istncomport()) {
13255 tnsettings(-1, x);
13256 return(success = 1);
13257 }
13258 #endif /* TN_COMPORT */
13259 #ifdef HWPARITY
13260 return(success = 1);
13261 #else /* HWPARITY */
13262 return(-2);
13263 #endif /* HWPARITY */
13264 } else
13265 return(-2);
13266 #endif /* STOPBITS */
13267
13268 case XYDISC: {
13269 extern int clsondisc;
13270 return(seton(&clsondisc));
13271 }
13272
13273 case XYSERIAL: {
13274 /* char c; */
13275 extern int cmask;
13276 if ((x = cmkey(sertbl,nsertbl,
13277 "Serial device character size, parity, and stop bits",
13278 "8N1", xxstring)) < 0)
13279 return(x);
13280 ckstrncpy(line,atmbuf,LINBUFSIZ); /* Associated keyword string */
13281 s = line;
13282 if ((y = cmcfm()) < 0)
13283 return(y);
13284 ckstrncpy(line,sernam[x],LINBUFSIZ);
13285 s = line;
13286 if (s[0] != '8' && s[0] != '7') /* Char size */
13287 return(-2);
13288 else
13289 z = s[0] - '0';
13290 if (isupper(s[1])) /* Parity */
13291 s[1] = tolower(s[1]);
13292 if (s[2] != '1' && s[2] != '2') /* Stop bits */
13293 return(-2);
13294 else
13295 stopbits = s[2] - '0';
13296 if (z == 8) { /* 8 bits + parity (or not) */
13297 parity = 0; /* Set parity */
13298 hwparity = (s[1] == 'n') ? 0 : s[1];
13299 setcmask(8); /* Also set TERM BYTESIZE to 8 */
13300 } else { /* 7 bits plus parity */
13301 parity = (s[1] == 'n') ? 0 : s[1];
13302 hwparity = 0;
13303 setcmask(7); /* Also set TERM BYTESIZE to 7 */
13304 }
13305 #ifdef TN_COMPORT
13306 if (network && !istncomport())
13307 tnsettings(parity, stopbits);
13308 #endif /* TN_COMPORT */
13309
13310 return(success = 1); /* from SET SERIAL */
13311 }
13312
13313 case XYOPTS: { /* SET OPTIONS */
13314 extern int setdiropts();
13315 extern int settypopts();
13316 #ifdef CKPURGE
13317 extern int setpurgopts();
13318 #endif /* CKPURGE */
13319 if ((x = cmkey(optstab,noptstab,"for command","", xxstring)) < 0)
13320 return(x);
13321 switch (x) {
13322 #ifndef NOFRILLS
13323 case XXDEL:
13324 return(setdelopts());
13325 #endif /* NOFRILLS */
13326 case XXDIR:
13327 return(setdiropts());
13328 case XXTYP:
13329 return(settypopts());
13330 #ifdef CKPURGE
13331 case XXPURGE:
13332 return(setpurgopts());
13333 #endif /* CKPURGE */
13334 default:
13335 return(-2);
13336 }
13337 }
13338 #endif /* NOLOCAL */
13339 #ifndef NOXFER
13340 case XYQ8FLG: {
13341 extern int q8flag;
13342 return(seton(&q8flag));
13343 }
13344 case XYTIMER: {
13345 extern int asktimer;
13346 y = cmnum("Time limit for ASK command, seconds","0",10,&x,xxstring);
13347 #ifdef QNX16
13348 return(setnum(&asktimer,x,y,32767));
13349 #else
13350 return(setnum(&asktimer,x,y,86400));
13351 #endif /* QNX16 */
13352 }
13353 case XYFACKB: {
13354 extern int fackbug;
13355 return(seton(&fackbug));
13356 }
13357 #endif /* NOXFER */
13358
13359 case XYHINTS:
13360 return(seton(&hints));
13361
13362 #ifndef NOSPL
13363 case XYEVAL: {
13364 extern int oldeval;
13365 if ((x = cmkey(oldnew,2,"","", xxstring)) < 0)
13366 return(x);
13367 if ((y = cmcfm()) < 0)
13368 return(y);
13369 oldeval = x;
13370 return(success = 1);
13371 }
13372 #endif /* NOSPL */
13373
13374 #ifndef NOXFER
13375 case XYFACKP: {
13376 extern int fackpath;
13377 return(seton(&fackpath));
13378 }
13379 #endif /* NOXFER */
13380
13381 case XYQNXPL: {
13382 extern int qnxportlock;
13383 return(seton(&qnxportlock));
13384 }
13385
13386 #ifndef NOCMDL
13387 #ifdef IKSD
13388 case XYIKS: {
13389 int setiks();
13390 return(setiks());
13391 }
13392 #endif /* IKSD */
13393 #endif /* NOCMDL */
13394
13395 #ifdef CKROOT
13396 case XYROOT:
13397 return(dochroot());
13398 #endif /* CKROOT */
13399
13400 #ifndef NOSPL
13401 #ifndef NOSEXP
13402 case XYSEXP: {
13403 if ((x = cmkey(sexptab,3,"","", xxstring)) < 0)
13404 return(x);
13405 switch (x) {
13406 case 0:
13407 if ((x = cmkey(ooatab,3,"","automatic", xxstring)) < 0)
13408 return(x);
13409 if ((y = cmcfm()) < 0)
13410 return(y);
13411 sexpecho = x;
13412 break;
13413 case 1: {
13414 int i, xx;
13415 xx = sexpmaxdep;
13416 if ((y = cmnum("Maximum recursion depth",
13417 "1000",10,&x,xxstring)) < 0)
13418 return(y);
13419 z = setnum(&sexpmaxdep,x,y,-1);
13420 if (z < 0)
13421 return(z);
13422 if (sxresult) { /* Free old stack if allocated */
13423 for (i = 0; i < xx; i++)
13424 if (sxresult[i]) free(sxresult[i]);
13425 free((char *)sxresult);
13426 if (sxrlen) free((char *)sxrlen);
13427 sxresult = NULL;
13428 sxrlen = NULL;
13429 }
13430 break;
13431 }
13432 case 2:
13433 return(seton(&sexptrunc));
13434 }
13435 return(success = 1);
13436 }
13437 #endif /* NOSEXPL */
13438 #endif /* NOSPL */
13439
13440 #ifdef NEWFTP
13441 case XYGPR: {
13442 extern struct keytab gprtab[];
13443 extern int ftpget;
13444 if ((x = cmkey(gprtab,3,"","kermit", xxstring)) < 0)
13445 return(x);
13446 if ((y = cmcfm()) < 0)
13447 return(y);
13448 ftpget = x;
13449 return(success = 1);
13450 }
13451 #endif /* NEWFTP */
13452
13453 #ifdef ANYSSH
13454 case XYSSH:
13455 return(dosetssh());
13456 #endif /* ANYSHH */
13457
13458 #ifdef SFTP_BUILTIN
13459 case XYSFTP:
13460 return(dosetsftp());
13461 #endif /* SFTP_BUILTIN */
13462
13463 #ifdef LOCUS
13464 case XYLOCUS:
13465 if ((x = cmkey(locustab,nlocustab,"",
13466 #ifdef KUI
13467 "ask"
13468 #else
13469 "auto"
13470 #endif /* KUI */
13471 ,xxstring)) < 0)
13472 return(x);
13473 if ((y = cmcfm()) < 0)
13474 return(y);
13475 if (x == 2 || x == 3) { /* AUTO or ASK */
13476 setautolocus(x - 1); /* Two forms of automatic locusing */
13477 /* setlocus(1,0); */ /* we're not changing the locus here */
13478 } else { /* LOCAL or REMOTE */
13479 setautolocus(0); /* No automatic Locus changing */
13480 setlocus(x,0); /* Set Locus as requested */
13481 }
13482 return(success = 1);
13483 #endif /* LOCUS */
13484
13485 #ifdef KUI
13486 case XYGUI:
13487 return(setgui());
13488 #endif /* KUI */
13489
13490 #ifndef NOFRILLS
13491 #ifndef NORENAME
13492 case XY_REN: /* SET RENAME */
13493 return(setrename());
13494 #endif /* NORENAME */
13495 #endif /* NOFRILLS */
13496
13497 #ifndef NOPUSH
13498 #ifdef CK_REDIR
13499 #ifndef NOXFER
13500 case XYEXTRN: /* SET EXTERNAL-PROTOCOL */
13501 return(setextern());
13502 #endif /* NOXFER */
13503 #endif /* CK_REDIR */
13504 #endif /* NOPUSH */
13505
13506 #ifndef NOSPL
13507 case XYVAREV: /* SET VARIABLE-EVALUATION */
13508 return(setvareval());
13509 #endif /* NOSPL */
13510
13511 #ifdef HAVE_LOCALE
13512 case XYLOCALE:
13513 if ((x = cmtxt("Locale string","C",&s,xxstring)) < 0)
13514 return(x);
13515 setlocale(LC_ALL, "");
13516 setlocale(LC_ALL, s);
13517 if (!setlocale(LC_ALL,NULL)) {
13518 printf("Warning: setlocale(%s) error: %s\n", s, ck_errstr());
13519 }
13520
13521 #ifdef COMMENT
13522 if (!setlocale(LC_COLLATE, s)) {perror("COLLATE");return(success=0);}
13523 if (!setlocale(LC_CTYPE, s)) {perror("CTYPE");return(success=0);}
13524 if (!setlocale(LC_MESSAGES, s)) {perror("MESSAGES");return(success=0);}
13525 if (!setlocale(LC_MONETARY, s)) {perror("MONETARY");return(success=0);}
13526 if (!setlocale(LC_NUMERIC, s)) {perror("NUMERIC");return(success=0);}
13527 if (!setlocale(LC_TIME, s)) {perror("TIME");return(success=0);}
13528 #endif /* COMMENT */
13529 return(success=1);
13530 #endif /* HAVE_LOCALE */
13531
13532 default:
13533 if ((x = cmcfm()) < 0) return(x);
13534 printf("Not implemented - %s\n",cmdbuf);
13535 return(success = 0);
13536 }
13537 }
13538
13539 /*
13540 H U P O K -- Is Hangup OK?
13541
13542 Issues a warning and gets OK from user depending on whether a connection
13543 seems to be open and what the SET EXIT WARNING setting is. Returns:
13544 0 if not OK to hang up or exit (i.e. user said No);
13545 nonzero if OK.
13546 Argument x is used to differentiate the EXIT command from SET LINE / HOST.
13547 */
13548 int
13549 hupok(x) int x; { /* Returns 1 if OK, 0 if not OK */
13550 int y, z = 1;
13551 extern int exithangup;
13552 #ifdef VMS
13553 extern int batch;
13554
13555 if (batch) /* No warnings in batch */
13556 return(1);
13557 #else
13558 #ifdef UNIX
13559 if (backgrd) /* No warnings in background */
13560 return(1);
13561 #endif /* UNIX */
13562 #endif /* VMS */
13563
13564 #ifndef K95G
13565 debug(F101,"hupok local","",local);
13566
13567 if (!local) /* No warnings in remote mode */
13568 return(1);
13569 #endif /* K95G */
13570
13571 if (x == 0 && exithangup == 0) /* EXIT and EXIT HANGUP is OFF */
13572 return(1);
13573
13574 debug(F101,"hupok x","",x);
13575 debug(F101,"hupok xitwarn","",xitwarn);
13576 debug(F101,"hupok network","",network);
13577 debug(F101,"hupok haveline","",haveline);
13578
13579 if ((local && xitwarn) || /* Is a connection open? */
13580 (!x && xitwarn == 2)) { /* Or Always give warning on EXIT */
13581 int needwarn = 0;
13582 char warning[256];
13583
13584 if (network) {
13585 if (ttchk() >= 0)
13586 needwarn = 1;
13587 /* A connection seems to be open but it can't possibly be */
13588 if (!haveline)
13589 needwarn = 0;
13590 if (needwarn) {
13591 if (strcmp(ttname,"*"))
13592 ckmakmsg(warning,256,
13593 " A network connection to ",ttname,
13594 " might still be active.\n",NULL);
13595 else
13596 ckstrncpy(warning,
13597 " An incoming network connection might still be active.\n",
13598 256);
13599 }
13600 } else { /* Serial connection */
13601 if (carrier == CAR_OFF) /* SET CARRIER OFF */
13602 needwarn = 0; /* so we don't care about carrier. */
13603 else if ((y = ttgmdm()) >= 0) /* else, get modem signals */
13604 needwarn = (y & BM_DCD); /* Check for carrier */
13605 else /* If we can't get modem signals... */
13606 needwarn = (ttchk() >= 0);
13607 /* A connection seems to be open but it can't possibly be */
13608 if (!haveline || !exithangup)
13609 needwarn = 0;
13610 if (needwarn)
13611 ckmakmsg(warning,256,
13612 " A serial connection might still be active on ",
13613 ttname,".\n",NULL);
13614 }
13615
13616 /* If a warning was issued, get user's permission to EXIT. */
13617
13618 if (needwarn || (!x && xitwarn == 2
13619 #ifndef K95G
13620 && local
13621 #endif /* K95G */
13622 )) {
13623 if ( !needwarn )
13624 ckstrncpy(warning, "No active connections", 256);
13625
13626 #ifdef COMMENT
13627 printf("%s",warning);
13628 z = getyesno(x ? "OK to close? " : "OK to exit? ",0);
13629 debug(F101,"hupok getyesno","",z);
13630 if (z < -3) z = 0;
13631 #else
13632 z = uq_ok(warning,
13633 x ? "OK to close? " : "OK to exit? ",
13634 3,
13635 NULL,
13636 0
13637 );
13638 debug(F101,"hupok uq_ok","",z);
13639 if (z < 0) z = 0;
13640 #endif /* COMMENT */
13641 }
13642 }
13643 return(z);
13644 }
13645
13646 #ifndef NOSHOW
13647 VOID
13648 shoctl() { /* SHOW CONTROL-PREFIXING */
13649 #ifdef CK_SPEED
13650 int i;
13651 #ifdef OS2
13652 int zero;
13653 #endif /* OS2 */
13654 printf(
13655 "\ncontrol quote = %d, applied to (0 = unprefixed, 1 = prefixed):\n\n",
13656 myctlq);
13657 #ifdef OS2
13658 #ifndef UNPREFIXZERO
13659 zero = ctlp[0];
13660 if (protocol == PROTO_K) /* Zero can't be unprefixed */
13661 ctlp[0] = 1; /* for Kermit */
13662 #endif /* UNPREFIXZERO */
13663 #endif /* OS2 */
13664 for (i = 0; i < 16; i++) {
13665 printf(" %3d: %d %3d: %d ",i,ctlp[i], i+16, ctlp[i+16]);
13666 if (i == 15)
13667 printf(" 127: %d",ctlp[127]);
13668 else
13669 printf(" ");
13670 printf(" %3d: %d %3d: %d ",i+128,ctlp[i+128], i+144, ctlp[i+144]);
13671 if (i == 15) printf(" 255: %d",ctlp[255]);
13672 printf("\n");
13673 }
13674 printf("\n");
13675 #ifndef UNPREFIXZERO
13676 #ifdef OS2
13677 ctlp[0] = zero;
13678 #endif /* OS2 */
13679 #endif /* UNPREFIXZERO */
13680
13681 #endif /* CK_SPEED */
13682 }
13683
13684 #ifndef NOXFER
13685 VOID
13686 shodbl() { /* SHOW DOUBLE/IGNORE */
13687 #ifdef CKXXCHAR
13688 int i, n = 0;
13689 printf("\nSET SEND DOUBLE characters:\n");
13690 for (i = 0; i < 255; i++) {
13691 if (dblt[i] & 2) {
13692 n++;
13693 printf(" %d", i);
13694 }
13695 }
13696 if (n == 0)
13697 printf(" (none)");
13698 n = 0;
13699 printf("\nSET RECEIVE IGNORE characters:\n");
13700 for (i = 0; i < 255; i++) {
13701 if (dblt[i] & 1) {
13702 n++;
13703 printf(" %d", i);
13704 }
13705 }
13706 if (n == 0)
13707 printf(" (none)");
13708 printf("\n\n");
13709 #endif /* CKXXCHAR */
13710 }
13711 #endif /* NOXFER */
13712 #endif /* NOSHOW */
13713
13714 #ifndef NOPUSH
13715 #ifdef CK_REXX
13716 /*
13717 Rexx command. Note, this is not OS/2-specific, because Rexx also runs
13718 on other systems where C-Kermit also runs, like the Amiga.
13719 */
13720 #define REXBUFL 100 /* Change this if neccessary */
13721 char rexxbuf[REXBUFL] = { '\0' }; /* Rexx's return value (string) */
13722
13723 int
13724 dorexx() {
13725 int x, y;
13726 char *rexxcmd;
13727
13728 if ((x = cmtxt("Rexx command","",&rexxcmd,xxstring)) < 0)
13729 return(x);
13730
13731 #ifdef IKSD
13732 if (inserver) {
13733 printf("?Sorry, command disabled.\r\n");
13734 return(success = 0);
13735 }
13736 #endif /* IKSD */
13737 #ifdef CK_APC
13738 /* Don't let this be set remotely */
13739 if (apcactive == APC_LOCAL ||
13740 apcactive == APC_REMOTE && !(apcstatus & APC_UNCH))
13741 return(success = 0);
13742 #endif /* CK_APC */
13743
13744 ckstrncpy(line,rexxcmd,LINBUFSIZ);
13745 rexxcmd = line;
13746 #ifdef OS2
13747 return(os2rexx(rexxcmd,rexxbuf,REXBUFL));
13748 #else /* !OS2 */
13749 printf("Sorry, nothing happens.\n");
13750 return(success = 0);
13751 #endif /* OS2 */
13752 }
13753 #endif /* CK_REXX */
13754 #endif /* NOPUSH */
13755 #else /* NOICP */
13756 VOID
13757 dologend() {
13758 /* Dummy write record to connection log */
13759 }
13760 #endif /* NOICP */
13761