Standards-Version: 3.9.6 (no changes)
[ckermit.git] / ckuus5.c
1 #include "ckcsym.h"
2
3 int xcmdsrc = 0;
4
5 #ifdef NOICP
6 int cmdsrc() { return(0); }
7 #endif /* NOICP */
8
9 /*  C K U U S 5 --  "User Interface" for C-Kermit, part 5  */
10
11 /*
12   Authors:
13     Frank da Cruz <fdc@columbia.edu>,
14       The Kermit Project, Columbia University, New York City
15     Jeffrey E Altman <jaltman@secure-endpoints.com>
16       Secure Endpoints Inc., New York City
17
18   Copyright (C) 1985, 2011,
19     Trustees of Columbia University in the City of New York.
20     All rights reserved.  See the C-Kermit COPYING.TXT file or the
21     copyright text in the ckcmai.c module for disclaimer and permissions.
22 */
23
24 /* Includes */
25
26 #include "ckcdeb.h"
27 #include "ckcasc.h"
28 #include "ckcker.h"
29 #include "ckuusr.h"
30
31 #ifdef DCMDBUF
32 char *line;                             /* Character buffer for anything */
33 char *tmpbuf;
34 #else
35 char line[LINBUFSIZ+1];
36 char tmpbuf[TMPBUFSIZ+1];               /* Temporary buffer */
37 #endif /* DCMDBUF */
38
39 #ifndef NOICP
40
41 #include "ckcnet.h"
42 #ifndef NOCSETS
43 #include "ckcxla.h"
44 #endif /* NOCSETS */
45 #ifdef MAC
46 #include "ckmasm.h"
47 #endif /* MAC */
48 #ifdef CK_SSL
49 #include "ck_ssl.h"
50 #endif /* CK_SSL */
51
52 extern char * ck_cryear;       /* (ckcmai.c) Latest C-Kermit copyright year */
53
54 #ifdef OS2
55 #include "ckoetc.h"
56 #ifndef NT
57 #define INCL_NOPM
58 #define INCL_VIO /* Needed for ckocon.h */
59 #include <os2.h>
60 #undef COMMENT
61 #else /* NT */
62 #include <windows.h>
63 #define TAPI_CURRENT_VERSION 0x00010004
64 #include <tapi.h>
65 #include <mcx.h>
66 #include "ckntap.h"
67 #define APIRET ULONG
68 extern int DialerHandle;
69 extern int StartedFromDialer;
70 #endif /* NT */
71 #include "ckocon.h"
72 #include "ckokey.h"
73 #ifdef KUI
74 #include "ikui.h"
75 #endif /* KUI */
76 #ifdef putchar
77 #undef putchar
78 #endif /* putchar */
79 #define putchar(x) conoc(x)
80 extern int cursor_save ;
81 extern bool cursorena[] ;
82 #endif /* OS2 */
83
84 /* 2010-03-09 SMS.  VAX C V3.1-051 needs <stat.h> for off_t. */
85 #ifdef VMS
86 #include <stat.h>
87 #endif /* def VMS */
88
89 /* For formatted screens, "more?" prompting, etc. */
90
91 #ifdef FT18
92 #define isxdigit(c) isdigit(c)
93 #endif /* FT18 */
94
95 #ifdef STRATUS                          /* Stratus Computer, Inc.  VOS */
96 #ifdef putchar
97 #undef putchar
98 #endif /* putchar */
99 #define putchar(x) conoc(x)
100 #ifdef getchar
101 #undef getchar
102 #endif /* getchar */
103 #define getchar(x) coninc(0)
104 #endif /* STRATUS */
105
106 /* External variables */
107
108 extern int carrier, cdtimo, local, quiet, backgrd, bgset, sosi, xsuspend,
109   binary, escape, xargs, flow, cmdmsk, duplex, ckxech, seslog, what,
110   inserver, diractive, tlevel, cwdf, nfuncs, msgflg, remappd, hints, mdmtyp,
111   zincnt, cmask, rcflag, success, xitsta, pflag, tnlm, tn_nlm, xitwarn,
112   debses, xaskmore, parity, saveask, wasclosed, whyclosed, cdactive,
113   rcdactive, keepallchars, cmd_err;
114
115 #ifdef LOCUS
116 extern int locus, autolocus;
117 #endif /* LOCUS */
118
119 #ifndef NOMSEND
120 extern int addlist;
121 #endif /* NOMSEND */
122
123 #ifdef CK_SPEED
124 extern int prefixing;
125 #endif /* CK_SPEED */
126
127 extern int g_matchdot;
128
129 #ifdef RECURSIVE
130 extern int recursive;
131 #endif /* RECURSIVE */
132 extern int xfiletype;
133
134 #ifdef IKSDCONF
135 extern char * iksdconf;
136 extern int iksdcf;
137 #endif /* IKSDCONF */
138
139 #ifdef CK_RECALL
140 extern int on_recall;
141 #endif /* CK_RECALL */
142
143 extern int ngetpath, exitonclose;
144 extern char * getpath[];
145 extern CHAR * epktmsg;
146
147 extern char * snd_move;
148 extern char * snd_rename;
149 extern char * rcv_move;
150 extern char * rcv_rename;
151 extern char * g_snd_move;
152 extern char * g_snd_rename;
153 extern char * g_rcv_move;
154 extern char * g_rcv_rename;
155
156 extern char * nm[];
157
158 #ifdef CK_UTSNAME
159 extern char unm_mch[];
160 extern char unm_mod[];
161 extern char unm_nam[];
162 extern char unm_rel[];
163 extern char unm_ver[];
164 #endif /* CK_UTSNAME */
165
166 #ifndef NOPUSH
167 #ifndef NOFRILLS
168 extern char editor[];
169 extern char editfile[];
170 extern char editopts[];
171 #ifdef BROWSER
172 extern char browser[];
173 extern char browsopts[];
174 extern char browsurl[];
175 #endif /* BROWSER */
176 #endif /*  NOFRILLS */
177 #endif /* NOPUSH */
178
179 #ifndef NOFRILLS
180 #ifndef NORENAME
181 _PROTOTYP(VOID shorename, (void));
182 #endif  /* NORENAME */
183 #endif  /* NOFRILLS */
184
185 #ifndef NOSERVER
186 extern char * x_user, * x_passwd, * x_acct;
187 #endif /* NOSERVER */
188
189 #ifdef CKLOGDIAL
190 extern int dialog;
191 extern char diafil[];
192 #endif /* CKLOGDIAL */
193
194 #ifdef CKROOT
195 extern int ckrooterr;
196 #endif /* CKROOT */
197
198 #ifndef NOSPL
199 extern int cfilef, xxdot, vareval;
200 extern char cmdfil[];
201
202 struct localvar * localhead[CMDSTKL];
203 struct localvar * localtail = NULL;
204 struct localvar * localnext = NULL;
205
206 _PROTOTYP( VOID shosexp, (void) );
207 _PROTOTYP( static VOID shoinput, (void) );
208 _PROTOTYP( static char gettok,   (void) );
209 _PROTOTYP( static VOID factor,   (void) );
210 _PROTOTYP( static VOID term,     (void) );
211 _PROTOTYP( static VOID termp,    (void) );
212 _PROTOTYP( static VOID exprp,    (void) );
213 _PROTOTYP( static VOID expr,     (void) );
214 _PROTOTYP( static VOID simple,   (void) );
215 _PROTOTYP( static VOID simpler,  (void) );
216 _PROTOTYP( static VOID simplest, (void) );
217 _PROTOTYP( static CK_OFF_T xparse,   (void) );
218 #endif /* NOSPL */
219 #ifndef NOSHOW
220 _PROTOTYP( int sho_iks, (void) );
221 #endif /* NOSHOW */
222
223 #ifdef MAC
224 char * ckprompt = "Mac-Kermit>";        /* Default prompt for Macintosh */
225 char * ikprompt = "IKSD>";
226 #else  /* Not MAC */
227 #ifdef NOSPL
228 #ifdef OS2
229 char * ckprompt = "K-95> ";             /* Default prompt for Win32 */
230 char * ikprompt = "IKSD> ";
231 #else
232 char * ckprompt = "C-Kermit>";
233 char * ikprompt = "IKSD>";
234 #endif /* NT */
235 #else  /* NOSPL */
236 #ifdef OS2
237 /* Default prompt for OS/2 and Win32 */
238 #ifdef NT
239 char * ckprompt = "[\\freplace(\\flongpath(\\v(dir)),/,\\\\)] K-95> ";
240 char * ikprompt = "[\\freplace(\\flongpath(\\v(dir)),/,\\\\)] IKSD> ";
241 #else  /* NT */
242 char * ckprompt = "[\\freplace(\\v(dir),/,\\\\)] K-95> ";
243 char * ikprompt = "[\\freplace(\\v(dir),/,\\\\)] IKSD> ";
244 #endif /* NT */
245 #else  /* OS2 */
246 #ifdef VMS
247 char * ckprompt = "\\v(dir) C-Kermit>"; /* Default prompt VMS */
248 char * ikprompt = "\\v(dir) IKSD>";
249 #else
250 char * ckprompt = "(\\v(dir)) C-Kermit>"; /* Default prompt for others */
251 char * ikprompt = "(\\v(dir)) IKSD>";
252 #endif /* VMS */
253 #endif /* NT */
254 #endif /* NOSPL */
255 #endif /* MAC */
256
257 #ifndef CCHMAXPATH
258 #define CCHMAXPATH 257
259 #endif /* CCHMAXPATH */
260 char inidir[CCHMAXPATH] = { NUL, NUL }; /* Directory INI file executed from */
261
262 #ifdef TNCODE
263 extern int tn_b_nlm;                    /* TELNET BINARY newline mode */
264 #endif /* TNCODE */
265
266 #ifndef NOKVERBS
267 extern struct keytab kverbs[];          /* Table of \Kverbs */
268 extern int nkverbs;                     /* Number of \Kverbs */
269 #endif /* NOKVERBS */
270
271 #ifndef NOPUSH
272 extern int nopush;
273 #endif /* NOPUSH */
274
275 #ifdef CK_RECALL
276 extern int cm_recall;
277 #endif /* CK_RECALL */
278
279 extern char *ccntab[];
280
281 /* Printer stuff */
282
283 extern char *printername;
284 extern int printpipe;
285 #ifdef BPRINT
286 extern int printbidi, pportparity, pportflow;
287 extern long pportspeed;
288 #endif /* BPRINT */
289
290 #ifdef OS2
291 _PROTOTYP (int os2getcp, (void) );
292 _PROTOTYP (int os2getcplist, (int *, int) );
293 #ifdef OS2MOUSE
294 extern int tt_mouse;
295 #endif /* OS2MOUSE */
296 extern int tt_update, tt_updmode, updmode, tt_utf8;
297 #ifndef IKSDONLY
298 extern int tt_status[];
299 #endif /* IKSDONLY */
300 #ifdef PCFONTS
301 extern struct keytab term_font[];
302 #else
303 #ifdef KUI
304 extern struct keytab * term_font;
305 #endif /* KUI */
306 #endif /* PCFONTS */
307 extern int ntermfont, tt_font, tt_font_size;
308 extern unsigned char colornormal, colorunderline, colorstatus,
309     colorhelp, colorselect, colorborder, colorgraphic, colordebug,
310     colorreverse, colorcmd, coloritalic;
311 extern int priority;
312 extern struct keytab prtytab[];
313 extern int nprty;
314 char * cmdmac = NULL;
315 #endif /* OS2 */
316
317 #ifdef VMS
318 _PROTOTYP (int zkermini, (char *, int, char *) );
319 #endif /* VMS */
320
321 extern long vernum;
322 extern int inecho, insilence, inbufsize, nvars, inintr;
323 extern char *protv, *fnsv, *cmdv, *userv, *ckxv, *ckzv, *ckzsys, *xlav,
324  *cknetv, *clcmds;
325 #ifdef OS2
326 extern char *ckyv;
327 #endif /* OS2 */
328 #ifdef CK_AUTHENTICATION
329 extern char * ckathv;
330 #endif /* CK_AUTHENTICATION */
331 #ifdef CK_SSL
332 extern char * cksslv;
333 #endif /* CK_SSL */
334 #ifdef CK_ENCRYPTION
335 #ifndef CRYPT_DLL
336 extern char * ckcrpv;
337 #endif /* CRYPT_DLL */
338 #endif /* CK_ENCRYPTION */
339
340 #ifdef SSHBUILTIN
341 extern char *cksshv;
342 #ifdef SFTP_BUILTIN
343 extern char *cksftpv;
344 #endif /* SFTP_BUILTIN */
345 #endif /* SSHBUILTIN */
346
347 #ifdef TNCODE
348 extern char *cktelv;
349 #endif /* TNCODE */
350 #ifndef NOFTP
351 #ifndef SYSFTP
352 extern char * ckftpv;
353 #endif /* SYSFTP */
354 #endif /* NOFTP */
355
356 extern int srvidl;
357
358 #ifdef OS2
359 extern char *ckonetv;
360 extern int interm;
361 #ifdef CK_NETBIOS
362 extern char *ckonbiv;
363 #endif /* CK_NETBIOS */
364 #ifdef OS2MOUSE
365 extern char *ckomouv;
366 #endif /* OS2MOUSE */
367 #endif /* OS2 */
368
369 #ifndef NOLOCAL
370 extern char *connv;
371 #endif /* NOLOCAL */
372 #ifndef NODIAL
373 extern char *dialv;
374 #endif /* NODIAL */
375 #ifndef NOSCRIPT
376 extern char *loginv;
377 extern int secho;
378 #endif /* NOSCRIPT */
379
380 #ifndef NODIAL
381 extern int nmdm, dirline;
382 extern struct keytab mdmtab[];
383 #endif /* NODIAL */
384
385 extern int network, nettype, ttnproto;
386
387 #ifdef OS2
388 #ifndef NOTERM
389 /* SET TERMINAL items... */
390 extern int tt_type, tt_arrow, tt_keypad, tt_wrap, tt_answer, tt_scrsize[];
391 extern int tt_bell, tt_roll[], tt_ctstmo, tt_cursor, tt_pacing, tt_type_mode;
392 extern char answerback[];
393 extern struct tt_info_rec tt_info[];    /* Indexed by terminal type */
394 extern int max_tt;
395 #endif /* NOTERM */
396 #endif /* OS2 */
397
398 _PROTOTYP( VOID shotrm, (void) );
399 _PROTOTYP( int shofea, (void) );
400
401 #ifdef OS2
402 extern int tt_rows[], tt_cols[];
403 #else /* OS2 */
404 extern int tt_rows, tt_cols;
405 #endif /* OS2 */
406 extern int cmd_rows, cmd_cols;
407
408 #ifdef CK_TMPDIR
409 extern int f_tmpdir;                    /* Directory changed temporarily */
410 extern char savdir[];                   /* Temporary directory */
411 #endif /* CK_TMPDIR */
412
413 #ifndef NOLOCAL
414 extern int tt_crd, tt_lfd, tt_escape;
415 #endif /* NOLOCAL */
416
417 #ifndef NOCSETS
418 extern int language, nfilc, tcsr, tcsl, tcs_transp, fcharset;
419 extern struct keytab fcstab[];
420 extern struct csinfo fcsinfo[];
421 #ifndef MAC
422 extern struct keytab ttcstab[];
423 #endif /* MAC */
424 #endif /* NOCSETS */
425
426 extern long speed;
427
428 #ifndef NOXMIT
429 extern int xmitf, xmitl, xmitp, xmitx, xmits, xmitw, xmitt;
430 extern char xmitbuf[];
431 #endif /* NOXMIT */
432
433 extern char **xargv, *versio, *ckxsys, *dftty, *lp;
434
435 #ifdef DCMDBUF
436 extern char *cmdbuf, *atmbuf;           /* Command buffers */
437 #ifndef NOSPL
438 extern char *savbuf;                    /* Command buffers */
439 #endif /* NOSPL */
440 #else
441 extern char cmdbuf[], atmbuf[];         /* Command buffers */
442 #ifndef NOSPL
443 extern char savbuf[];                   /* Command buffers */
444 #endif /* NOSPL */
445 #endif /* DCMDBUF */
446
447 extern char toktab[], ttname[], psave[];
448 extern CHAR sstate, feol;
449 extern int cmflgs, techo, repars, ncmd;
450 extern struct keytab cmdtab[];
451
452 #ifndef NOSETKEY
453 KEY *keymap;
454 #ifndef OS2
455 #define mapkey(x) keymap[x]
456 #endif /* OS2 */
457 MACRO *macrotab;
458 _PROTOTYP( VOID shostrdef, (CHAR *) );
459 #endif /* NOSETKEY */
460
461 extern int cmdlvl;
462
463 #ifndef NOSPL
464 extern struct mtab *mactab;
465 extern struct keytab mackey[];
466 extern struct keytab vartab[], fnctab[], iftab[];
467 extern int maclvl, nmac, mecho, fndiags, fnerror, fnsuccess, nif;
468 #endif /* NOSPL */
469
470 FILE *tfile[MAXTAKE];                   /* TAKE file stack */
471 char *tfnam[MAXTAKE];
472 int tfline[MAXTAKE];
473
474 int topcmd = -1;                        /* cmdtab index of current command */
475 int havetoken = 0;
476 extern int dblquo;                      /* Doublequoting enabled */
477
478 #ifdef DCMDBUF                          /* Initialization filespec */
479 char *kermrc = NULL;
480 #else
481 char kermrcb[KERMRCL];
482 char *kermrc = kermrcb;
483 #endif /* DCMDBUF */
484
485 int noherald = 0;
486 int cm_retry = 1;                       /* Command retry enabled */
487 xx_strp xxstring = zzstring;
488
489 #ifndef NOXFER
490 extern int displa, bye_active, protocol, pktlog, remfile, rempipe, unkcs,
491   keep, lf_opts, fncnv, pktpaus, autodl, xfrcan, xfrchr, xfrnum, srvtim,
492   srvdis, query, retrans, streamed, reliable, crunched, timeouts,
493   fnrpath, autopath, rpackets, spackets, epktrcvd, srvping;
494
495 #ifdef CK_AUTODL
496 extern int inautodl, cmdadl;
497 #endif /* CK_AUTODL */
498
499 #ifndef NOSERVER
500 extern int en_asg, en_cwd, en_cpy, en_del, en_dir, en_fin, en_bye, en_ret,
501   en_get, en_hos, en_que, en_ren, en_sen, en_set, en_spa, en_typ, en_who,
502   en_mai, en_pri, en_mkd, en_rmd, en_xit, en_ena;
503 #endif /* NOSERVER */
504
505 extern int atcapr,
506   atenci, atenco, atdati, atdato, atleni, atleno, atblki, atblko,
507   attypi, attypo, atsidi, atsido, atsysi, atsyso, atdisi, atdiso;
508
509 #ifdef STRATUS
510 extern int atfrmi, atfrmo, atcrei, atcreo, atacti, atacto;
511 #endif /* STRATUS */
512
513 #ifdef CK_PERMS
514 extern int atlpri, atlpro, atgpri, atgpro;
515 #endif /* CK_PERMS */
516
517 #ifdef CK_LOGIN
518 extern char * anonfile;                 /* Anonymous login init file */
519 extern char * anonroot;                 /* Anonymous file-system root */
520 extern char * userfile;                 /* Forbidden user file */
521 extern int isguest;                     /* Flag for anonymous user */
522 #endif /* CK_LOGIN */
523 #endif /* NOXFER */
524
525 #ifdef DCMDBUF
526 int *xquiet = NULL;
527 int *xvarev = NULL;
528 #else
529 int xquiet[CMDSTKL];
530 int xvarev[CMDSTKL];
531 #endif /* DCMDBUF */
532
533 char * prstring[CMDSTKL];
534
535 #ifndef NOSPL
536
537 extern long ck_alarm;
538 extern char alrm_date[], alrm_time[];
539
540 /* Local declarations */
541
542 static int nulcmd = 0;                  /* Flag for next cmd to be ignored */
543
544 /* Definitions for predefined macros */
545
546 /* First, the single-line macros, installed with addmac()... */
547
548 /* IBM-LINEMODE macro */
549 char *m_ibm = "set parity mark, set dupl half, set handsh xon, set flow none";
550
551 /* FATAL macro */
552 char *m_fat = "if def \\%1 echo \\%1, if not = \\v(local) 0 hangup, stop 1";
553
554 #ifdef CK_SPEED
555 #ifdef IRIX65
556 char *m_fast = "set win 30, set rec pack 4000, set prefix cautious";
557 #else
558 #ifdef IRIX
559 /* Because of bug in telnet server */
560 char *m_fast = "set window 30, set rec pack 4000, set send pack 4000,\
561  set pref cautious";
562 #else
563 #ifdef pdp11
564 char *m_fast = "set win 3, set rec pack 1024, set prefix cautious";
565 #else
566 #ifdef BIGBUFOK
567 char *m_fast = "set win 30, set rec pack 4000, set prefix cautious";
568 #else
569 char *m_fast = "set win 4, set rec pack 2200, set prefix cautious";
570 #endif /* BIGBUFOK */
571 #endif /* IRIX */
572 #endif /* IRIX65 */
573 #endif /* pdp11 */
574 #ifdef pdp11
575 char *m_cautious = "set win 2, set rec pack 512, set prefixing cautious";
576 #else
577 char *m_cautious = "set win 4, set rec pack 1000, set prefixing cautious";
578 #endif /* pdp11 */
579 char *m_robust = "set win 1, set rec pack 90, set prefixing all, \
580 set reliable off, set clearchannel off";
581 #else
582 #ifdef BIGBUFOK
583 #ifdef IRIX65
584 char *m_fast = "set win 30, set rec pack 4000";
585 #else
586 #ifdef IRIX
587 char *m_fast = "set win 30, set rec pack 4000, set send pack 4000";
588 #else
589 char *m_fast = "set win 30, set rec pack 4000";
590 #endif /* IRIX */
591 #endif /* IRIX65 */
592 #else /* Not BIGBUFOK */
593 char *m_fast = "set win 4, set rec pack 2200";
594 #endif /* BIGBUFOK */
595 char *m_cautious = "set win 4, set rec pack 1000";
596 char *m_robust = "set win 1, set rec pack 90, set reliable off";
597 #endif /* CK_SPEED */
598
599 #ifdef VMS
600 char *m_purge = "run purge \\%*";
601 #endif /* VMS */
602
603 #ifdef OS2
604 char *m_manual = "browse \\v(exedir)docs/manual/kermit95.htm";
605 #endif /* OS2 */
606
607 /* Now the multiline macros, defined with addmmac()... */
608
609 /* FOR macro for \%i-style loop variables (see dofor()...) */
610
611 char *for_def[] = { "_assign _for\\v(cmdlevel) { _getargs,",
612 "def \\\\\\%1 \\feval(\\%2),:_..top,if \\%5 \\\\\\%1 \\%3 goto _..bot,",
613 "\\%6,:_..inc,incr \\\\\\%1 \\%4,goto _..top,:_..bot,_putargs},",
614 "def break goto _..bot, def continue goto _..inc,",
615 "do _for\\v(cmdlevel) \\%1 \\%2 \\%3 \\%4 { \\%5 },_assign _for\\v(cmdlevel)",
616 ""};
617
618 /* This is the FOR macro when the loop variable is itself a macro */
619
620 char *foz_def[] = { "_assign _for\\v(cmdlevel) { _getargs,",
621 "def \\%1 \\feval(\\%2),:_..top,if \\%5 \\%1 \\%3 goto _..bot,",
622 "\\%6,:_..inc,incr \\%1 \\%4,goto _..top,:_..bot,_putargs},",
623 "def break goto _..bot, def continue goto _..inc,",
624 "do _for\\v(cmdlevel) \\%1 \\%2 \\%3 \\%4 { \\%5 },_assign _for\\v(cmdlevel)",
625 ""};
626
627 /* WHILE macro */
628 char *whil_def[] = { "_assign _whi\\v(cmdlevel) {_getargs,",
629 ":_..inc,\\%1,\\%2,goto _..inc,:_..bot,_putargs},",
630 "_def break goto _..bot, _def continue goto _..inc,",
631 "do _whi\\v(cmdlevel),_assign _whi\\v(cmdlevel)",
632 ""};
633
634 /* SWITCH macro */
635 char *sw_def[] = { "_assign _sw_\\v(cmdlevel) {_getargs,",
636 "_forward {\\%1},\\%2,:default,:_..bot,_putargs},_def break goto _..bot,",
637 "do _sw_\\v(cmdlevel),_assign _sw_\\v(cmdlevel)",
638 ""};
639
640 /* XIF macro */
641 char *xif_def[] = {
642 "_assign _if\\v(cmdlevel) {_getargs,\\%1,_putargs},",
643 "do _if\\v(cmdlevel),_assign _if\\v(cmdlevel)",
644 ""};
645
646 /*
647   Variables declared here for use by other ckuus*.c modules.
648   Space is allocated here to save room in ckuusr.c.
649 */
650 #ifdef DCMDBUF
651 struct cmdptr *cmdstk;
652 int
653   *ifcmd  = NULL,
654   *count  = NULL,
655   *iftest = NULL,
656   *intime = NULL,
657   *inpcas = NULL,
658   *takerr = NULL,
659   *merror = NULL;
660 #else
661 struct cmdptr cmdstk[CMDSTKL];
662 int ifcmd[CMDSTKL], count[CMDSTKL], iftest[CMDSTKL], intime[CMDSTKL],
663   inpcas[CMDSTKL], takerr[CMDSTKL], merror[CMDSTKL];
664 #endif /* DCMDBUF */
665
666 /* Macro stack */
667
668 #ifdef COMMENT
669 char *topline = NULL;                   /* Program invocation arg line */
670 char *m_line[MACLEVEL] = { NULL, NULL }; /* Stack of macro invocation lines */
671 #endif /* COMMENT */
672
673 char **m_xarg[MACLEVEL];                /* Pointers to arg vector arrays */
674 int n_xarg[MACLEVEL];                   /* Sizes of arg vector arrays */
675 char *m_arg[MACLEVEL][NARGS];           /* Args of each level */
676 int macargc[MACLEVEL];                  /* Argc of each level */
677 char *macp[MACLEVEL];                   /* Current position in each macro */
678 char *macx[MACLEVEL];                   /* Beginning of each macro def */
679 char *mrval[MACLEVEL];                  /* RETURN value at each level */
680 int lastcmd[MACLEVEL];                  /* Last command at each level */
681 int topargc = 0;                        /* Argc at top level */
682 char **topxarg = NULL;                  /* Argv at top level */
683 char *toparg[MAXARGLIST+2];
684
685 /* Global Variables */
686
687 char *g_var[GVARS+1];                   /* Global \%a..z pointers */
688 extern char varnam[];                   /* \%x variable name buffer */
689
690 /* Arrays -- Dimension must be 'z' - ARRAYBASE + 1 */
691 /* Note: a_link[x] < 0 means no link; >= 0 is a link */
692
693 char **a_ptr[32];                       /* Array pointers, for arrays a-z */
694 int a_dim[32];                          /* Dimensions for each array */
695 int a_link[32];                         /* Link (index of linked-to-array) */
696
697 char **aa_ptr[CMDSTKL][32];             /* Array stack for automatic arrays */
698 int aa_dim[CMDSTKL][32];                /* Dimensions for each array */
699
700 /* INPUT command buffers and variables */
701
702 char * inpbuf = NULL;                   /* Buffer for INPUT and REINPUT */
703 extern char * inpbp;                    /* Global/static pointer to it  */
704 char inchar[2] = { NUL, NUL };          /* Last character that was INPUT */
705 int  incount = 0;                       /* INPUT character count */
706 extern int instatus;                    /* INPUT status */
707 static char * i_text[] = {              /* INPUT status text */
708     "success", "timeout", "interrupted", "internal error", "i/o error"
709 };
710
711 char lblbuf[LBLSIZ];                    /* Buffer for labels */
712
713 #else  /* NOSPL */
714
715 int takerr[MAXTAKE];
716 #endif /* NOSPL */
717
718 static char *prevdir = NULL;
719
720 int pacing = 0;                         /* OUTPUT pacing */
721
722 char *tp;                               /* Temporary buffer pointer */
723
724 int timelimit = 0, asktimer = 0;        /* Timers for time-limited commands */
725
726 #ifdef CK_APC                           /* Application Program Command (APC) */
727 int apcactive = APC_INACTIVE;
728 int apcstatus = APC_OFF;                /* OFF by default everywhere */
729 #ifdef DCMDBUF
730 char *apcbuf;
731 #else
732 char apcbuf[APCBUFLEN];
733 #endif /* DCMDBUF */
734 #endif /* CK_APC */
735
736 extern char pktfil[],
737 #ifdef DEBUG
738   debfil[],
739 #endif /* DEBUG */
740 #ifdef TLOG
741   trafil[],
742 #endif /* TLOG */
743   sesfil[];
744
745 #ifndef NOFRILLS
746 extern int rmailf, rprintf;             /* REMOTE MAIL & PRINT items */
747 extern char optbuf[];
748 #endif /* NOFRILLS */
749
750 extern int noinit;                      /* Flat to skip init file */
751
752 #ifndef NOSPL
753 static struct keytab kcdtab[] = {       /* Symbolic directory names */
754 #ifdef NT
755     { "appdata",  VN_APPDATA,   0 },
756     { "common",   VN_COMMON,    0 },
757     { "desktop",  VN_DESKTOP,   0 },
758 #endif /* NT */
759     { "download", VN_DLDIR,     0 },
760 #ifdef OS2ORUNIX
761     { "exedir",   VN_EXEDIR,    0 },
762 #endif /* OS2ORUNIX */
763     { "home",     VN_HOME,      0 },
764     { "inidir",   VN_INI,       0 },
765 #ifdef UNIX
766     { "lockdir",  VN_LCKDIR,    0 },
767 #endif /* UNIX */
768 #ifdef NT
769     { "my_documents",VN_PERSONAL,  0 },
770     { "personal", VN_PERSONAL,  CM_INV },
771 #endif /* NT */
772     { "startup",  VN_STAR,      0 },
773     { "textdir",  VN_TXTDIR,    0 },
774     { "tmpdir",   VN_TEMP,      0 }
775 };
776 static int nkcdtab = (sizeof(kcdtab) / sizeof(struct keytab));
777 #endif /* NOSPL */
778
779 #ifndef NOSPL
780 _PROTOTYP( VOID freelocal, (int) );
781 _PROTOTYP( static CK_OFF_T expon, (CK_OFF_T, CK_OFF_T) );
782 _PROTOTYP( static CK_OFF_T gcd, (CK_OFF_T, CK_OFF_T) );
783 _PROTOTYP( static CK_OFF_T fact, (CK_OFF_T) );
784
785 int                     /* Initialize macro data structures. */
786 macini() {              /* Allocate mactab and preset the first element. */
787     int i;
788     if (!(mactab = (struct mtab *) malloc(sizeof(struct mtab) * MAC_MAX)))
789       return(-1);
790     mactab[0].kwd = NULL;
791     mactab[0].mval = NULL;
792     mactab[0].flgs = 0;
793     for (i = 0; i < MACLEVEL; i++)
794       localhead[i] = NULL;
795     return(0);
796 }
797 #endif /* NOSPL */
798
799 /*  C M D S R C  --  Returns current command source  */
800
801 /*  0 = top level, 1 = file, 2 = macro, -1 = error (shouldn't happen) */
802
803 /*
804   As of 19 Aug 2000 this routine is obsolete.  The scalar global variable
805   xcmdsrc can be checked instead to save the overhead of a function call.
806 */
807 int
808 cmdsrc() {
809 #ifdef COMMENT
810     return(xcmdsrc);
811 #else
812 #ifndef NOSPL
813     if (cmdlvl == 0)
814       return(0);
815     else if (cmdstk[cmdlvl].src == CMD_MD)
816       return(2);
817     else if (cmdstk[cmdlvl].src == CMD_TF)
818       return(1);
819     else
820       return(-1);
821 #else
822     if (tlevel < 0)
823       return(0);
824     else
825       return(1);
826 #endif /* NOSPL */
827 #endif /* COMMENT */
828 }
829
830 /*  C M D I N I  --  Initialize the interactive command parser  */
831
832 static int cmdinited = 0;               /* Command parser initialized */
833 extern int cmdint;                      /* Interrupts are allowed */
834 #ifdef CK_AUTODL
835 int cmdadl = 1;                         /* Autodownload */
836 #else
837 int cmdadl = 0;
838 #endif /* CK_AUTODL */
839
840 char * k_info_dir = NULL;               /* Where to find text files */
841 #ifdef UNIX
842 static char * txtdir[] = {
843     "/usr/local/doc/",                  /* Linux, SunOS, ... */
844     "/usr/share/lib/",                  /* HP-UX 10.xx... */
845     "/usr/share/doc/",                  /* Other possibilities... */
846     "/usr/local/lib/",                  /* NOTE: Each of these is tried */
847     "/usr/local/share/",                /* as is, and also with a kermit */
848     "/usr/local/share/doc/",            /* subdirectory. */
849     "/usr/local/share/lib/",
850     "/opt/kermit/",                     /* Solaris */
851     "/opt/kermit/doc/",
852     "/opt/",
853     "/usr/doc/",
854     "/doc/",
855     ""
856 };
857 #endif /* UNIX */
858
859 /*
860   lookup() cache to speed up script execution.
861
862   This is a static cache.  Items are stored in decreasing frequency of
863   reference based on statistics from a range of scripts.  This gives
864   better performance than a dynamic cache, which would require a lot more
865   code and also would require system-dependent elements including system
866   calls (e.g. to get subsecond times for entry aging).
867 */
868 #ifdef USE_LUCACHE                      /* Set in ckuusr.h */
869 #define LUCACHE 32                      /* Change this to reduce cache size */
870 int lusize = 0;
871 char * lucmd[LUCACHE];
872 int luval[LUCACHE];
873 int luidx[LUCACHE];
874 struct keytab * lutab[LUCACHE];
875 #endif /* USE_LUCACHE */
876
877 static VOID
878 luinit() {                              /* Initialize lookup() cache */
879     int x, y;
880
881 #ifdef USE_LUCACHE
882     x = lookup(cmdtab,"if",ncmd,&y);
883     lucmd[lusize] = "if";
884     luval[lusize] = x;
885     luidx[lusize] = y;
886     lutab[lusize] = cmdtab;
887     if (++lusize > LUCACHE) return;
888
889     x = lookup(iftab,"not",nif,&y);
890     lucmd[lusize] = "not";
891     luval[lusize] = x;
892     luidx[lusize] = y;
893     lutab[lusize] = iftab;
894     if (++lusize > LUCACHE) return;
895
896     x = lookup(vartab,"cmdlevel",nvars,&y);
897     lucmd[lusize] = "cmdlevel";
898     luval[lusize] = x;
899     luidx[lusize] = y;
900     lutab[lusize] = vartab;
901     if (++lusize > LUCACHE) return;
902
903     x = lookup(cmdtab,"goto",ncmd,&y);
904     lucmd[lusize] = "goto";
905     luval[lusize] = x;
906     luidx[lusize] = y;
907     lutab[lusize] = cmdtab;
908     if (++lusize > LUCACHE) return;
909
910     x = lookup(iftab,">",nif,&y);
911     lucmd[lusize] = ">";
912     luval[lusize] = x;
913     luidx[lusize] = y;
914     lutab[lusize] = iftab;
915     if (++lusize > LUCACHE) return;
916
917     x = lookup(cmdtab,"incr",ncmd,&y);
918     lucmd[lusize] = "incr";
919     luval[lusize] = x;
920     luidx[lusize] = y;
921     lutab[lusize] = cmdtab;
922     if (++lusize > LUCACHE) return;
923
924     x = lookup(cmdtab,"def",ncmd,&y);
925     lucmd[lusize] = "def";
926     luval[lusize] = x;
927     luidx[lusize] = y;
928     lutab[lusize] = cmdtab;
929     if (++lusize > LUCACHE) return;
930
931     x = lookup(cmdtab,"_assign",ncmd,&y);
932     lucmd[lusize] = "_assign";
933     luval[lusize] = x;
934     luidx[lusize] = y;
935     lutab[lusize] = cmdtab;
936     if (++lusize > LUCACHE) return;
937
938     x = lookup(cmdtab,"echo",ncmd,&y);
939     lucmd[lusize] = "echo";
940     luval[lusize] = x;
941     luidx[lusize] = y;
942     lutab[lusize] = cmdtab;
943     if (++lusize > LUCACHE) return;
944
945     x = lookup(fnctab,"eval",nfuncs,&y);
946     lucmd[lusize] = "eval";
947     luval[lusize] = x;
948     luidx[lusize] = y;
949     lutab[lusize] = fnctab;
950     if (++lusize > LUCACHE) return;
951
952     x = lookup(fnctab,"lit",nfuncs,&y);
953     lucmd[lusize] = "lit";
954     luval[lusize] = x;
955     luidx[lusize] = y;
956     lutab[lusize] = fnctab;
957     if (++lusize > LUCACHE) return;
958
959     x = lookup(cmdtab,"do",ncmd,&y);
960     lucmd[lusize] = "do";
961     luval[lusize] = x;
962     luidx[lusize] = y;
963     lutab[lusize] = cmdtab;
964     if (++lusize > LUCACHE) return;
965
966     x = lookup(cmdtab,"_getargs",ncmd,&y);
967     lucmd[lusize] = "_getargs";
968     luval[lusize] = x;
969     luidx[lusize] = y;
970     lutab[lusize] = cmdtab;
971     if (++lusize > LUCACHE) return;
972
973     x = lookup(iftab,"<",nif,&y);
974     lucmd[lusize] = "<";
975     luval[lusize] = x;
976     luidx[lusize] = y;
977     lutab[lusize] = iftab;
978     if (++lusize > LUCACHE) return;
979
980     x = lookup(cmdtab,"_putargs",ncmd,&y);
981     lucmd[lusize] = "_putargs";
982     luval[lusize] = x;
983     luidx[lusize] = y;
984     lutab[lusize] = cmdtab;
985     if (++lusize > LUCACHE) return;
986
987     x = lookup(cmdtab,"asg",ncmd,&y);
988     lucmd[lusize] = "asg";
989     luval[lusize] = x;
990     luidx[lusize] = y;
991     lutab[lusize] = cmdtab;
992     if (++lusize > LUCACHE) return;
993
994     x = lookup(cmdtab,"else",ncmd,&y);
995     lucmd[lusize] = "else";
996     luval[lusize] = x;
997     luidx[lusize] = y;
998     lutab[lusize] = cmdtab;
999 #endif /* USE_LUCACHE */
1000 }
1001
1002 VOID
1003 cmdini() {
1004     int i = 0, x = 0, y = 0, z = 0, skip = 0;
1005     char * p;
1006 #ifdef TTSPDLIST
1007     long * ss = NULL;
1008     extern int nspd;
1009     extern struct keytab * spdtab;
1010 #endif /* TTSPDLIST */
1011
1012 #ifndef NOSPL
1013 /*
1014   On stack to allow recursion!
1015 */
1016     char vnambuf[VNAML];                /* Buffer for variable names */
1017 #endif /* NOSPL */
1018
1019     if (cmdinited)                      /* Already initialized */
1020       return;                           /* Don't do it again */
1021
1022     for (i = 0; i < CMDSTKL; i++)       /* Prompt strings for each */
1023       prstring[i] = NULL;               /* command level */
1024
1025 #ifndef NOCSETS
1026     p = getenv("K_CHARSET");            /* Set default file character set */
1027     if (p) {                            /* from environment */
1028         x = lookup(fcstab,p,nfilc,&y);
1029         if (x > -1)
1030           fcharset = x;
1031     }
1032 #endif /* NOCSETS */
1033
1034     p = getenv("K_INFO_DIRECTORY");     /* Find Kermit info directory */
1035     if (p && *p && strlen(p) <= CKMAXPATH)
1036       makestr(&k_info_dir,p);
1037     if (!k_info_dir) {
1038         p = getenv("K_INFO_DIR");
1039         if (p && *p && strlen(p) <= CKMAXPATH)
1040           makestr(&k_info_dir,p);
1041     }
1042 #ifdef UNIX
1043     if (k_info_dir) {                   /* Look for Kermit docs directory */
1044         if (zchki(k_info_dir) == -2) {
1045             char xbuf[CKMAXPATH+32], *s = "";
1046             if (ckrchar(k_info_dir) != '/')
1047               s = "/";
1048             ckmakmsg(xbuf,CKMAXPATH+32,k_info_dir,s,"ckubwr.txt",NULL);
1049             if (zchki(xbuf) < 0)
1050               makestr(&k_info_dir,NULL);
1051         }
1052     }
1053     if (!k_info_dir) {
1054         char xbuf[CKMAXPATH+32];
1055         int i;
1056         for (i = 0; *(txtdir[i]); i++) {
1057             ckmakmsg(xbuf,CKMAXPATH+32,txtdir[i],"ckubwr.txt",NULL,NULL);
1058             if (zchki(xbuf) > 0) {
1059                 makestr(&k_info_dir,txtdir[i]);
1060                 debug(F110,"k_info_dir 1",k_info_dir,0);
1061                 break;
1062             }
1063             ckmakmsg(xbuf,CKMAXPATH+32,
1064                      txtdir[i],"kermit/","ckubwr.txt",NULL);
1065             if (zchki(xbuf) > 0) {
1066                 ckmakmsg(xbuf,CKMAXPATH+32,txtdir[i],"kermit/",NULL,NULL);
1067                 makestr(&k_info_dir,xbuf);
1068                 debug(F110,"k_info_dir 2",k_info_dir,0);
1069                 break;
1070             }
1071             ckmakmsg(xbuf,CKMAXPATH+32,
1072                      txtdir[i],"ckermit/","ckubwr.txt",NULL);
1073             if (zchki(xbuf) > 0) {
1074                 ckmakmsg(xbuf,CKMAXPATH+32,txtdir[i],"ckermit/",NULL,NULL);
1075                 makestr(&k_info_dir,xbuf);
1076                 debug(F110,"k_info_dir 3",k_info_dir,0);
1077                 break;
1078             }
1079         }
1080         if (k_info_dir) {               /* Make sure it ends with "/" */
1081             if (ckrchar(k_info_dir) != '/') {
1082                 char xbuf[CKMAXPATH+32];
1083                 ckmakmsg(xbuf,CKMAXPATH+32,k_info_dir,"/",NULL,NULL);
1084                 makestr(&k_info_dir,xbuf);
1085             }
1086         }
1087     }
1088 #else
1089 #ifdef OS2
1090     {
1091         char xdir[CKMAXPATH+8], *s = "";
1092         extern char startupdir[];
1093         xdir[0] = NUL;
1094         if (ckrchar(startupdir) != '/')
1095           s = "/";
1096         if (strlen(s) + strlen(startupdir) + 5 < CKMAXPATH + 8 )
1097           ckmakmsg(xdir,CKMAXPATH+8,s,startupdir,"DOC/",NULL);
1098         makestr(&k_info_dir,xdir);
1099     }
1100 #endif /* OS2 */
1101 #endif /* UNIX */
1102
1103 #ifdef TTSPDLIST
1104     if (!spdtab && (ss = ttspdlist())) { /* Get speed list if necessary */
1105         int j, k, m = 0, n;             /* Create sorted keyword table */
1106         char buf[16];
1107         char * p;
1108         if ((spdtab =
1109              (struct keytab *) malloc(sizeof(struct keytab) * ss[0]))) {
1110             for (i = 1; i <= ss[0]; i++) { /* ss[0] = number of elements */
1111                 if (ss[i] < 1L) break;     /* Shouldn't happen */
1112                 buf[0] = NUL;              /* Make string */
1113                 sprintf(buf,"%ld",ss[i]);  /* SAFE */
1114                 if (ss[i] == 8880L)
1115                   ckstrncpy(buf,"75/1200",sizeof(buf));
1116                 if (ss[i] == 134L)
1117                   ckstrncat(buf,".5",16);
1118                 n = strlen(buf);
1119                 if ((n > 0) && (p = (char *)malloc(n+1))) {
1120                     if (m > 0) {        /* Have at least one in list */
1121                         for (j = 0;     /* Find slot */
1122                              j < m && strcmp(buf,spdtab[j].kwd) > 0;
1123                              j++
1124                              )
1125                           ;
1126                         if (j < m) {    /* Must insert */
1127                             for (k = m-1; k >= j; k--) { /* Move others down */
1128                                 spdtab[k+1].kwd = spdtab[k].kwd;
1129                                 spdtab[k+1].flgs = spdtab[k].flgs;
1130                                 spdtab[k+1].kwval = spdtab[k].kwval;
1131                             }
1132                         }
1133                     } else              /* First one */
1134                       j = 0;
1135                     ckstrncpy(p,buf,n+1); /* Add new speed */
1136                     spdtab[j].kwd = p;
1137                     spdtab[j].flgs = 0;
1138                     spdtab[j].kwval = (int) ss[i] / 10;
1139                     m++;                /* Count this one */
1140                 }
1141             }
1142         }
1143         nspd = m;
1144     }
1145 #endif /* TTSPDLIST */
1146
1147 #ifndef NOSPL
1148     /* Allocate INPUT command buffer */
1149     if (!inpbuf) {
1150         if (!(inpbuf = (char *) malloc(INPBUFSIZ+8)))
1151           fatal("cmdini: no memory for INPUT buffer");
1152     }
1153     for (x = 0; x < INPBUFSIZ; x++)     /* Initialize it */
1154       inpbuf[x] = NUL;
1155     inpbp = inpbuf;                     /* Initialize pointer */
1156     inbufsize = INPBUFSIZ;              /* and size. */
1157 #endif /* NOSPL */
1158
1159 #ifdef DCMDBUF
1160     if (cmsetup() < 0) fatal("Can't allocate command buffers!");
1161
1162 #ifndef NOSPL
1163     /* Allocate command stack allowing command parser to call itself */
1164
1165     if (!(cmdstk = (struct cmdptr *) malloc(sizeof(struct cmdptr)*CMDSTKL)))
1166       fatal("cmdini: no memory for cmdstk");
1167     if (!(ifcmd = (int *) malloc(sizeof(int)*CMDSTKL)))
1168       fatal("cmdini: no memory for ifcmd");
1169     if (!(count = (int *) malloc(sizeof(int)*CMDSTKL)))
1170       fatal("cmdini: no memory for count");
1171     if (!(iftest = (int *) malloc(sizeof(int)*CMDSTKL)))
1172       fatal("cmdini: no memory for iftest");
1173     if (!(intime = (int *) malloc(sizeof(int)*CMDSTKL)))
1174       fatal("cmdini: no memory for intime");
1175     if (!(inpcas = (int *) malloc(sizeof(int)*CMDSTKL)))
1176       fatal("cmdini: no memory for inpcas");
1177     if (!(takerr = (int *) malloc(sizeof(int)*CMDSTKL)))
1178       fatal("cmdini: no memory for takerr");
1179     if (!(merror = (int *) malloc(sizeof(int)*CMDSTKL)))
1180       fatal("cmdini: no memory for merror");
1181     if (!(xquiet = (int *) malloc(sizeof(int)*CMDSTKL)))
1182       fatal("cmdini: no memory for xquiet");
1183     if (!(xvarev = (int *) malloc(sizeof(int)*CMDSTKL)))
1184       fatal("cmdini: no memory for xvarev");
1185     if (!kermrc)
1186       if (!(kermrc = (char *) malloc(KERMRCL+1)))
1187         fatal("cmdini: no memory for kermrc");
1188 #ifdef CK_APC
1189 /* Application Program Command buffer */
1190     if (!(apcbuf = malloc(APCBUFLEN + 1)))
1191         fatal("cmdini: no memory for apcbuf");
1192 #endif /* CK_APC */
1193 #endif /* NOSPL */
1194
1195 /* line[] and tmpbuf[] are the two string buffers used by the command parser */
1196
1197     if (!(line = malloc(LINBUFSIZ + 1)))
1198         fatal("cmdini: no memory for line");
1199     if (!(tmpbuf = malloc(LINBUFSIZ + 1)))
1200         fatal("cmdini: no memory for tmpbuf");
1201 #endif /* DCMDBUF */
1202
1203 #ifndef NOSPL
1204 #ifdef CK_MINPUT
1205     {                                   /* Initialize MINPUT pointers */
1206         int i;
1207         extern char *ms[];
1208         for (i = 0; i < MINPMAX; i++)
1209           ms[i] = NULL;
1210     }
1211 #endif /* CK_MINPUT */
1212
1213     if (macini() < 0)                   /* Allocate macro buffers */
1214       fatal("Can't allocate macro buffers!");
1215
1216     ifcmd[0] = 0;                       /* Command-level related variables. */
1217     iftest[0] = 0;                      /* Initialize variables at top level */
1218     count[0] = 0;                       /* of stack... */
1219     intime[0] = 0;
1220     inpcas[0] = 0;
1221     takerr[0] = 0;
1222     merror[0] = 0;
1223     xquiet[0] = quiet;
1224     xvarev[0] = vareval;
1225 #endif /* NOSPL */
1226
1227 #ifndef NOSPL
1228     cmdlvl = 0;                         /* Initialize the command stack */
1229     xcmdsrc = CMD_KB;
1230     cmdstk[cmdlvl].src = CMD_KB;        /* Source is console */
1231     cmdstk[cmdlvl].lvl = 0;             /* Level is 0 */
1232     cmdstk[cmdlvl].ccflgs = 0;          /* No flags */
1233 #endif /* NOSPL */
1234
1235     tlevel = -1;                        /* Take file level = keyboard */
1236     for (i = 0; i < MAXTAKE; i++)       /* Initialize command file names */
1237       tfnam[i] = NULL;
1238
1239     cmsetp(ckprompt);                   /* Set up C-Kermit's prompt */
1240                                         /* Can't set IKSD prompt here since */
1241                                         /* we do not yet know if we are IKSD */
1242 #ifndef NOSPL
1243
1244     initmac();                          /* Initialize macro table */
1245
1246 /* Predefine built-in one-line macros */
1247
1248     addmac("ibm-linemode",m_ibm);       /* IBM-LINEMODE */
1249     addmac("fatal",m_fat);              /* FATAL macro */
1250     y = addmac("fast",m_fast);          /* FAST macro */
1251     addmac("cautious",m_cautious);      /* CAUTIOUS macro */
1252     addmac("robust",m_robust);          /* ROBUST macro */
1253 #ifdef OS2
1254     addmac("manual",m_manual);          /* MANUAL macro */
1255 #endif /* OS2 */
1256 #ifdef VMS
1257     addmac("purge",m_purge);            /* PURGE macro */
1258 #endif /* VMS */
1259
1260 /*
1261   Predefine built-in multiline macros; these are top-level commands
1262   that are implemented internally as macros.  NOTE: When adding a new
1263   one of these, remember to update the END and RETURN commands to
1264   account for it, or else END and RETURN from within it won't work right.
1265 */
1266     x = addmmac("_forx",for_def);       /* FOR macro */
1267     if (x > -1) mactab[x].flgs = CM_INV;
1268     x = addmmac("_forz",foz_def);       /* Other FOR macro */
1269     if (x > -1) mactab[x].flgs = CM_INV;
1270     x = addmmac("_xif",xif_def);        /* XIF macro */
1271     if (x > -1) mactab[x].flgs = CM_INV;
1272     x = addmmac("_while",whil_def);     /* WHILE macro */
1273     if (x > -1) mactab[x].flgs = CM_INV;
1274     x = addmmac("_switx",sw_def);       /* SWITCH macro */
1275     if (x > -1) mactab[x].flgs = CM_INV;
1276
1277 /* Fill in command-line argument vector */
1278
1279     sprintf(vnambuf,"\\&@[%d]",xargs);  /* SAFE */
1280     if (inserver) {                     /* But hidden in IKSD */
1281         y = -1;
1282         xargs = 0;
1283     } else
1284       y = arraynam(vnambuf,&x,&z);      /* goes in array \&@[] */
1285
1286     tmpbuf[0] = NUL;
1287     if (y > -1) {
1288         int j = -1;
1289         int yy = 0;
1290         dclarray((char)x,z);            /* Declare the array */
1291 #ifndef NOTAKEARGS
1292         /* Macro argument vector */
1293         sprintf(vnambuf,"\\&_[%d]",z);  /* SAFE */
1294         yy = arraynam(vnambuf,&x,&z);   /* goes in array \&_[] */
1295         if (yy > -1)                    /* Name is OK */
1296           dclarray((char)x,z);          /* Declare the array */
1297 #endif /* NOTAKEARGS */
1298         skip = 0;
1299         for (i = 0; i < xargs; i++) {   /* Fill the arrays */
1300             sprintf(vnambuf,"\\&@[%d]",i); /* SAFE */
1301             addmac(vnambuf,xargv[i]);
1302             if (cfilef && i == 0)
1303               continue;
1304 #ifdef KERBANG
1305             if (skip) {
1306                 j = 0;
1307                 skip = 0;
1308                 continue;
1309             }
1310 #endif /* KERBANG */
1311             if (j < 0 &&                /* Assign items after "=" or "--"*/
1312                 (!strcmp(xargv[i],"=") || !strcmp(xargv[i],"--"))
1313                 ) {
1314                 j = 0;                  /* to \%1..\%9 */
1315 #ifdef KERBANG
1316             } else if (j < 0 &&
1317                        (!strcmp(xargv[i],"+") ||
1318                         !strncmp(xargv[i],"+ ",2) ||
1319                         !strncmp(xargv[i],"+\t",2))
1320                         ) {
1321                 skip = 1;
1322                 continue;
1323 #endif /* KERBANG */
1324             } else if (j > -1) {
1325                 j++;
1326                 if (j <= 9) {
1327                     vnambuf[0] = '\\';
1328                     vnambuf[1] = '%';
1329                     vnambuf[2] = (char)(j+'0');
1330                     vnambuf[3] = NUL;
1331                     addmac(vnambuf,xargv[i]);
1332                 }
1333                 if (yy > -1) {
1334                     char c, * p;
1335                     int flag = 0;
1336                     p = xargv[i];
1337                     makestr(&(toparg[j]),p);
1338                     while ((c = *p++)) { if (c == SP) { flag++; break; } }
1339                     if (flag)
1340                       ckstrncat(tmpbuf,"\"",TMPBUFSIZ);
1341                     ckstrncat(tmpbuf,xargv[i],TMPBUFSIZ);
1342                     if (flag)
1343                       ckstrncat(tmpbuf,"\"",TMPBUFSIZ);
1344                     ckstrncat(tmpbuf," ",TMPBUFSIZ);
1345                 }
1346             }
1347         }
1348         if (cfilef) {
1349             addmac("\\%0",cmdfil);
1350             if (yy > -1)
1351               makestr(&(toparg[0]),cmdfil);
1352         } else {
1353             addmac("\\%0",xargv[0]);
1354             if (yy > -1)
1355               makestr(&(toparg[0]),xargv[0]);
1356         }
1357         if (yy > -1) {
1358             topargc = (j < 0) ? 1 : j + 1;
1359             topxarg = toparg;
1360 #ifdef COMMENT
1361             /* This needs work */
1362             if (!cfilef)
1363               makestr(&topline,tmpbuf);
1364 #endif /* COMMENT */
1365         } else {
1366             topargc = 0;
1367             topxarg = NULL;
1368         }
1369         a_dim[0] = topargc - 1;
1370         a_ptr[0] = topxarg;
1371         debug(F111,"a_dim[0]","A",a_dim[0]);
1372     }
1373     *vnambuf = NUL;
1374 #endif /* NOSPL */
1375
1376     luinit();                           /* Initialize lookup() cache */
1377
1378 /* Get our home directory now.  This needed in lots of places. */
1379
1380     cmdinited = 1;
1381 }
1382
1383 #ifdef NT
1384 _PROTOTYP(char * GetAppData,(int));
1385 #endif /* NT */
1386
1387 VOID
1388 doinit() {
1389 #ifdef CKROOT
1390 extern int ckrooterr;
1391 #endif /* CKROOT */
1392     int x = 0, ok = 0;
1393 #ifdef OS2
1394     char * ptr = 0;
1395 #endif /* OS2 */
1396
1397     if (!cmdinited)
1398       cmdini();
1399
1400 #ifdef MAC
1401     return;                             /* Mac Kermit has no init file */
1402
1403 #else /* !MAC */
1404
1405 /* If skipping init file ('-Y' on Kermit command line), return now. */
1406
1407     if (noinit) {
1408         kermrc[0] = '\0';
1409         inidir[0] = '\0';
1410 /*
1411   But returning from here results in inidir[] never being set to anything.
1412   Instead it should be set to wherever the init file *would* have been
1413   executed from.  So this bit of code should be removed, and then we should
1414   sprinkle "if (noinit)" tests throughout the following code until we have
1415   set inidir[], and then return without actually taking the init file.
1416 */
1417         return;
1418     }
1419
1420 #ifdef OS2
1421 /*
1422   The -y init file must be fully specified or in the current directory.
1423   KERMRC is looked for via INIT, DPATH and PATH in that order.  Finally, our
1424   own executable file path is taken and the .EXE suffix is replaced by .INI
1425   and this is tried as the initialization file.
1426 */
1427 #ifdef CK_LOGIN
1428     debug(F101,"doinit inserver","",inserver);
1429     debug(F101,"doinit isguest","",isguest);
1430     debug(F110,"doinit anonfile",anonfile,0);
1431
1432     if (isguest && anonfile) {
1433       ckstrncpy(line, anonfile, LINBUFSIZ+1);
1434     } else
1435 #endif /* CK_LOGIN */
1436       if (rcflag) {
1437           ckstrncpy(line,kermrc,LINBUFSIZ+1);
1438 #ifdef CK_LOGIN
1439       } else if (inserver) {
1440           char * appdata = NULL;
1441 #ifdef NT
1442           appdata = GetAppData(1);
1443           if ( appdata ) {
1444               ckmakmsg(line,LINBUFSIZ+1,appdata,
1445                         "Kermit 95/k95.ini",NULL,NULL);
1446               if ( zchki(line) < 0 )
1447                   line[0] = '\0';
1448           }
1449           if (line[0] == 0) {
1450               appdata = GetAppData(0);
1451               if ( appdata ) {
1452                   ckmakmsg(line,LINBUFSIZ+1,appdata,
1453                             "Kermit 95/k95.ini",NULL,NULL);
1454                   if ( zchki(line) < 0 )
1455                       line[0] = '\0';
1456               }
1457           }
1458 #endif /* NT */
1459           if (line[0] == 0) {
1460               appdata = zhome();
1461               if ( appdata ) {
1462                   ckmakmsg(line,LINBUFSIZ+1,appdata,
1463 #ifdef NT
1464                           "k95.ini",
1465 #else /* NT */
1466                           "k2.ini",
1467 #endif /* NT */
1468                            NULL,NULL);
1469                   if ( zchki(line) < 0 )
1470                       line[0] = '\0';
1471               }
1472           }
1473           debug(F110,"doinit inserver inifile",line,0);
1474 #endif /* CK_LOGIN */
1475     } else {
1476         char * env = 0;
1477 #ifdef NT
1478         env = getenv("K95.KSC");
1479 #else
1480         env = getenv("K2.KSC");
1481 #endif /* NT */
1482         if (!env) {
1483 #ifdef NT
1484             env = getenv("K95.INI");
1485 #else
1486             env = getenv("K2.INI");
1487 #endif /* NT */
1488         }
1489         if (!env)
1490           env = getenv("CKERMIT.INI");
1491         if (!env)
1492           env = getenv("CKERMIT_INI");
1493         line[0] = '\0';
1494
1495         debug(F110,"doinit env",env,0);
1496         if (env)
1497           ckstrncpy(line,env,LINBUFSIZ+1);
1498
1499 #ifdef NT
1500         if (line[0] == 0) {
1501             env = GetAppData(1);
1502             if ( env ) {
1503                 ckmakmsg(line,LINBUFSIZ+1,env,"Kermit 95/k95.ini",NULL,NULL);
1504                 if ( zchki(line) < 0 )
1505                     line[0] = '\0';
1506             }
1507         }
1508         if (line[0] == 0) {
1509             env = GetAppData(0);
1510             if ( env ) {
1511                 ckmakmsg(line,LINBUFSIZ+1,env,"Kermit 95/k95.ini",NULL,NULL);
1512                 if ( zchki(line) < 0 )
1513                     line[0] = '\0';
1514             }
1515         }
1516 #endif /* NT */
1517
1518         if (line[0] == 0) {
1519             env = zhome();
1520             if ( env ) {
1521                 ckmakmsg(line,LINBUFSIZ+1,env,
1522 #ifdef NT
1523                           "k95.ini",
1524 #else /* NT */
1525                           "k2.ini",
1526 #endif /* NT */
1527                           NULL,NULL);
1528                 if ( zchki(line) < 0 )
1529                     line[0] = '\0';
1530             }
1531         }
1532
1533         if (line[0] == 0)
1534           _searchenv(kermrc,"INIT",line);
1535         if (line[0] == 0)
1536           _searchenv(kermrc,"DPATH",line);
1537         if (line[0] == 0)
1538           _searchenv(kermrc,"PATH",line);
1539         if (line[0] == 0) {
1540             char *pgmptr = GetLoadPath();
1541             if (pgmptr && strlen(pgmptr) < LINBUFSIZ-8) {
1542                 lp = strrchr(pgmptr, '\\');
1543                 if (lp) {
1544                     strncpy(line, pgmptr, lp - pgmptr);
1545 #ifdef NT
1546                     strcpy(line + (lp - pgmptr), "/k95.ini");
1547 #else /* NT */
1548                     strcpy(line + (lp - pgmptr), "/k2.ini");
1549 #endif /* NT */
1550                 } else {
1551                     lp = strrchr(pgmptr, '.');
1552                     if (lp) {
1553                         strncpy(line, pgmptr, lp - pgmptr);
1554                         strcpy(line + (lp - pgmptr), ".ini");
1555                     }
1556                 }
1557             }
1558         }
1559     }
1560
1561 #ifdef CKROOT
1562     if (!zinroot(line)) {
1563         debug(F110,"doinit setroot violation",line,0);
1564         return;
1565     }
1566 #endif /* CKROOT */
1567
1568     debug(F110,"doinit fopen()",line,0);
1569     if ((tfile[0] = fopen(line,"r")) != NULL) {
1570         ok = 1;
1571         tlevel = 0;
1572         tfline[tlevel] = 0;
1573         if (tfnam[tlevel] = malloc(strlen(line)+1))
1574           strcpy(tfnam[tlevel],line);   /* safe */
1575 #ifndef NOSPL
1576         cmdlvl++;
1577         xcmdsrc = CMD_TF;
1578         cmdstk[cmdlvl].src = CMD_TF;
1579         cmdstk[cmdlvl].lvl = tlevel;
1580         cmdstk[cmdlvl].ccflgs = 0;
1581         ifcmd[cmdlvl] = 0;
1582         iftest[cmdlvl] = 0;
1583         count[cmdlvl] =  count[cmdlvl-1]; /* Inherit from previous level */
1584         intime[cmdlvl] = intime[cmdlvl-1];
1585         inpcas[cmdlvl] = inpcas[cmdlvl-1];
1586         takerr[cmdlvl] = takerr[cmdlvl-1];
1587         merror[cmdlvl] = merror[cmdlvl-1];
1588         xquiet[cmdlvl] = quiet;
1589         xvarev[cmdlvl] = vareval;
1590 #endif /* NOSPL */
1591         debug(F110,"doinit init file",line,0);
1592     } else {
1593         debug(F100,"doinit no init file","",0);
1594     }
1595     ckstrncpy(kermrc,line,KERMRCL);
1596     for (ptr = kermrc; *ptr; ptr++)     /* Convert backslashes to slashes */
1597        if (*ptr == '\\')
1598          *ptr = '/';
1599 #else /* not OS2 */
1600     lp = line;
1601     lp[0] = '\0';
1602     debug(F101,"doinit rcflag","",rcflag);
1603 #ifdef GEMDOS
1604     zkermini(line, rcflag, kermrc);
1605 #else
1606 #ifdef VMS
1607     {
1608         int x;
1609         x = zkermini(line,LINBUFSIZ,kermrc);
1610         debug(F111,"CUSTOM zkermini",line,x);
1611         if (x == 0)
1612           line[0] = NUL;
1613     }
1614 #else /* not VMS */
1615 #ifdef CK_LOGIN
1616     debug(F101,"doinit isguest","",isguest);
1617     if (isguest)
1618       ckstrncpy(lp, anonfile ? anonfile : kermrc, LINBUFSIZ);
1619     else
1620 #endif /* CK_LOGIN */
1621       if (rcflag) {                     /* If init file name from cmd line */
1622           ckstrncpy(lp,kermrc,LINBUFSIZ); /* use it, */
1623       } else {                          /* otherwise... */
1624 #ifdef CK_INI_A                         /* If we've a system-wide init file */
1625           /* And it takes precedence over the user's... */
1626           ckstrncpy(lp,CK_SYSINI,KERMRCL); /* Use it */
1627           if (zchki(lp) < 0) {          /* (if it exists...) */
1628 #endif /* CK_INI_A */
1629               char * homdir;
1630               char * env = 0;
1631               line[0] = NUL;
1632
1633               /* Add support for environment variable */
1634               env = getenv("CKERMIT.INI");
1635               if (!env)
1636                 env = getenv("CKERMIT_INI");
1637               if (env)
1638                 ckstrncpy(lp,env,KERMRCL);
1639
1640               if (lp[0] == 0) {
1641                   homdir = zhome();
1642                   if (homdir) {         /* Home directory for init file. */
1643                       ckstrncpy(lp,homdir,KERMRCL);
1644 #ifdef STRATUS
1645                       ckstrncat(lp,">",KERMRCL);/* VOS dirsep */
1646 #else
1647                       if (lp[0] == '/') ckstrncat(lp,"/",KERMRCL);
1648 #endif /* STRATUS */
1649                   }
1650                   ckstrncat(lp,kermrc,KERMRCL);/* Append default file name */
1651               }
1652 #ifdef CK_INI_A
1653           }
1654 #endif /* CK_INI_A */
1655 #ifdef CK_INI_B                         /* System-wide init defined? */
1656           /* But user's ini file takes precedence */
1657           if (zchki(lp) < 0)            /* If user doesn't have her own, */
1658             ckstrncpy(lp,CK_SYSINI,KERMRCL); /* use system-wide one. */
1659 #endif /* CK_INI_B */
1660       }
1661 #endif /* VMS */
1662 #endif /* GEMDOS */
1663
1664 #ifdef AMIGA
1665     reqoff();                           /* Disable requestors */
1666 #endif /* AMIGA */
1667
1668 #ifdef USE_CUSTOM
1669     /* If no init file was found, execute the customization file */
1670     debug(F111,"CUSTOM 1",line,rcflag);
1671     if ((!line[0] || zchki(line) < 0) && !rcflag) {
1672         int x;
1673 #ifdef OS2
1674         x = ckmakestr(line,LINBUFSIZ,GetAppData(1),"/","K95CUSTOM.INI",NULL);
1675         debug(F111,"CUSTOM 2",line,x);
1676         if (zchki(line) < 0) {
1677             x = ckmakestr(line,LINBUFSIZ,GetAppData(0),"/","K95USER.INI",NULL);
1678             debug(F111,"CUSTOM 3",line,x);
1679         }
1680 #else  /* OS2 */
1681         x = ckstrncpy(line,zhome(),LINBUFSIZ);
1682 #ifndef VMS
1683         /* VMS zhome() returns "SYS$LOGIN:" */
1684         if (line[x-1] != DIRSEP) {
1685             line[x++] = DIRSEP;
1686             line[x] = NUL;
1687         }
1688 #endif /* VMS */
1689         x = ckstrncat(line,MYCUSTOM,LINBUFSIZ);
1690         debug(F111,"CUSTOM 4",line,x);
1691 #endif /* OS2 */
1692     }
1693     debug(F110,"CUSTOM 5",line,0);
1694 #endif /* USE_CUSTOM */
1695
1696 #ifdef CKROOT
1697     if (!zinroot(line)) {
1698         debug(F110,"doinit setroot violation",line,0);
1699         return;
1700     }
1701 #endif /* CKROOT */
1702
1703     debug(F110,"doinit ini file is",line,0);
1704     if ((tfile[0] = fopen(line,"r")) != NULL) { /* Try to open init file. */
1705         ok = 1;
1706         tlevel = 0;
1707         tfline[tlevel] = 0;
1708         if ((tfnam[tlevel] = malloc(strlen(line)+1)))
1709           strcpy(tfnam[tlevel],line);   /* safe */
1710
1711         ckstrncpy(kermrc,line,KERMRCL);
1712
1713 #ifndef NOSPL
1714         cmdlvl++;
1715         ifcmd[cmdlvl] = 0;
1716         iftest[cmdlvl] = 0;
1717         count[cmdlvl] =  count[cmdlvl-1]; /* Inherit from previous level */
1718         intime[cmdlvl] = intime[cmdlvl-1];
1719         inpcas[cmdlvl] = inpcas[cmdlvl-1];
1720         takerr[cmdlvl] = takerr[cmdlvl-1];
1721         merror[cmdlvl] = merror[cmdlvl-1];
1722         xquiet[cmdlvl] = quiet;
1723         xvarev[cmdlvl] = vareval;
1724         debug(F101,"doinit open ok","",cmdlvl);
1725         xcmdsrc = CMD_TF;
1726         cmdstk[cmdlvl].src = CMD_TF;
1727         cmdstk[cmdlvl].lvl = tlevel;
1728         cmdstk[cmdlvl].ccflgs = 0;
1729 #endif /* NOSPL */
1730     } else if (rcflag) {
1731         /* Print an error message only if a specific file was asked for. */
1732         printf("?%s - %s\n", ck_errstr(), line);
1733     }
1734
1735 #ifdef datageneral
1736 /* If CKERMIT.INI not found in home directory, look in searchlist */
1737     if (/* homdir && */ (tlevel < 0)) {
1738         ckstrncpy(lp,kermrc,LINBUFSIZ);
1739         if ((tfile[0] = fopen(line,"r")) != NULL) {
1740             ok = 1;
1741             tlevel = 0;
1742             tfline[tlevel] = 0;
1743             if (tfnam[tlevel] = malloc(strlen(line)+1))
1744               strcpy(tfnam[tlevel],line); /* safe */
1745 #ifndef NOSPL
1746             cmdlvl++;
1747             xcmdsrc = CMD_TF;
1748             cmdstk[cmdlvl].src = CMD_TF;
1749             cmdstk[cmdlvl].lvl = tlevel;
1750             cmdstk[cmdlvl].ccflgs = 0;
1751             ifcmd[cmdlvl] = 0;
1752             iftest[cmdlvl] = 0;
1753             count[cmdlvl] =  count[cmdlvl-1]; /* Inherit from previous level */
1754             intime[cmdlvl] = intime[cmdlvl-1];
1755             inpcas[cmdlvl] = inpcas[cmdlvl-1];
1756             takerr[cmdlvl] = takerr[cmdlvl-1];
1757             merror[cmdlvl] = merror[cmdlvl-1];
1758             xquiet[cmdlvl] = quiet;
1759             xvarev[cmdlvl] = vareval;
1760 #endif /* NOSPL */
1761         }
1762     }
1763 #endif /* datageneral */
1764
1765 #ifdef AMIGA                            /* Amiga... */
1766     reqpop();                           /* Restore requestors */
1767 #endif /* AMIGA */
1768 #endif /* OS2 */
1769 #endif /* MAC */
1770
1771     /* Assign value to inidir */
1772
1773     if (!ok) {
1774         inidir[0] = NUL;
1775     } else {
1776         ckstrncpy(inidir, kermrc, CCHMAXPATH);
1777         x = strlen(inidir);
1778         if (x > 0) {
1779             int i;
1780             for (i = x - 1; i > 0; i-- ) {
1781                 if (ISDIRSEP(inidir[i])) {
1782                     inidir[i+1] = NUL;
1783                     break;
1784                 }
1785             }
1786         }
1787 #ifdef NT
1788         GetShortPathName(inidir,inidir,CCHMAXPATH);
1789 #endif /* NT */
1790     }
1791 }
1792
1793 VOID
1794 doiksdinit() {
1795 #ifdef CK_SSL
1796     /* IKSD doesn't request client certs */
1797     ssl_verify_flag = SSL_VERIFY_NONE;
1798 #endif /* CK_SSL */
1799
1800     if (!cmdinited)
1801       cmdini();
1802
1803 #ifdef IKSDCONF
1804 #ifdef OS2
1805     line[0] = '\0';
1806     _searchenv(iksdconf,"INIT",line);
1807     if (line[0] == 0)
1808       _searchenv(iksdconf,"DPATH",line);
1809     if (line[0] == 0)
1810       _searchenv(iksdconf,"PATH",line);
1811     if (line[0] == 0) {
1812         char *pgmptr = GetLoadPath();
1813         if (pgmptr && strlen(pgmptr) < LINBUFSIZ-8) {
1814             lp = strrchr(pgmptr, '\\');
1815             if (lp) {
1816                 strncpy(line, pgmptr, lp - pgmptr);
1817                 strcpy(line + (lp - pgmptr), "\\");
1818                 strcpy(line + (lp - pgmptr + 1), iksdconf);
1819             } else {
1820                 lp = strrchr(pgmptr, '.');
1821                 if (lp) {
1822                     strncpy(line, pgmptr, lp - pgmptr);
1823                     strcpy(line + (lp - pgmptr), ".ksc");
1824                 }
1825             }
1826         }
1827     }
1828     debug(F110,"doiksdinit() line",line,0);
1829     tfile[0] = fopen(line,"r");
1830 #else /* OS2 */
1831     tfile[0] = fopen(iksdconf,"r");
1832 #endif /* OS2 */
1833     if (tfile[0] != NULL) {
1834         tlevel = 0;
1835         tfline[tlevel] = 0;
1836 #ifdef OS2
1837         if (tfnam[tlevel] = malloc(strlen(line)+1))
1838           strcpy(tfnam[tlevel],line);
1839 #else /* OS2 */
1840         if ((tfnam[tlevel] = malloc(strlen(iksdconf)+1)))
1841           strcpy(tfnam[tlevel],iksdconf);
1842 #endif /* OS2 */
1843 #ifndef NOSPL
1844         cmdlvl++;
1845         xcmdsrc = CMD_TF;
1846         cmdstk[cmdlvl].src = CMD_TF;
1847         cmdstk[cmdlvl].lvl = tlevel;
1848         cmdstk[cmdlvl].ccflgs = 0;
1849         ifcmd[cmdlvl]  = 0;
1850         iftest[cmdlvl] = 0;
1851         count[cmdlvl]  = count[cmdlvl-1]; /* Inherit from previous level */
1852         intime[cmdlvl] = intime[cmdlvl-1];
1853         inpcas[cmdlvl] = inpcas[cmdlvl-1];
1854         takerr[cmdlvl] = takerr[cmdlvl-1];
1855         merror[cmdlvl] = merror[cmdlvl-1];
1856         xquiet[cmdlvl] = quiet;
1857         xvarev[cmdlvl] = vareval;
1858 #endif /* NOSPL */
1859         debug(F110,"doiksdinit file ok",tfnam[tlevel],0);
1860     } else {
1861         debug(F110,"doiksdinit open failed",tfnam[tlevel],0);
1862     }
1863 #endif /* IKSDCONF */
1864 }
1865
1866 #ifndef NOSPL
1867 /*
1868   G E T N C M
1869
1870   Get next command from current macro definition.  Command is copied
1871   into string pointed to by argument s, max length n.   Returns:
1872    0 if a string was copied;
1873   -1 if there was no string to copy.
1874 */
1875 int
1876 getncm(s,n) char *s; int n; {
1877     int y = 0;                          /* Character counter */
1878     int quote = 0;
1879     int kp = 0;                         /* Brace up-down counter */
1880     int pp = 0;                         /* Parenthesis up-down counter */
1881 #ifndef NODQMACRO
1882     int dq = 0;                         /* Doublequote counter */
1883 #endif /* NODQMACRO */
1884     char *s2;                           /* Copy of destination pointer */
1885
1886     s2 = s;                             /* Initialize string pointers */
1887     *s = NUL;                           /* and destination buffer */
1888
1889     /* debug(F010,"getncm entry",macp[maclvl],0); */
1890
1891     for (y = 0;                         /* Loop for n bytes max */
1892          macp[maclvl] && *macp[maclvl] && y < n;
1893          y++, s++, macp[maclvl]++) {
1894
1895         *s = *macp[maclvl];             /* Get next char from macro def */
1896
1897 #ifndef COMMENT
1898 /*
1899   This is to allow quoting of parentheses, commas, etc, in function
1900   arguments, but it breaks just about everything else.  DON'T REMOVE THIS
1901   COMMENT!  (Otherwise you'll wind up adding the same code again and breaking
1902   everything again.)  <-- The preceding warning should be obsolete since the
1903   statements below have been fixed, but in case of fire, remove the "n" from
1904   the <#>ifndef above.  NEW WARNING: code added 12 Apr 2002 to exempt the
1905   opening brace in \{nnn} from being treated as a quoted brace.
1906 */
1907         if (!quote && *s == CMDQ) {
1908             quote = 1;
1909             continue;
1910         }
1911         if (quote) {
1912             int notquote = 0;
1913             quote = 0;
1914             if (*s == '{') {            /* Check for \{nnn} (8.0.203) */
1915                 char c, * p;
1916                 p = macp[maclvl] + 1;
1917                 while ((c = *p++)) {
1918                     if (isdigit(c))
1919                       continue;
1920                     else if (c == '}') {
1921                         notquote++;
1922                         break;
1923                     } else {
1924                         break;
1925                     }
1926                 }
1927             }
1928             if (notquote == 0)
1929               continue;
1930         }
1931 #endif /* COMMENT */
1932
1933 /*
1934   Allow braces around macro definition to prevent commas from being turned to
1935   end-of-lines and also treat any commas within parens as text so that
1936   multiple-argument functions won't cause the command to break prematurely.
1937   19 Oct 2001: Similar treatment was added for doublequotes, so
1938
1939      define foo { echo "one, two, three" }
1940
1941   would work as expected.  This doesn't seem to have broken anything but
1942   if something comes up later, rebuild with NODQMACRO defined.
1943 */
1944         if (*s == '{') kp++;            /* Count braces */
1945         if (*s == '}' && kp > 0) kp--;
1946         if (*s == '(') pp++;            /* Count parentheses. */
1947         if (*s == ')' && pp > 0) pp--;
1948 #ifndef NODQMACRO
1949 #ifndef COMMENT
1950         /* Too many false positives */
1951         /* No, not really -- this is indeed the best we can do */
1952         /* Reverted to this method Sun May 11 18:43:45 2003 */
1953         if (*s == '"') dq = 1 - dq;     /* Account for doublequotes */
1954 #else  /* Fri Apr  4 13:21:29 2003 */
1955         /* The code below breaks the SWITCH statement */
1956         /* There is no way to make this work -- it would require */
1957         /* building in all the knowledge of command parser. */
1958         if (dblquo && (*s == '"')) {    /* Have doublequote */
1959             if (dq == 1) {              /* Close quote only if... */
1960                 if ((*(macp[maclvl]+1) == SP) || /* followed by space or... */
1961                     (!*(macp[maclvl]+1)) ||      /* at end or ... */
1962                     /* Next char is command separator... */
1963                     /* Sun May 11 17:24:12 2003 */
1964                     (kp < 1 && pp < 1 && (*(macp[maclvl]+1) == ','))
1965                     )                
1966                   dq = 0;               /* Close the quote */
1967             } else if (dq == 0) {
1968                 /* Open quote only if at beginning or preceded by space */
1969                 if (s > s2) {
1970                     if (*(s-1) == SP)
1971                       dq = 1;
1972                 } else if (s == s2) {
1973                       dq = 1;
1974                 }
1975             }
1976         }
1977 #endif /* COMMENT */
1978 #endif /* NODQMACRO */
1979         if (*s == ',' && pp <= 0 && kp <= 0
1980 #ifndef NODQMACRO
1981             && dq == 0
1982 #endif /* NODQMACRO */
1983             ) {
1984             macp[maclvl]++;             /* Comma not in {} or () */
1985             /* debug(F110,"next cmd",s,0); */
1986             kp = pp = 0;                /* so we have the next command */
1987             break;
1988         }
1989     }                                   /* Reached end. */
1990 #ifdef COMMENT
1991     /* DON'T DO THIS - IT BREAKS EVERYTHING */
1992     *s = NUL;
1993 #endif /* COMMENT */
1994     if (*s2 == NUL) {                   /* If nothing was copied, */
1995         /* debug(F100,"XXX getncm eom","",0); */
1996         popclvl();                      /* pop command level. */
1997         return(-1);
1998     } else {                            /* otherwise, tack CR onto end */
1999         *s++ = CR;
2000         *s = '\0';
2001         /* debug(F110,"XXX getncm OK",s,0); */
2002         if (mecho && pflag)             /* If MACRO ECHO ON, echo the cmd */
2003           printf("%s\n",s2);
2004     }
2005     return(0);
2006 }
2007
2008 /*  D O M A C  --  Define and then execute a macro */
2009
2010 int
2011 domac(name, def, flags) char *name, *def; int flags; {
2012     int x, m;
2013 #ifndef NOLOCAL
2014 #ifdef OS2
2015     extern int term_io;
2016     int term_io_sav = term_io;
2017     term_io = 0;                        /* Disable Terminal Emulator I/O */
2018 #endif /* OS2 */
2019 #endif /* NOLOCAL */
2020     m = maclvl;                         /* Current macro stack level */
2021     x = addmac(name, def);              /* Define a new macro */
2022     if (x > -1) {                       /* If successful, */
2023         dodo(x,NULL,flags);             /* start it (increments maclvl). */
2024         while (maclvl > m) {            /* Keep going till done with it, */
2025             debug(F101,"domac loop maclvl 1","",maclvl);
2026             sstate = (CHAR) parser(1);  /* parsing & executing each command, */
2027             debug(F101,"domac loop maclvl 2","",maclvl);
2028             if (sstate) proto();        /* including protocol commands. */
2029         }
2030         debug(F101,"domac loop exit maclvl","",maclvl);
2031     }
2032 #ifndef NOLOCAL
2033 #ifdef OS2
2034     term_io = term_io_sav;
2035 #endif /* OS2 */
2036 #endif /* NOLOCAL */
2037     return(success);
2038 }
2039 #endif /* NOSPL */
2040
2041 /*
2042   G E T N C T
2043
2044   Get next command from TAKE (command) file.
2045
2046   Call with:
2047    s     Pointer to buffer to read into
2048    n     Length of buffer
2049    f     File descriptor of file to read from
2050    flag  0 == keep line terminator on and allow continuation
2051          1 == discard line terminator and don't allow continuation
2052
2053   Call with flag == 0 to read a command from a TAKE file;
2054   Call with flag != 0 to read a line from a dialing or network directory.
2055
2056   In both cases, trailing comments and/or trailing whitespace is/are stripped.
2057   If flag == 0, continued lines are combined into one line.  A continued line
2058   is one that ends in hypen, or any line in a "block", which starts with "{"
2059   at the end of a line and ends with a matching "}" at the beginning of a
2060   subsequent line; blocks may be nested.
2061
2062   Returns:
2063    0 if a string was copied,
2064   -1 on EOF,
2065   -2 on malloc failure
2066   -3 if line is not properly terminated
2067   -4 if (possibly continued) line is too long.
2068 */
2069 static int lpxlen = 0;
2070
2071 int
2072 getnct(s,n,f,flag) char *s; int n; FILE *f; int flag; {
2073     int i = 0, len = 0, buflen = 0;
2074     char c = NUL, cc = NUL, ccl = NUL, ccx = NUL, *s2 = NULL;
2075     char *lp = NULL, *lpx = NULL, *lp2 = NULL, *lp3 = NULL, *lastcomma = NULL;
2076     char * prev = NULL;
2077     int bc = 0;                         /* Block counter */
2078
2079     s2 = s;                             /* Remember original pointer */
2080     prev = s2;                          /* Here too */
2081     buflen = n;                         /* Remember original buffer length */
2082
2083     if (n < 0)
2084       return(-2);
2085
2086     /* Allocate a line buffer only if we don't have one that's big enough */
2087
2088     debug(F111,"getnct",ckitoa(lpxlen),n);
2089
2090     if (lpx && (n > lpxlen)) {          /* Have one already */
2091         debug(F101,"getnct new buffer","",lpxlen);
2092         free(lpx);                      /* But it's not big enough */
2093         lpx = NULL;                     /* Free current one */
2094         lpxlen = 0;
2095     }
2096     if (!lpx) {                         /* Get new one */
2097         if (!(lpx = (char *) malloc(n))) {
2098             debug(F101,"getnct malloc failure","",0);
2099             printf("?Memory allocation failure [getnct:%d]\n",n);
2100             return(-2);
2101         }
2102         lpxlen = n;
2103     }
2104     lp2 = lpx;
2105 #ifdef KLUDGE
2106     /* NOTE: No longer used as of 14 Aug 2000 */
2107     lp2++;
2108 #endif /* KLUDGE */
2109
2110     while (1) {                         /* Loop to read lines from file */
2111         debug(F101,"getnct while (1)","",n);
2112         if (fgets(lp2,n,f) == NULL) {   /* Read a line into lp2 */
2113             debug(F110,"getnct EOF",s2,0); /* EOF */
2114             free(lpx);                  /* Free temporary storage */
2115             lpx = NULL;
2116             *s = NUL;                   /* Make destination be empty */
2117             return(-1);                 /* Return failure code */
2118         }
2119
2120 #ifndef NODIAL
2121         if (flag)                       /* Count this line */
2122           dirline++;
2123         else
2124 #endif /* NODIAL */
2125           tfline[tlevel]++;
2126         len = strlen(lp2) - 1;          /* Position of line terminator */
2127         if (len == 0 && lp2[0] != '\n') { /* Last line in file has one char */
2128             lp2[++len] = '\n';          /* that is not a newline */
2129             lp2[len] = NUL;
2130         }
2131         debug(F010,"getnct",lp2,0);
2132         if (len < 0)
2133           len = 0;
2134         if (techo && pflag)             /* If TAKE ECHO ON, */
2135           printf("%3d. %s",             /* echo it this line. */
2136 #ifndef NODIAL
2137                  flag ? dirline :
2138 #endif /* NODIAL */
2139                  tfline[tlevel],
2140                  lp2
2141                  );
2142         lp3 = lp2;                      /* Working pointer */
2143         i = len;                        /* Get first nonwhitespace character */
2144         while (i > 0 && (*lp3 == SP || *lp3 == HT)) {
2145             i--;
2146             lp3++;
2147         }
2148         if (i == 0 && bc > 0)           /* Blank line in {...} block */
2149           continue;
2150
2151         /* Isolate, remove, and check terminator */
2152
2153         c = lp2[len];                   /* Value of line terminator */
2154         /* debug(F101,"getnct terminator","",c); */
2155         if (c < LF || c > CR) {         /* It's not a terminator */
2156             /* debug(F111,"getnct bad line",lp2,c); */
2157             if (feof(f) && len > 0 && len < n) {
2158                 /* Kludge Alert... */
2159                 if (!quiet)
2160                   printf("WARNING: Last line of %s lacks terminator\n",
2161                          s2 == cmdbuf ? "command file" : "directory file");
2162                 c = lp2[++len] = '\n';  /* No big deal - supply one. */
2163             } else {                    /* Something's wrong, fail. */
2164                 free(lpx);
2165                 lpx = NULL;
2166                 return(-3);
2167             }
2168         }
2169         /* Trim trailing whitespace */
2170
2171         for (i = len - 1; i > -1 && lp2[i] <= SP; i--) /* Trim */
2172           ;
2173         /* debug(F101,"getnct i","",i); */
2174         lp2[i+1] = NUL;                 /* Terminate the string */
2175         /* debug(F110,"getnct lp2",lp2,0); */
2176         lp = lp2;                       /* Make a working pointer */
2177
2178         /* Remove trailing or full-line comment */
2179
2180         while ((cc = *lp)) {
2181             if (cc == ';' || cc == '#') { /* Comment introducer? */
2182                 if (lp == lp2) {        /* First char on line */
2183                     *lp = NUL;
2184                     break;
2185                 } else if (*(lp - 1) == SP || *(lp - 1) == HT) {
2186                     lp--;
2187                     *lp = NUL;  /* Or preceded by whitespace */
2188                     break;
2189                 }
2190             }
2191             lp++;
2192         }
2193         if (lp > lp2)
2194           lp--;                         /* Back up over the NUL */
2195
2196         /* Now trim any space that preceded the comment */
2197
2198         while ((*lp == SP || *lp == HT) && lp >= lp2) {
2199             *lp = NUL;
2200             if (lp <= lp2)
2201               break;
2202             lp--;
2203         }
2204         /* debug(F110,"getnct comment trimmed",lp2,0); */
2205
2206         len = strlen(lp2);              /* Length after trimming */
2207
2208         if (n - len < 2) {              /* Check remaining space */
2209             debug(F111,"getnct command too long",s2,buflen);
2210             printf("?Line too long, maximum length: %d.\n",buflen);
2211             free(lpx);
2212             return(-4);
2213         }
2214         ccl = (len > 0) ? lp2[len-1] : 0;     /* Last character in line */
2215         ccx = (len > 1) ? lp2[len-2] : 0;     /* Penultimate char in line */
2216
2217 #ifdef COMMENT
2218         /* Line containing only whitespace and ,- */
2219         if ((len > 1) && (lp3 == lp2+len-2) && (ccl == '-') && (ccx == ','))
2220           continue;
2221 #endif /* COMMENT */
2222
2223 #ifdef KLUDGE
2224 /*
2225   If it is a command and it begins with a token (like ! or .) that is not
2226   followed by a space, insert a space now; otherwise cmkey() can get mighty
2227   confused.
2228 */
2229         if (s == s2 && !flag) {
2230             char *p = toktab;
2231             while (*p) {
2232                 if (*p == *lp3 && *(p+1) != SP) {
2233                     debug(F110,"getnct token",p,0);
2234                     *lp3-- = SP;
2235                     *lp3 = *p;
2236                     if (lp3 < lp2) {
2237                         lp2--;
2238                         len++;
2239                     }
2240                     break;
2241                 } else
2242                   p++;
2243             }
2244         }
2245 #endif /* KLUDGE */
2246         lp = lp2;
2247
2248         while ((*s++ = *lp++))          /* Copy result to target buffer */
2249           n--;                          /* accounting for length */
2250         s--;                            /* Back up over the NUL */
2251
2252         /* Check whether this line is continued */
2253
2254         if (flag)                       /* No line continuation when flag=1 */
2255           break;                        /* So break out of read-lines loop */
2256
2257 #ifdef COMMENT
2258         debug(F000,"getnct first char","",*lp3);
2259         debug(F000,"getnct last char","",ccl);
2260         debug(F000,"getnct next-to-last char","",ccx);
2261 #endif /* COMMENT */
2262
2263         if (bc > 0 && *lp3 == '}') {    /* First char on line is '}' */
2264             bc--;                       /* Decrement block counter */
2265         }
2266
2267         if (bc == 0 &&                  /* Line is continued if bc > 0 */
2268 #ifdef COMMENT
2269             /* Not supported as of C-Kermit 6.0 */
2270             ccl != CMDQ &&              /* or line ends with CMDQ */
2271 #endif /* COMMENT */
2272             ccl != '-'  &&              /* or line ends with dash */
2273             ccl != '{')                 /* or line ends with opening brace */
2274           break;                        /* None of those, we're done. */
2275
2276         if (ccl == '-' || ccl == '{')   /* Continuation character */
2277           if (ccx == CMDQ)              /* But it's quoted */
2278             break;                      /* so ignore it */
2279
2280         if (ccl == '{') {               /* Last char on line is '{'? */
2281             bc++;                       /* Count the block opener. */
2282         } else if (ccl == '-') {        /* Explicit continue? */
2283             char c, * ss;
2284             int state = 0, nn;
2285             s--;                        /* Yes, back up over terminators */
2286             n++;                        /* and over continuation character */
2287             nn = n;                     /* Save current count */
2288             ss = s;                     /* and pointer */
2289             s--;                        /* Back up over dash */
2290             n++;
2291             while (state < 2 && s >= prev) { /* Check for "{,-" */
2292                 n++;
2293                 c = *s--;
2294                 if (c <= SP)
2295                   continue;
2296                 if (c != ',' && c != '{')
2297                   break;
2298                 switch (state) {
2299                   case 0:               /* Looking for comma */
2300                     if (c == ',')
2301                       state = 1;
2302                     break;
2303                   case 1:               /* Looking for left brace */
2304                     if (c == '{') {
2305                         state = 2;
2306                         s += 2;
2307                         *s = NUL;
2308                         bc++;
2309                     }
2310                     break;
2311                 }
2312             }
2313             if (state != 2) { s = ss; n = nn; }
2314             *s = NUL;
2315         } else {                        /* None of those but (bc > 0) */
2316             lastcomma = s;
2317             *s++ = ',';                 /* and insert a comma */
2318             n--;
2319         }
2320 #ifdef COMMENT
2321         debug(F101,"getnct bc","",bc);
2322         debug(F100,"getnct continued","",0);
2323 #endif /* COMMENT */
2324
2325         *s = NUL;
2326         prev = s;
2327
2328     } /* read-lines while loop */
2329
2330     if (lastcomma)
2331       *lastcomma = SP;
2332     if (!flag)                          /* Tack line terminator back on */
2333       *s++ = c;
2334     *s++ = NUL;                         /* Terminate the string */
2335     untab(s2);                          /* Done, convert tabs to spaces */
2336 #ifdef DEBUG
2337     if (!flag) {
2338         debug(F010,"CMD(F)",s2,0);
2339     }
2340 #endif /* DEBUG */
2341     free(lpx);                          /* Free temporary storage */
2342     return(0);                          /* Return success */
2343 }
2344
2345 VOID
2346 shostack() {                            /* Dump the command stack */
2347     int i;
2348     char *p;
2349 #ifndef NOSPL
2350     for (i = cmdlvl; i > 0; i--) {
2351         if (cmdstk[i].src == CMD_TF) {
2352             p = tfnam[cmdstk[i].lvl];
2353             if (zfnqfp(p,TMPBUFSIZ,tmpbuf))
2354               p = tmpbuf;
2355             printf(" %2d. File  : %s (line %d)\n",
2356                    i,
2357                    p,
2358                    tfline[cmdstk[i].lvl]
2359                    );
2360         } else if (cmdstk[i].src == CMD_MD) {
2361             char * m;
2362             m = m_arg[cmdstk[i].lvl][0]; /* Name of this macro */
2363             if (i > 0) {                 /* Special handling for 2-level */
2364                 char *s;                 /* built-in macros... */
2365                 s = m_arg[cmdstk[i-1].lvl][0]; /* Name next level up */
2366                 if (s && cmdstk[i-1].src == CMD_MD) {
2367                     if (!strcmp(s,"_forx"))
2368                       m = "FOR";
2369                     else if (!strcmp(s,"_xif"))
2370                       m = "XIF";
2371                     else if (!strcmp(s,"_while"))
2372                       m = "WHILE";
2373                     else if (!strcmp(s,"_switx"))
2374                       m = "SWITCH";
2375                 }
2376             }
2377             printf(" %2d. Macro : %s\n",i,m);
2378         } else if (cmdstk[i].src == CMD_KB) {
2379             printf(" %2d. Prompt:\n",i);
2380         } else {
2381             printf(" %2d. ERROR : Command source unknown\n",i);
2382         }
2383     }
2384 #else
2385     for (i = tlevel; i > -1; i--) {
2386         p = tfnam[i];
2387         if (zfnqfp(p,TMPBUFSIZ,tmpbuf))
2388           p = tmpbuf;
2389         printf(" %2d. File  : %s (line %d)\n",
2390                i,
2391                p,
2392                tfline[i]
2393                );
2394     }
2395 #endif /* NOSPL */
2396     if (i == 0)
2397       printf(" %2d. Prompt: (top level)\n",0);
2398 }
2399
2400 /* For command error messages - avoid dumping out the contents of some */
2401 /* some huge FOR loop if it contains a syntax error. */
2402
2403 static char *
2404 cmddisplay(s, cx) char * s; int cx; {
2405     static char buf[80];
2406     if ((int)strlen(s) > 70) {
2407         sprintf(buf,"%.64s...",s);      /* SAFE */
2408         s = buf;
2409     }
2410     return(s);
2411 }
2412
2413 static VOID
2414 cmderr() {
2415     if (xcmdsrc > 0) {
2416         switch (cmd_err) {              /* SET COMMAND ERROR-DISPLAY */
2417           case 0:
2418             break;
2419           case 1:
2420           case 2:
2421             if (tlevel > -1) {
2422 #ifndef NOSPL
2423                 if (xcmdsrc == 2)
2424                   printf(
2425 "In macro or block defined in file: %s starting about line %d\n",
2426                          tfnam[tlevel] ? tfnam[tlevel] : "", tfline[tlevel]
2427                          );
2428                 else
2429 #endif /* NOSPL */
2430                   printf("File: %s, Line: %d\n",
2431                          tfnam[tlevel] ? tfnam[tlevel] : "", tfline[tlevel]
2432                          );
2433             }
2434 #ifndef NOSPL
2435             if (cmd_err == 2) {
2436                 if (cmdstk[cmdlvl].src == CMD_MD) { /* Executing a macro? */
2437                     int m;
2438                     m = cmdstk[cmdlvl].lvl;
2439                     if (mlook(mactab,m_arg[m][0],nmac) >= 0)
2440                       printf("Macro name: %s\n", m_arg[m][0]);
2441                 }
2442             }
2443 #endif /* NOSPL */
2444             break;
2445
2446           case 3:
2447             printf("Command stack:\n");
2448             shostack();                     
2449         }
2450     }
2451 }
2452
2453 /*  P A R S E R  --  Top-level interactive command parser.  */
2454
2455 /*
2456   Call with:
2457     m = 0 for normal behavior: keep parsing and executing commands
2458           until an action command is parsed, then return with a
2459           Kermit start-state as the value of this function.
2460     m = 1 to parse only one command, can also be used to call parser()
2461           recursively.
2462     m = 2 to read but do not execute one command.
2463   In all cases, parser() returns:
2464     0     if no Kermit protocol action required
2465     > 0   with a Kermit protocol start-state.
2466     < 0   upon error.
2467 */
2468 int
2469 parser(m) int m; {
2470     int tfcode, xx, yy, zz;             /* Workers */
2471     int is_tn = 0;
2472     int cdlost = 0;
2473
2474 #ifndef NOSPL
2475     int inlevel;                        /* Level we were called at */
2476     extern int askflag, echostars;
2477 #endif /* NOSPL */
2478     char *cbp;                          /* Command buffer pointer */
2479 #ifdef MAC
2480     extern char *lfiles;                /* Fake extern cast */
2481 #endif /* MAC */
2482     extern int interrupted;
2483 #ifndef NOXFER
2484     extern int sndcmd, getcmd, fatalio, clearrq;
2485 #endif /* NOXFER */
2486
2487 #ifdef AMIGA
2488     reqres();                           /* Restore AmigaDOS requestors */
2489 #endif /* AMIGA */
2490
2491 #ifdef OS2
2492     if (cursor_save > -1) {             /* Restore cursor if it was */
2493         cursorena[VCMD] = cursor_save;  /* turned off during file transfer */
2494         cursor_save = -1;
2495     }
2496 #endif /* OS2 */
2497
2498 #ifdef IKSDB
2499     if (ikdbopen) slotstate(what,"COMMAND PROMPT","",""); /* IKSD database */
2500 #endif /* IKSDB */
2501
2502     is_tn = (local && network && IS_TELNET()) ||
2503       (!local && sstelnet);
2504
2505     if (!xcmdsrc)                       /* If at top (interactive) level ... */
2506       concb((char)escape);              /* put console in 'cbreak' mode. */
2507
2508 #ifdef CK_TMPDIR
2509 /* If we were cd'd temporarily to another device or directory ... */
2510     if (f_tmpdir) {
2511         int x;
2512         x = zchdir((char *) savdir);    /* ... restore previous directory */
2513         f_tmpdir = 0;                   /* and remember we did it. */
2514         debug(F111,"parser tmpdir restoring",savdir,x);
2515     }
2516 #endif /* CK_TMPDIR */
2517
2518 #ifndef NOSPL
2519     inlevel = cmdlvl;           /* Current macro level */
2520 #ifdef DEBUG
2521     if (deblog) {
2522         debug(F101,"&parser entry maclvl","",maclvl);
2523         debug(F101,"&parser entry inlevel","",inlevel);
2524         debug(F101,"&parser entry tlevel","",tlevel);
2525         debug(F101,"&parser entry cmdlvl","",cmdlvl);
2526         debug(F101,"&parser entry m","",m);
2527     }
2528 #endif /* DEBUG */
2529 #endif /* NOSPL */
2530
2531 #ifndef NOXFER
2532     ftreset();                          /* Reset global file settings */
2533 #endif /* NOXFER */
2534 /*
2535   sstate becomes nonzero when a command has been parsed that requires some
2536   action from the protocol module.  Any non-protocol actions, such as local
2537   directory listing or terminal emulation, are invoked directly from below.
2538 */
2539     sstate = 0;                         /* Start with no start state. */
2540
2541 #ifndef NOXFER
2542 #ifndef NOSPL
2543     query = 0;                          /* QUERY not active */
2544 #endif /* NOSPL */
2545 #ifndef NOHINTS
2546     if (!success) {
2547         if (local && !network && carrier != CAR_OFF) {
2548             int x;                      /* Serial connection */
2549             x = ttgmdm();               /* with carrier checking */
2550             if (x > -1) {
2551                 if (!(x & BM_DCD)) {
2552                     cdlost = 1;
2553                     fatalio = 1;
2554                 }
2555             }
2556         }
2557     }
2558 #ifdef DEBUG
2559     if (deblog) {
2560         debug(F101,"parser top what","",what);
2561         debug(F101,"parser top interrupted","",interrupted);
2562         debug(F101,"parser top cdlost","",cdlost);
2563         debug(F101,"parser top sndcmd","",sndcmd);
2564         debug(F101,"parser top getcmd","",getcmd);
2565     }
2566 #endif /* DEBUG */
2567     if (cdlost && !interrupted && (sndcmd || getcmd)) {
2568         printf("?Connection broken (carrier signal lost)\n");
2569     }
2570     if (sndcmd && protocol == PROTO_K &&
2571         !success && hints && !interrupted && !fatalio && !xcmdsrc) {
2572         int x = 0, n = 0;
2573         printf("\n*************************\n");
2574         printf("SEND-class command failed.\n");
2575         printf(" Packets sent: %d\n", spackets);
2576         printf(" Retransmissions: %d\n",retrans);
2577         printf(" Timeouts: %d\n", timeouts);
2578         printf(" Damaged packets: %d\n", crunched);
2579         if (epktrcvd) {
2580             printf(" Transfer canceled by receiver.\n");
2581             printf(" Receiver's message: \"%s\"\n",(char *)epktmsg);
2582             n++;
2583         } else {
2584             if (epktmsg) if (*epktmsg) {
2585                 printf(" Fatal Kermit Protocol Error: %s\n",epktmsg);
2586                 n++;
2587             }
2588         }
2589         if (local && !network && carrier != CAR_OFF) {
2590             int xx;                     /* Serial connection */
2591             xx = ttgmdm();              /* with carrier checking */
2592             if (xx > -1) {
2593                 if (!(xx & BM_DCD))
2594                   cdlost = 1;
2595             }
2596         }
2597
2598 #ifdef UNIX
2599         if (errno != 0)
2600 #endif /* UNIX */
2601           {
2602               printf(" Most recent local OS error: \"%s\"\n",ck_errstr());
2603               n++;
2604           }
2605         printf(
2606    "\nHINTS... If the preceding error message%s not explain the failure:\n",
2607                (n > 1) ? "s do" : " does"
2608                );
2609 #ifndef NOLOCAL
2610         if (local) {
2611             if (rpackets == 0) {
2612                 printf(" . Did you start a Kermit receiver on the far end?\n");
2613             } else {
2614                 printf(
2615                 " . Try changing the remote Kermit's FLOW-CONTROL setting.\n");
2616                 if (!network && mdmtyp > 0)
2617                   if ((3 * crunched) > spackets)
2618                     printf(
2619                 " . Try placing a new call to get a cleaner connection.\n");
2620             }
2621         } else if (rpackets > 0) {
2622             if (flow == FLO_NONE)
2623              printf(" . Give me a SET FLOW XON/XOFF command and try again.\n");
2624             else
2625              printf(" . Give me a SET FLOW NONE command and try again.\n");
2626         }
2627         x++;
2628 #endif /* NOLOCAL */
2629
2630         if ((3 * timeouts) > spackets)
2631           printf(" . Adjust the timeout method (see HELP SET SEND).\n");
2632         if ((3 * retrans) > spackets)
2633           printf(" . Increase the retry limit (see HELP SET RETRY).\n");
2634
2635 #ifdef CK_SPEED
2636         if (prefixing != PX_ALL && rpackets > 2) {
2637             printf(" . Try it again with: SET PREFIXING ALL\n");
2638             x++;
2639         }
2640 #endif /* CK_SPEED */
2641 #ifdef STREAMING
2642         if (streamed) {
2643             printf(" . Try it again with: SET STREAMING OFF\n");
2644             x++;
2645         } else if (reliable) {
2646             printf(" . Try it again with: SET RELIABLE OFF\n");
2647             x++;
2648         }
2649 #endif /* STREAMING */
2650
2651 #ifdef CK_SPEED
2652         if (clearrq > 0 && prefixing == PX_NON) {
2653             printf(" . Try it again with: SET CLEAR-CHANNEL OFF\n");
2654             x++;
2655         }
2656 #endif /* CK_SPEED */
2657         if (!parity) {
2658             printf(" . Try it again with: SET PARITY SPACE\n");
2659             x++;
2660         }
2661         printf(" . %sive a ROBUST command and try again.\n",
2662                (x > 0) ? "As a last resort, g" : "G"
2663                );
2664         printf("Also:\n");
2665         printf(" . Be sure the source file has read permission.\n");
2666         printf(" . Be sure the target directory has write permission.\n");
2667 /*
2668         if the file was 2G or larger make sure other Kermit supports LFs...
2669 */
2670         printf(" . Be sure the target disk has sufficient space.\n");
2671         printf("(Use SET HINTS OFF to suppress hints.)\n");
2672         printf("*************************\n\n");
2673     }
2674     debug(F101,"topcmd","",topcmd);
2675     if (getcmd && protocol == PROTO_K &&
2676         !success && hints && !interrupted && !fatalio && !xcmdsrc) {
2677         int x = 0;
2678         extern int urpsiz, wslotr;
2679         printf("\n*************************\n");
2680         printf("RECEIVE- or GET-class command failed.\n");
2681         printf(" Packets received: %d\n", rpackets);
2682         printf(" Damaged packets: %d\n", crunched);
2683         printf(" Timeouts: %d\n", timeouts);
2684         if (rpackets > 0)
2685           printf(" Packet length: %d\n", urpsiz);
2686         if (epktrcvd) {
2687             printf(" Transfer canceled by sender.\n");
2688             printf(" Sender's message: \"%s\"\n",(char *)epktmsg);
2689         }
2690 #ifdef UNIX
2691         if (errno != 0)
2692 #endif /* UNIX */
2693           printf(" Most recent local error: \"%s\"\n",ck_errstr());
2694         printf(
2695    "\nHINTS... If the preceding error message%s not explain the failure:\n",
2696                epktrcvd ? "s do" : " does"
2697                );
2698 #ifndef NOLOCAL
2699         if (local) {
2700             if (topcmd == XXGET)
2701               printf(" . Did you start a Kermit SERVER on the far end?\n");
2702             if (rpackets == 0) {
2703                 if (topcmd != XXGET)
2704                   printf(" . Did you start a Kermit SENDer on the far end?\n");
2705             } else {
2706                 printf(
2707                 " . Choose a different FLOW-CONTROL setting and try again.\n");
2708             }
2709         } else if (topcmd == XXGET)
2710           printf(" . Is the other Kermit in (or does it have) SERVER mode?\n");
2711         if (rpackets > 0 && urpsiz > 90)
2712           printf(" . Try smaller packets (SET RECEIVE PACKET-LENGTH).\n");
2713         if (rpackets > 0 && wslotr > 1 && !streamed)
2714           printf(" . Try a smaller window size (SET WINDOW).\n");
2715         if (!local && rpackets > 0) {
2716             if (flow == FLO_NONE)
2717              printf(" . Give me a SET FLOW XON/XOFF command and try again.\n");
2718             else
2719              printf(" . Give me a SET FLOW NONE command and try again.\n");
2720         }
2721         x++;
2722 #endif /* NOLOCAL */
2723 #ifdef STREAMING
2724         if (streamed) {
2725             printf(" . Try it again with: SET STREAMING OFF\n");
2726             x++;
2727         } else if (reliable && local) {
2728             printf(" . Try it again with: SET RELIABLE OFF\n");
2729             x++;
2730         } else
2731 #endif /* STREAMING */
2732         if (!parity) {
2733             printf(" . Try it again with: SET PARITY SPACE\n");
2734             x++;
2735         }
2736         printf((x > 0) ?
2737                " . As a last resort, give a ROBUST command and try again.\n" :
2738                " . Give a ROBUST command and try again.\n"
2739                );
2740         printf("Also:\n");
2741         printf(" . Be sure the target directory has write permission.\n");
2742         printf(" . Be sure the target disk has sufficient space.\n");
2743         printf(" . Try telling the %s to SET PREFIXING ALL.\n",
2744                topcmd == XXGET ? "server" : "sender"
2745                );
2746         printf(" . Try giving a ROBUST command to the %s.\n",
2747                topcmd == XXGET ? "server" : "sender"
2748                );
2749         printf("(Use SET HINTS OFF to suppress hints.)\n");
2750         printf("*************************\n\n");
2751     }
2752 #endif /* NOHINTS */
2753     getcmd = 0;
2754     sndcmd = 0;
2755     interrupted = 0;
2756 #endif /* NOXFER */
2757
2758     while (sstate == 0) {               /* Parse cmds until action requested */
2759         debug(F100,"parse top","",0);
2760         what = W_COMMAND;               /* Now we're parsing commands. */
2761         rcdactive = 0;                  /* REMOTE CD not active */
2762         keepallchars = 0;               /* MINPUT not active */
2763
2764 #ifdef OS2
2765         if (apcactive == APC_INACTIVE)
2766           WaitCommandModeSem(-1);
2767 #endif /* OS2 */
2768 #ifdef IKS_OPTION
2769         if ((local &&
2770              !xcmdsrc &&
2771              is_tn &&
2772              TELOPT_ME(TELOPT_KERMIT) &&
2773              TELOPT_SB(TELOPT_KERMIT).kermit.me_start) ||
2774             (!local &&
2775              !cmdadl &&
2776              TELOPT_ME(TELOPT_KERMIT) &&
2777              TELOPT_SB(TELOPT_KERMIT).kermit.me_start)
2778             ) {
2779             tn_siks(KERMIT_STOP);
2780         }
2781 #endif /* IKS_OPTION */
2782
2783 #ifndef NOXFER
2784         if (autopath) {
2785             fnrpath = PATH_AUTO;
2786             autopath = 0;
2787         }
2788         remfile = 0;                    /* Clear these in case REMOTE */
2789         remappd = 0;                    /* command was interrupted... */
2790         rempipe = 0;
2791         makestr(&snd_move,g_snd_move);  /* Restore these */
2792         makestr(&rcv_move,g_rcv_move);
2793         makestr(&snd_rename,g_snd_rename);
2794         makestr(&rcv_rename,g_rcv_rename);
2795 #endif /* NOXFER */
2796
2797     /* Take requested action if there was an error in the previous command */
2798
2799         setint();
2800         debug(F101,"parser tlevel","",tlevel);
2801         debug(F101,"parser cmd_rows","",cmd_rows);
2802
2803 #ifndef NOLOCAL
2804         debug(F101,"parser wasclosed","",wasclosed);
2805         if (wasclosed) {                /* If connection was just closed */
2806 #ifndef NOSPL
2807             int k;
2808             k = mlook(mactab,"on_close",nmac); /* Look up "on_close" */
2809             if (k >= 0) {               /* If found, */
2810                 /* printf("ON_CLOSE CMD LOOP\n"); */
2811                 dodo(k,ckitoa(whyclosed),0); /* Set it up */
2812             }
2813 #endif /* NOSPL */
2814             whyclosed = WC_REMO;
2815             wasclosed = 0;
2816         }
2817 #endif /* NOLOCAL */
2818
2819 #ifndef NOSPL
2820         xxdot = 0;                      /* Clear this... */
2821
2822         debug(F101,"parser success","",success);
2823         if (success == 0) {
2824             if (cmdstk[cmdlvl].src == CMD_TF && takerr[cmdlvl]) {
2825                 printf("Command file terminated by error.\n");
2826                 popclvl();
2827                 if (cmdlvl == 0) return(0);
2828             }
2829             if (cmdstk[cmdlvl].src == CMD_MD && merror[cmdlvl]) {
2830                 printf("Command error: macro terminated.\n");
2831                 popclvl();
2832                 if (m && (cmdlvl < inlevel))
2833                   return((int) sstate);
2834             }
2835         }
2836         nulcmd = (m == 2);
2837         debug(F101,"parser nulcmd","",nulcmd);
2838 #else
2839         if (success == 0 && tlevel > -1 && takerr[tlevel]) {
2840             printf("Command file terminated by error.\n");
2841             popclvl();
2842             cmini(ckxech);              /* Clear the cmd buffer. */
2843             if (tlevel < 0)             /* Just popped out of cmd files? */
2844               return(0);                /* End of init file or whatever. */
2845         }
2846 #endif /* NOSPL */
2847
2848 #ifdef MAC
2849         /* Check for TAKE initiated by menu. */
2850         if ((tlevel == -1) && lfiles)
2851             startlfile();
2852 #endif /* MAC */
2853
2854         /* If in TAKE file, check for EOF */
2855 #ifndef NOSPL
2856 #ifdef MAC
2857         if
2858 #else
2859         while
2860 #endif /* MAC */
2861           ((cmdstk[cmdlvl].src == CMD_TF)  /* If end of take file */
2862                && (tlevel > -1)
2863                && feof(tfile[tlevel])) {
2864             popclvl();                  /* pop command level */
2865             cmini(ckxech);              /* and clear the cmd buffer. */
2866             if (cmdlvl == 0) {          /* Just popped out of all cmd files? */
2867                 return(0);              /* End of init file or whatever. */
2868             }
2869         }
2870 #ifdef MAC
2871         miniparser(1);
2872         if (sstate == 'a') {            /* if cmd-. cancel */
2873             debug(F100, "parser: cancel take due to sstate", "", sstate);
2874             sstate = '\0';
2875             dostop();
2876             return(0);                  /* End of init file or whatever. */
2877         }
2878 #endif /*  MAC */
2879
2880 #else /* NOSPL */
2881         if ((tlevel > -1) && feof(tfile[tlevel])) { /* If end of take */
2882             popclvl();                  /* Pop up one level. */
2883             cmini(ckxech);              /* and clear the cmd buffer. */
2884             if (tlevel < 0)             /* Just popped out of cmd files? */
2885               return(0);                /* End of init file or whatever. */
2886         }
2887 #endif /* NOSPL */
2888
2889
2890 #ifndef NOSPL
2891         debug(F101,"parser cmdlvl","",cmdlvl);
2892         debug(F101,"parser cmdsrc","",cmdstk[cmdlvl].src);
2893
2894         if (cmdstk[cmdlvl].src == CMD_MD) { /* Executing a macro? */
2895             debug(F100,"parser macro","",0);
2896             maclvl = cmdstk[cmdlvl].lvl; /* Get current level */
2897             debug(F101,"parser maclvl","",maclvl);
2898             cbp = cmdbuf;               /* Copy next cmd to command buffer. */
2899             *cbp = NUL;
2900             if (*savbuf) {              /* In case then-part of 'if' command */
2901                 ckstrncpy(cbp,savbuf,CMDBL); /* was saved, restore it. */
2902                 *savbuf = '\0';
2903             } else {                    /* Else get next cmd from macro def */
2904                 if (getncm(cbp,CMDBL) < 0) {
2905 #ifdef DEBUG
2906                     if (deblog) {
2907                         debug(F101,"parser end of macro m","",m);
2908                         debug(F101,"parser end of macro cmdlvl","",cmdlvl);
2909                         debug(F101,"parser end of macro inlevel","",inlevel);
2910                     }
2911 #endif /* DEBUG */
2912                     if (m && (cmdlvl < inlevel))
2913                       return((int) sstate);
2914                     else /* if (!m) */ continue;
2915                 }
2916             }
2917             debug(F010,"CMD(M)",cmdbuf,0);
2918
2919         } else if (cmdstk[cmdlvl].src == CMD_TF)
2920 #else
2921           if (tlevel > -1)
2922 #endif /* NOSPL */
2923           {
2924 #ifndef NOSPL
2925             debug(F111,"parser savbuf",savbuf,tlevel);
2926             if (*savbuf) {              /* In case THEN-part of IF command */
2927                 ckstrncpy(cmdbuf,savbuf,CMDBL); /* was saved, restore it. */
2928                 *savbuf = '\0';
2929             } else
2930 #endif /* NOSPL */
2931
2932               /* Get next line from TAKE file */
2933
2934               if ((tfcode = getnct(cmdbuf,CMDBL,tfile[tlevel],0)) < 0) {
2935                   debug(F111,"parser tfcode",tfile[tlevel],tfcode);
2936                   if (tfcode < -1) {    /* Error */
2937                       printf("?Error in TAKE command file: %s\n",
2938                              (tfcode == -2) ? "Memory allocation failure" :
2939                              "Line too long or contains NUL characters"
2940                              );
2941                       dostop();
2942                   }
2943                   continue;             /* -1 means EOF */
2944               }
2945
2946         /* If interactive, get next command from user. */
2947
2948         } else {                        /* User types it in. */
2949             if (pflag) prompt(xxstring);
2950             cmini(ckxech);
2951         }
2952
2953     /* Now we know where next command is coming from. Parse and execute it. */
2954
2955         repars = 1;                     /* 1 = command needs parsing */
2956 #ifndef NOXFER
2957         displa = 0;                     /* Assume no file transfer display */
2958 #endif /* NOXFER */
2959
2960         while (repars) {                /* Parse this cmd until entered. */
2961
2962             debug(F101,"parser top of while loop","",0);
2963             xaskmore = saveask;         /* Restore global more-prompting */
2964             diractive = 0;              /* DIR command not active */
2965             cdactive = 0;               /* CD command not active */
2966 #ifndef NOSPL
2967             askflag = 0;                /* ASK command not active */
2968             echostars = 0;              /* Nor ASKQ */
2969             debok = 1;                  /* Undisable debugging */
2970 #endif /* NOSPL */
2971
2972 #ifdef RECURSIVE
2973             /* In case of "send /recursive ./?<Ctrl-U>" etc */
2974             recursive = 0;              /* This is never sticky */
2975 #endif /* RECURSIVE */
2976             xfiletype = -1;             /* Reset this between each command */
2977 #ifndef NOMSEND
2978             addlist = 0;
2979 #endif /* NOMSEND */
2980 #ifdef CK_RECALL
2981             on_recall = 1;
2982 #endif /* CK_RECALL */
2983             /* This might have been changed by a switch */
2984             if (g_matchdot > -1) {
2985                 matchdot = g_matchdot;
2986                 g_matchdot = -1;
2987             }
2988             cmres();                    /* Reset buffer pointers. */
2989
2990 #ifdef OS2
2991 #ifdef COMMENT
2992             /* we check to see if a macro is waiting to be executed */
2993             /* if so, we call domac on it */
2994             if (cmdmac) {
2995                 ckstrncpy(cmdbuf, cmdmac, CMDBL);
2996                 free(cmdmac);
2997                 cmdmac = NULL;
2998             }
2999 #endif /* COMMENT */
3000 #endif /* OS2 */
3001 #ifndef NOXFER
3002             bye_active = 0;
3003 #endif /* NOXFER */
3004             havetoken = 0;
3005             xx = cmkey2(cmdtab,ncmd,"Command","",toktab,xxstring,1);
3006             debug(F101,"top-level cmkey2","",xx);
3007             if (xx == -5) {
3008                 yy = chktok(toktab);
3009                 debug(F101,"top-level cmkey token","",yy);
3010 #ifndef COMMENT
3011                 /* Either way makes absolutely no difference */
3012                 debug(F110,"NO UNGWORD",atmbuf,0);
3013                 /* ungword(); */
3014 #else
3015                 debug(F110,"TOKEN UNGWORD",atmbuf,0);
3016                 ungword();
3017 #endif /* COMMENT */
3018                 switch (yy) {
3019                   case '#': xx = XXCOM; break; /* Comment */
3020                   case ';': xx = XXCOM; break; /* Comment */
3021 #ifndef NOSPL
3022                   case '.': xx = XXDEF; xxdot = 1; break; /* Assignment */
3023                   case ':': xx = XXLBL; break; /* GOTO label */
3024 #endif /* NOSPL */
3025
3026 #ifndef NOPUSH
3027 #ifdef CK_REDIR
3028                   case '<':
3029 #endif /* CK_REDIR */
3030                   case '@':
3031                   case '!':
3032                     if (nopush) {
3033                         char *s; int x;
3034                         if ((x = cmtxt("Text to be ignored","",&s,NULL)) < 0)
3035                           return(x);
3036                         success = 0;
3037                         xx = XXCOM;
3038                     } else {
3039                         switch(yy) {
3040 #ifdef CK_REDIR
3041                           case '<': xx = XXFUN; break; /* REDIRECT */
3042 #endif /* CK_REDIR */
3043                           case '@':
3044                           case '!': xx = XXSHE; break; /* Shell escape */
3045                         }
3046                     }
3047                     break;
3048 #endif /* NOPUSH */
3049 #ifdef CK_RECALL
3050                   case '^': xx = XXREDO;  break;
3051 #endif /* CK_RECALL */
3052 #ifndef NOSPL
3053                   case '{': xx = XXMACRO; break;
3054                   case '(': xx = XXSEXP;  break;
3055 #endif /* NOSPL */
3056
3057                   default:
3058                     if (!quiet && !cmd_err) {
3059                         printf("\n?Invalid - \"%s\"\n",
3060                                cmddisplay((char *)cmdbuf,xx)
3061                                );
3062                         cmderr();
3063                     }
3064                     xx = -2;
3065                 }
3066                 havetoken = 1;
3067                 debug(F101,"HAVE TOKEN","",xx);
3068             }
3069             if (xx > -1) {
3070                 topcmd = xx;            /* Top-level command index */
3071 #ifndef NOSPL
3072                 if (maclvl > -1)
3073                   lastcmd[maclvl] = xx;
3074 #endif /* NOSPL */
3075                 debug(F101,"topcmd","",topcmd);
3076                 debug(F101,"cmflgs","",cmflgs);
3077             }
3078
3079 #ifndef NOSPL
3080             /* Special handling for IF..ELSE */
3081
3082             debug(F101,"cmdlvl","",cmdlvl);
3083             debug(F101,"ifcmd[cmdlvl]","",ifcmd[cmdlvl]);
3084
3085             if (ifcmd[cmdlvl])          /* Count stmts after IF */
3086               ifcmd[cmdlvl]++;
3087             if (ifcmd[cmdlvl] > 2 && xx != XXELS && xx != XXCOM)
3088               ifcmd[cmdlvl] = 0;
3089
3090             /* Execute the command and take action based on return code. */
3091
3092             if (nulcmd) {               /* Ignoring this command? */
3093                 xx = XXCOM;             /* Make this command a comment. */
3094             }
3095             fnsuccess = 1;              /* For catching \function() errors */
3096 #endif /* NOSPL */
3097
3098             debug(F101,"calling docmd()","",xx);
3099             zz = docmd(xx);             /* Parse rest of command & execute. */
3100
3101 #ifndef NOSPL
3102             {                           /* For \v(lastcommand) */
3103                 extern char * prevcmd;
3104                 /* The exception list kind of a hack but let's try it... */
3105                 if (ckstrcmp(cmdbuf,"_getarg",7,0) &&
3106                     ckstrcmp(cmdbuf,"if ",3,0) &&
3107                     ckstrcmp(cmdbuf,"xif ",4,0) &&
3108                     ckstrcmp(cmdbuf,"do _if",6,0) &&
3109                     ckstrcmp(cmdbuf,"_assign _if",11,0))
3110                   ckstrncpy(prevcmd,cmdbuf,CMDBL);
3111             }
3112 #endif  /* NOSPL */
3113
3114 #ifndef NOSPL
3115             if (fnerror && !fnsuccess)
3116               success = 0;
3117 #endif /* NOSPL */
3118             debug(F101,"docmd returns","",zz);
3119             /* debug(F011,"cmdbuf",cmdbuf,30); */
3120             /* debug(F011,"atmbuf",atmbuf,30); */
3121 #ifdef MAC
3122             if (tlevel > -1) {
3123                 if (sstate == 'a') {    /* if cmd-. cancel */
3124                     debug(F110, "parser: cancel take, sstate:", "a", 0);
3125                     sstate = '\0';
3126                     dostop();
3127                     return(0);          /* End of init file or whatever. */
3128                 }
3129             }
3130 #endif /* MAC */
3131             switch (zz) {
3132               case -4:                  /* EOF (e.g. on redirected stdin) */
3133                 doexit(GOOD_EXIT,xitsta); /* ...exit successfully */
3134               case -1:                  /* Reparse needed */
3135                 repars = 1;             /* Just set reparse flag and... */
3136                 continue;
3137 #ifdef OS2
3138               case -7:                  /* They typed a disk letter */
3139                 if (!zchdir((char *)cmdbuf)) {
3140                     perror((char *)cmdbuf);
3141                     success = 0;
3142                 } else success = 1;
3143                 repars = 0;
3144                 continue;
3145
3146 #endif /* OS2 */
3147               case -6:                  /* Invalid command given w/no args */
3148               case -2: {                /* Invalid command given w/args */
3149                   int x = 0;
3150                   char * eol = "";
3151                   x = strlen(cmdbuf);   /* Avoid blank line */
3152                   if (x > 0) {
3153                       if (cmdbuf[x-1] != LF)
3154                         eol = "\n";
3155                       printf("?Invalid: %s%s",
3156                              cmddisplay(cmdbuf,xx),eol
3157                              );
3158                   } else
3159                     printf("?Invalid\n");
3160               }
3161               case -9:                  /* Bad, error message already done */
3162                 success = 0;
3163                 debug(F110,"top-level cmkey failed",cmdbuf,0);
3164                 /* If in background w/ commands coming stdin, terminate */
3165                 if (pflag == 0 && tlevel < 0)
3166                   fatal("Kermit command error in background execution");
3167 /*
3168   Command retry feature, edit 190.  If we're at interactive prompting level,
3169   reprompt the user with as much of the command as didn't fail.
3170 */
3171 #ifdef CK_RECALL
3172                 if (cm_retry && !xcmdsrc) { /* If at top level */
3173                     int len;
3174                     char *p, *s;
3175                     len = strlen(cmdbuf); /* Length of command buffer */
3176                     p = malloc(len + 1);  /* Allocate space for copy */
3177                     if (p) {              /* If we got the space copy */
3178                         strcpy(p,cmdbuf); /* the command buffer (SAFE). */
3179                         /* Chop off final field, the one that failed. */
3180                         s = p + len - 1;          /* Point to end */
3181                         while (*s == SP && s > p) /* Trim blanks */
3182                           s--;
3183                         while (*s != SP && s > p) /* Trim last field */
3184                           s--;
3185                         if (s > p)        /* Keep the space */
3186                           s++;            /* after last good field */
3187                         if (s >= p)       /* Cut off remainder */
3188                           *s = NUL;
3189                         cmini(ckxech);    /* Reinitialize the parser */
3190                         ckstrncpy(cmdbuf,p,CMDBL); /* Copy result back */
3191                         free(p);          /* Free temporary storage */
3192                         p = NULL;
3193                         prompt(xxstring); /* Reprint the prompt */
3194                         printf("%s",cmdbuf); /* Reprint partial command */
3195                         repars = 1;          /* Force reparse */
3196                         continue;
3197                     }
3198                 } else
3199 #endif /* CK_RECALL */
3200                   cmderr();
3201
3202                 cmini(ckxech);          /* (fall thru) */
3203
3204               case -3:                  /* Empty command OK at top level */
3205                 repars = 0;             /* Don't need to reparse. */
3206                 continue;               /* Go back and get another command. */
3207
3208               default:                  /* Command was successful. */
3209 #ifndef NOSPL
3210                 debug(F101,"parser preparing to continue","",maclvl);
3211 #endif /* NOSPL */
3212                 debug(F101,"parser success","",success);
3213                 repars = 0;             /* Don't need to reparse. */
3214                 continue;               /* Go back and get another command. */
3215             }
3216         }
3217 #ifndef NOSPL
3218         debug(F101,"parser breaks out of while loop","",maclvl);
3219         if (m && (cmdlvl < inlevel))  return((int) sstate);
3220 #endif /* NOSPL */
3221     }
3222
3223 /* Got an action command, return start state. */
3224
3225     return((int) sstate);
3226 }
3227
3228 #ifndef NOSPL
3229 /*
3230   OUTPUT command.
3231   Buffering and pacing added by L.I. Kirby, 5A(189), June 1993.
3232 */
3233 #define OBSIZE 80                       /* Size of local character buffer */
3234
3235 static int obn;                         /* Buffer offset (high water mark) */
3236 static char obuf[OBSIZE+1];             /* OUTPUT buffer. */
3237 static char *obp;                       /* Pointer to output buffer. */
3238 _PROTOTYP( static int oboc, (char) );
3239 _PROTOTYP( static int xxout, (char *, int) );
3240
3241 static int
3242 #ifdef CK_ANSIC
3243 xxout(char *obuf, int obsize)
3244 #else
3245 xxout(obuf, obsize) char *obuf; int obsize;
3246 #endif /* CK_ANSIC */
3247 /* xxout */ {                           /* OUTPUT command's output function */
3248     int i, rc;
3249
3250     debug(F101,"xxout obsize","",obsize);
3251     debug(F101,"xxout pacing","",pacing);
3252     debug(F111,"xxout string",obuf,strlen(obuf));
3253
3254     rc = 0;                             /* Initial return code. */
3255     if (!obuf || (obsize <= 0))         /* Nothing to output. */
3256       goto xxout_x;                     /* Return successfully */
3257
3258     rc = -1;                              /* Now assume failure */
3259     if (pacing == 0) {                    /* Is pacing enabled? */
3260         if ((local ?                      /* No, write entire string at once */
3261              ttol((CHAR *)obuf, obsize) : /* to communications device */
3262              conxo(obsize, obuf))         /* or to console */
3263             != obsize)
3264           goto xxout_x;
3265     } else {
3266         for (i = 0; i < obsize; i++) {  /* Write individual chars */
3267             if ((local ? ttoc(obuf[i]) : conoc(obuf[i])) < 0)
3268               goto xxout_x;
3269             msleep(pacing);
3270         }
3271     }
3272     if (duplex) {
3273 #ifdef OS2
3274         if (inecho && local) {
3275 #ifndef NOLOCAL
3276             for (i = 0; i < obsize; i++) { /* Write to emulator */
3277                 scriptwrtbuf((USHORT)obuf[i]); /* which also logs session */
3278             }
3279 #endif /* NOLOCAL */
3280             conxo(obsize,obuf);
3281         } else if (seslog) {            /* or log session here */
3282             logstr((char *) obuf, obsize);
3283         }
3284 #else /* OS2 */
3285         if (seslog) {
3286             logstr((char *) obuf, obsize);
3287         }
3288         if (inecho && local) {
3289             conxo(obsize,obuf);
3290         }
3291 #endif /* OS2 */
3292     }
3293     rc = 0;                             /* Success */
3294   xxout_x:
3295     obn = 0;                            /* Reset count */
3296     obp = obuf;                         /* and pointers */
3297     return(rc);                         /* return our return code */
3298 }
3299
3300 #ifdef COMMENT
3301 /*
3302   Macros for OUTPUT command execution, to make it go faster.
3303 */
3304 #define obfls() ((xxout(obuf,obn)<0)?-1:0)
3305 #define oboc(c) ((*obp++=(char)(c)),*obp=0,(((++obn)>=OBSIZE)?obfls():0))
3306
3307 #else /* The macros cause some compilers to generate bad code. */
3308
3309 static int
3310 #ifdef CK_ANSIC
3311 oboc(char c)
3312 #else
3313 oboc(c) char c;
3314 #endif /* CK_ANSIC */
3315 /* oboc */ {                            /* OUTPUT command's output function */
3316
3317     *obp++ = c;                         /* Deposit character */
3318     *obp = NUL;                         /* Flush buffer if it's now full */
3319
3320     return(((++obn) >= OBSIZE) ? xxout(obuf,obn) : 0);
3321 }
3322 #endif /* COMMENT */
3323
3324 /*  Routines for handling local variables -- also see popclvl().  */
3325
3326 VOID
3327 freelocal(m) int m; {                   /* Free local variables */
3328     struct localvar * v, * tv;          /* at macro level m... */
3329     debug(F101,"freelocal level","",m);
3330     if (m < 0) return;
3331     v = localhead[m];                   /* List head for level m */
3332     while (v) {
3333         if (v->lv_name)                 /* Variable name */
3334           free(v->lv_name);
3335         if (v->lv_value)                /* Value */
3336           free(v->lv_value);
3337         tv = v;                         /* Save pointer to this node */
3338         v = v->lv_next;                 /* Get next one */
3339         if (tv)                         /* Free this one */
3340           free((char *)tv);
3341     }
3342     localhead[m] = (struct localvar *) NULL; /* Done, set list head to NULL */
3343 }
3344
3345 #define MAXLOCALVAR 64
3346
3347 /* Return a pointer to the definition of a user-defined variable */
3348
3349 static char *
3350 vardef(s,isarray,x1,x2) char * s; int * isarray, * x1, * x2; {
3351     char * p;
3352     char c;
3353     *isarray = 0;
3354     if (!s) return(NULL);
3355     if (!*s) return(NULL);
3356     p = s;
3357     if (*s == CMDQ) {
3358         p++;
3359         if (!*p)
3360           return(NULL);
3361         if ((c = *p) == '%') {          /* Scalar variable. */
3362             c = *++p;                   /* Get ID character. */
3363             p = "";                     /* Assume definition is empty */
3364             if (!c)
3365               return(NULL);
3366             if (c >= '0' && c <= '9') { /* Digit for macro arg */
3367                 if (maclvl < 0)         /* Digit variables are global */
3368                   return(g_var[c]);     /* if no macro is active */
3369                 else                    /* otherwise */
3370                   return(m_arg[maclvl][c - '0']); /* they're on the stack */
3371             } else if (isalpha(c)) {
3372                 if (isupper(c)) c -= ('a'-'A');
3373                 return(g_var[c]);           /* Letter for global variable */
3374             } else
3375               return(NULL);
3376         } else if (c == '&') {          /* Array reference. */
3377             int x, vbi, d;
3378             x = arraynam(p,&vbi,&d);    /* Get name and subscript */
3379             if (x > -1 || d == -17) {
3380                 *isarray = 1;
3381                 *x1 = vbi;
3382                 *x2 = (d == -17) ? 0 : d;
3383             }
3384             if (x < 0)
3385               return(NULL);
3386             if (chkarray(vbi,d) >= 0) { /* Array is declared? */
3387                 vbi -= ARRAYBASE;       /* Convert name to index */
3388                 if (a_dim[vbi] >= d) {  /* If subscript in range */
3389                     char **ap;
3390                     ap = a_ptr[vbi];
3391                     return((ap) ? ap[d] : NULL);
3392                 }
3393             }
3394         }
3395         return(NULL);
3396     } else {
3397         int k;
3398         k = mxlook(mactab,s,nmac);
3399         return((k > -1) ? mactab[k].mval : NULL);
3400     }
3401 }
3402
3403
3404 int
3405 addlocal(p) char * p; {
3406     int x, z, isarray = 0;
3407     char * s;
3408     struct localvar * v, *prev = (struct localvar *)NULL;
3409     extern int tra_asg; int tra_tmp;
3410
3411     tra_tmp = tra_asg;
3412
3413     s = vardef(p,&isarray,&x,&z);       /* Get definition of variable */
3414     if (isarray) {                      /* Arrays are handled specially */
3415         pusharray(x,z);
3416         return(0);
3417     }
3418     if (!s) s = "";
3419     if ((v = localhead[cmdlvl])) {      /* Already have some at this level? */
3420         while (v) {                     /* Find end of list */
3421             prev = v;
3422             v = v->lv_next;
3423         }
3424     }
3425     v = (struct localvar *) malloc(sizeof(struct localvar));
3426     if (!v) {
3427         printf("?Failure to allocate storage for local variables");
3428         return(-9);
3429     }
3430     if (!localhead[cmdlvl])             /* If first, set list head */
3431       localhead[cmdlvl] = v;
3432     else                                /* Otherwise link previous to this */
3433       prev->lv_next = v;
3434     prev = v;                           /* And make this previous */
3435     v->lv_next = (struct localvar *) NULL; /* No next yet */
3436
3437     if (!(v->lv_name = (char *) malloc((int) strlen(p) + 1)))
3438       return(-1);
3439     strcpy(v->lv_name, p);              /* Copy name into new node (SAFE) */
3440
3441     if (*s) {
3442         if (!(v->lv_value = (char *) malloc((int) strlen(s) + 1)))
3443           return(-1);
3444         strcpy(v->lv_value, s);         /* Copy value into new node (SAFE) */
3445     } else
3446       v->lv_value = NULL;
3447
3448     tra_asg = 0;
3449     delmac(p,1);                        /* Delete the original macro */
3450     tra_asg = tra_tmp;
3451     return(0);
3452 }
3453
3454 int
3455 dolocal() {                             /* Do the LOCAL command */
3456     int i, x;
3457     char * s;
3458     char * list[MAXLOCALVAR+2];         /* Up to 64 variables per line */
3459
3460     if ((x = cmtxt("Variable name(s)","",&s,NULL)) < 0)
3461       return(x);
3462
3463     xwords(s,MAXLOCALVAR,list,0);       /* Break up line into "words" */
3464
3465     /* Note: Arrays do not use the localhead list, but have their own stack */
3466
3467     for (i = 1; i < MAXLOCALVAR && list[i]; i++) { /* Go through the list */
3468         if (addlocal(list[i]) < 0)
3469           goto localbad;
3470     }
3471     return(success = 1);
3472
3473   localbad:
3474     printf("?Failure to allocate storage for local variables");
3475     freelocal(cmdlvl);
3476     return(-9);
3477 }
3478
3479 /*  D O O U T P U T  --  Returns 0 on failure, 1 on success */
3480
3481 #ifndef NOKVERBS
3482 #define K_BUFLEN 30
3483 #define SEND_BUFLEN 255
3484 #define sendbufd(x) { osendbuf[sendndx++] = x;\
3485  if (sendndx == SEND_BUFLEN) {dooutput(s,cx); sendndx = 0;}}
3486 #endif /* NOKVERBS */
3487
3488 int outesc = 1;                         /* Process special OUTPUT escapes */
3489
3490 int
3491 dooutput(s, cx) char *s; int cx; {
3492 #ifdef SSHBUILTIN
3493     extern int ssh_cas;
3494     extern char * ssh_cmd;
3495 #endif /* SSHBUILTIN */
3496     int x, xx, y, quote;                /* Workers */
3497     int is_tn = 0;
3498
3499     is_tn = (local && network && IS_TELNET()) ||
3500       (!local && sstelnet);
3501
3502     debug(F111,"dooutput s",s,(int)strlen(s));
3503
3504     if (local) {                        /* Condition external line */
3505 #ifdef NOLOCAL
3506         goto outerr;
3507 #else
3508         if (ttchk() < 0) {
3509             if (!network) {
3510                 if (carrier != CAR_OFF) {
3511                     int x;
3512                     x = ttgmdm();
3513                     if ((x > -1) && ((x & BM_DCD) == 0)) {
3514                         printf(
3515 "?Carrier signal required but not present - Try SET CARRIER-WATCH OFF.\n"
3516                               );
3517                         return(0);
3518                     }
3519                 } else {
3520                     printf(
3521 "?Problem with serial port or modem or cable - Try SHOW COMMUNICATIONS.\n"
3522                           );
3523                     return(0);
3524                 }
3525             }
3526             printf("?Connection %s %s is not open or not functioning.\n",
3527                    network ? "to" : "on",
3528                    ttname
3529                    );
3530             return(0);
3531         }
3532         if (ttvt(speed,flow) < 0) {
3533             printf("?OUTPUT initialization error\n");
3534             return(0);
3535         }
3536 #endif /* NOLOCAL */
3537     }
3538 #ifdef SSHBUILTIN
3539     if ( network && nettype == NET_SSH && ssh_cas && ssh_cmd && 
3540          !(strcmp(ssh_cmd,"kermit") && strcmp(ssh_cmd,"sftp"))) {
3541         if (!quiet)
3542             printf("?SSH Subsystem active: %s\n", ssh_cmd);
3543         return(0);
3544     }
3545 #endif /* SSHBUILTIN */
3546
3547     if (!cmdgquo()) {                   /* COMMAND QUOTING OFF */
3548         x = strlen(s);                  /* Just send the string literally */
3549         xx = local ? ttol((CHAR *)s,x) : conxo(x,s);
3550         return(success = (xx == x) ? 1 : 0);
3551     }
3552     quote = 0;                          /* Initialize backslash (\) quote */
3553     obn = 0;                            /* Reset count */
3554     obp = obuf;                         /* and pointers */
3555
3556   outagain:
3557     while ((x = *s++)) {                /* Loop through the string */
3558         y = 0;                          /* Error code, 0 = no error. */
3559         debug(F000,"dooutput","",x);
3560         if (quote) {                    /* This character is quoted */
3561 #ifndef NOKVERBS
3562            if (x == 'k' || x == 'K') {  /* \k or \K */
3563                extern struct keytab kverbs[];
3564                extern int nkverbs;
3565                extern char * keydefptr;
3566                extern int keymac;
3567                extern int keymacx;
3568                int x, y, brace = 0;
3569                int pause;
3570                char * p, * b;
3571                char kbuf[K_BUFLEN + 1]; /* Key verb name buffer */
3572                char osendbuf[SEND_BUFLEN +1];
3573                int  sendndx = 0;
3574
3575                if (xxout(obuf,obn) < 0) /* Flush buffer */
3576                  goto outerr;
3577                debug(F100,"OUTPUT KVERB","",0); /* Send a KVERB */
3578                {                        /* Have K verb? */
3579                    if (!*s) {
3580                        break;
3581                    }
3582 /*
3583   We assume that the verb name is {braced}, or it extends to the end of the
3584   string, s, or it ends with a space, control character, or backslash.
3585 */
3586                    p = kbuf;            /* Copy verb name into local buffer */
3587                    x = 0;
3588                    while ((x++ < K_BUFLEN) && (*s > SP) && (*s != CMDQ)) {
3589                        if (brace && *s == '}') {
3590                            break;
3591                        }
3592                        *p++ = *s++;
3593                    }
3594                    if (*s && !brace)    /* If we broke because of \, etc, */
3595                      s--;               /*  back up so we get another look. */
3596                    brace = 0;
3597                    *p = NUL;            /* Terminate. */
3598                    p = kbuf;            /* Point back to beginning */
3599                    debug(F110,"dooutput kverb",p,0);
3600                    y = xlookup(kverbs,p,nkverbs,&x); /* Look it up */
3601                    debug(F101,"dooutput lookup",0,y);
3602                    if (y > -1) {
3603                        if (sendndx) {
3604                            dooutput(osendbuf,cx);
3605                            sendndx = 0;
3606                        }
3607                        dokverb(VCMD,y);
3608 #ifndef NOSPL
3609                    } else {             /* Is it a macro? */
3610                        y = mxlook(mactab,p,nmac);
3611                        if (y > -1) {
3612                            cmpush();
3613                            keymac = 1;  /* Flag for key macro active */
3614                            keymacx = y; /* Key macro index */
3615                            keydefptr = s; /* Where to resume next time */
3616                            debug(F111,"dooutput mxlook",keydefptr,y);
3617                            parser(1);
3618                            cmpop();
3619                        }
3620 #endif /* NOSPL */
3621                    }
3622                }
3623                quote = 0;
3624                continue;
3625            } else
3626 #endif /* NOKVERBS */
3627              if (outesc && (x == 'n' || x == 'N')) { /* \n or \N */
3628                  if (xxout(obuf,obn) < 0) /* Flush buffer */
3629                    goto outerr;
3630                  debug(F100,"OUTPUT NUL","",0); /* Send a NUL */
3631                  if (local)
3632                    ttoc(NUL);
3633                  else
3634                    conoc(NUL);
3635                  quote = 0;
3636                  continue;
3637
3638              } else if (outesc && (x == 'b' || x == 'B')) { /* \b or \B */
3639
3640                 if (xxout(obuf,obn) < 0) /* Flush buffer first */
3641                   goto outerr;
3642                 debug(F100,"OUTPUT BREAK","",0);
3643 #ifndef NOLOCAL
3644                 ttsndb();               /* Send BREAK signal */
3645 #else
3646                  if (local)
3647                    ttoc(NUL);
3648                  else
3649                    conoc(NUL);
3650 #endif /* NOLOCAL */
3651                 quote = 0;              /* Turn off quote flag */
3652                 continue;               /* and not the b or B */
3653 #ifdef CK_LBRK
3654              } else if (outesc && (x == 'l' || x == 'L')) { /* \l or \L */
3655                  if (xxout(obuf,obn) < 0) /* Flush buffer first */
3656                    goto outerr;
3657                  debug(F100,"OUTPUT Long BREAK","",0);
3658 #ifndef NOLOCAL
3659                  ttsndlb();             /* Send Long BREAK signal */
3660 #else
3661                  if (local)
3662                    ttoc(NUL);
3663                  else
3664                    conoc(NUL);
3665 #endif /* NOLOCAL */
3666                  quote = 0;             /* Turn off quote flag */
3667                  continue;              /* and not the l or L */
3668 #endif /* CK_LBRK */
3669
3670              } else if (x == CMDQ) {    /* Backslash itself */
3671                  debug(F100,"OUTPUT CMDQ","",0);
3672                  xx = oboc(dopar(CMDQ)); /* Output the backslash. */
3673                  if (xx < 0)
3674                    goto outerr;
3675                  quote = 0;
3676                  continue;
3677
3678              } else {                   /* if \ not followed by special esc */
3679                 /* Note: Atari ST compiler won't allow macro call in "if ()" */
3680                  xx = oboc(dopar(CMDQ)); /* Output the backslash. */
3681                  if (xx < 0)
3682                    goto outerr;
3683                  quote = 0;             /* Turn off quote flag */
3684              }
3685         } else if (x == CMDQ) {         /* This is the quote character */
3686             quote = 1;                  /* Go back and get next character */
3687             continue;                   /* which is quoted */
3688         }
3689         xx = oboc(dopar((char)x));      /* Output this character */
3690         debug(F111,"dooutput",obuf,obn);
3691         if (xx < 0)
3692           goto outerr;
3693 #ifdef COMMENT
3694         if (seslog && duplex) {         /* Log the character if log is on */
3695             logchar((char)x);
3696         }
3697 #endif /* COMMENT */
3698         if (x == '\015') {              /* String contains carriage return */
3699             int stuff = -1, stuff2 = -1;
3700             if (tnlm) {                 /* TERMINAL NEWLINE ON */
3701                 stuff = LF;             /* Stuff LF */
3702             }
3703 #ifdef TNCODE
3704             /* TELNET NEWLINE ON/OFF/RAW */
3705             if (is_tn) {
3706                 switch (TELOPT_ME(TELOPT_BINARY) ? /* NVT or BINARY */
3707                         tn_b_nlm :
3708                         tn_nlm
3709                         ) {
3710                   case TNL_CR:
3711                     break;
3712                   case TNL_CRNUL:
3713                     stuff2 = stuff;
3714                     stuff  = NUL;
3715                     break;
3716                   case TNL_CRLF:
3717                     stuff2 = stuff;
3718                     stuff = LF;
3719                     break;
3720                 }
3721             }
3722 #endif /* TNCODE */
3723             if (stuff > -1) {           /* Stuffing another character... */
3724                 xx = oboc(dopar((CHAR)stuff));
3725                 if (xx < 0)
3726                   goto outerr;
3727 #ifdef COMMENT
3728                 if (seslog && duplex) { /* Log stuffed char if appropriate */
3729                     logchar((char)stuff);
3730                 }
3731 #endif /* COMMENT */
3732             }
3733             if (stuff2 > -1) {          /* Stuffing another character... */
3734                 xx = oboc(dopar((CHAR)stuff2));
3735                 if (xx < 0)
3736                   goto outerr;
3737 #ifdef COMMENT
3738                 if (seslog && duplex) { /* Log stuffed char if appropriate */
3739                     logchar((char)stuff2);
3740                 }
3741 #endif /* COMMENT */
3742             }
3743             if (xxout(obuf,obn) < 0)    /* Flushing is required here! */
3744               goto outerr;
3745         }
3746     }
3747     if (cx == XXLNOUT) {
3748         s = "\015";
3749         cx = 0;
3750         goto outagain;
3751     }
3752     if (quote == 1)                     /* String ended with backslash */
3753       xx = oboc(dopar(CMDQ));
3754
3755     if (obn > 0)                        /* OUTPUT done */
3756       if (xxout(obuf,obn) < 0)          /* Flush the buffer if necessary. */
3757         goto outerr;
3758     return(1);
3759
3760 outerr:                                 /* OUTPUT command error handler */
3761     if (msgflg) printf("?OUTPUT execution error\n");
3762     return(0);
3763
3764 /* Remove "local" OUTPUT macro defininitions */
3765
3766 #ifdef COMMENT
3767 /* No more macros ... */
3768 #undef oboc
3769 #undef obfls
3770 #endif /* COMMENT */
3771 }
3772 #endif /* NOSPL */
3773
3774 /* Display version herald and initial prompt */
3775
3776 VOID
3777 herald() {
3778     int x = 0, i;
3779     extern int srvcdmsg;
3780     extern char * cdmsgfile[];
3781     char * ssl;
3782     char * krb4;
3783     char * krb5;
3784
3785 #ifndef NOCMDL
3786     extern char * bannerfile;
3787     debug(F110,"herald bannerfile",bannerfile,0);
3788     if (bannerfile) {
3789         concb((char)escape);
3790         if (dotype(bannerfile,1,0,0,NULL,0,NULL,0,0,NULL,0) > 0) {
3791             debug(F111,"herald","srvcdmsg",srvcdmsg);
3792             if (srvcdmsg) {
3793                 for (i = 0; i < 8; i++) {
3794                     debug(F111,"herald cdmsgfile[i]",cdmsgfile[i],i);
3795                     if (zchki(cdmsgfile[i]) > -1) {
3796                         printf("\n");
3797                         dotype(cdmsgfile[i],
3798                                xaskmore,0,0,NULL,0,NULL,0,0,NULL,0);
3799                         break;
3800                     }
3801                 }
3802             }
3803             return;
3804         }
3805     }
3806 #endif /* NOCMDL */
3807
3808 #ifdef COMMENT
3809     /* The following generates bad code in SCO compilers. */
3810     /* Observed in both OSR5 and Unixware 2 -- after executing this */
3811     /* statement when all conditions are false, x has a value of -32. */
3812     if (noherald || quiet || bgset > 0 || (bgset != 0 && backgrd != 0))
3813       x = 1;
3814 #else
3815     x = 0;
3816     if (noherald || quiet)
3817       x = 1;
3818     else if (bgset > 0)
3819       x = 1;
3820     else if (bgset < 0 && backgrd > 0)
3821       x = 1;
3822 #endif /* COMMENT */
3823
3824     ssl = "";
3825     krb4 = "";
3826     krb5 = "";
3827 #ifdef CK_AUTHENTICATION
3828 #ifdef CK_SSL    
3829     ssl = "+SSL";
3830 #endif  /* CK_SSL */
3831 #ifdef KRB4
3832     krb4 = "+KRB4";
3833 #endif  /* KRB4 */
3834 #ifdef KRB5
3835     krb5 = "+KRB5";
3836 #endif  /* KRB5 */
3837 #endif  /* CK_AUTHENTICATION */
3838
3839     if (x == 0) {
3840 #ifdef datageneral
3841         printf("%s, for%s\n",versio,ckxsys);
3842 #else
3843 #ifdef OSK
3844         printf("%s, for%s\n",versio,ckxsys);
3845 #else
3846 #ifdef CK_64BIT
3847         printf("%s, for%s%s%s%s (64-bit)\n\r",versio,ckxsys,ssl,krb4,krb5);
3848 #else
3849         printf("%s, for%s%s%s%s\n\r",versio,ckxsys,ssl,krb4,krb5);
3850 #endif/* CK_64BIT */
3851 #endif /* OSK */
3852 #endif /* datageneral */
3853         printf(" Copyright (C) 1985, %s,\n", ck_cryear);
3854         printf("  Trustees of Columbia University in the City of New York.\n");
3855 #ifdef OS2
3856        shoreg();
3857 #endif /* OS2 */
3858
3859         if (!quiet && !backgrd) {
3860 #ifdef COMMENT
3861 /* "Default file-transfer mode is AUTOMATIC" is useless information... */
3862             char * s;
3863             extern int xfermode;
3864 #ifdef VMS
3865             s = "AUTOMATIC";
3866 #else
3867             if (xfermode == XMODE_A) {
3868                 s = "AUTOMATIC";
3869             } else {
3870                 s = gfmode(binary,1);
3871             }
3872             if (!s) s = "";
3873 #endif /* VMS */
3874             if (*s)
3875               printf("Default file-transfer mode is %s\n", s);
3876 #endif /* COMMENT */
3877
3878             debug(F111,"herald","srvcdmsg",srvcdmsg);
3879             if (srvcdmsg) {
3880                 for (i = 0; i < 8; i++) {
3881                     debug(F111,"herald cdmsgfile[i]",cdmsgfile[i],i);
3882                     if (zchki(cdmsgfile[i]) > -1) {
3883                         printf("\n");
3884                         dotype(cdmsgfile[i],
3885                                xaskmore,0,0,NULL,0,NULL,0,0,NULL,0);
3886                         break;
3887                     }
3888                 }
3889             }
3890             printf("Type ? or HELP for help.\n");
3891         }
3892     }
3893 }
3894
3895 /*  G F M O D E  --  Get File (transfer) Mode  */
3896
3897 char *
3898 gfmode(binary,upcase) int binary, upcase; {
3899     char * s;
3900     switch (binary) {
3901       case XYFT_T: s = upcase ? "TEXT" : "text"; break;
3902 #ifdef VMS
3903       case XYFT_B: s = upcase ? "BINARY FIXED" : "binary fixed"; break;
3904       case XYFT_I: s = upcase ? "IMAGE" : "image"; break;
3905       case XYFT_L: s = upcase ? "LABELED" : "labeled"; break;
3906       case XYFT_U: s = upcase ? "BINARY UNDEF" : "binary undef"; break;
3907 #else
3908 #ifdef MAC
3909       case XYFT_B: s = upcase ? "BINARY" : "binary"; break;
3910       case XYFT_M: s = upcase ? "MACBINARY" : "macbinary"; break;
3911 #else
3912       case XYFT_B: s = upcase ? "BINARY" : "binary"; break;
3913 #ifdef CK_LABELED
3914       case XYFT_L: s = upcase ? "LABELED" : "labeled"; break;
3915 #endif /* CK_LABELED */
3916 #endif /* MAC */
3917 #endif /* VMS */
3918       case XYFT_X: s = upcase ? "TENEX" : "tenex"; break;
3919       default: s = "";
3920     }
3921     return(s);
3922 }
3923
3924 #ifndef NOSPL
3925 static int
3926 isaa(s) char * s; {                     /* Is associative array */
3927     char c;
3928     int x;
3929     if (!s) s = "";
3930     if (!*s) return(0);
3931     s++;
3932     while ((c = *s++)) {
3933         if (c == '<') {
3934             x = strlen(s);
3935             return ((*(s+x-1) == '>') ? 1 : 0);
3936         }
3937     }
3938     return(0);
3939 }
3940
3941 /*  M L O O K  --  Lookup the macro name in the macro table  */
3942
3943 /*
3944   Call this way:  v = mlook(table,word,n);
3945
3946     table - a 'struct mtab' table.
3947     word  - the target string to look up in the table.
3948     n     - the number of elements in the table.
3949
3950   The keyword table must be arranged in ascending alphabetical order, and
3951   all letters must be lowercase.
3952
3953   Returns the table index, 0 or greater, if the name was found, or:
3954
3955    -3 if nothing to look up (target was null),
3956    -2 if ambiguous,
3957    -1 if not found.
3958
3959   A match is successful if the target matches a keyword exactly, or if
3960   the target is a prefix of exactly one keyword.  It is ambiguous if the
3961   target matches two or more keywords from the table.
3962 */
3963 int
3964 mlook(table,cmd,n) struct mtab table[]; char *cmd; int n; {
3965     register int i;
3966     int v, w, cmdlen = 0;
3967     char c = 0, c1, * s;
3968     if (!cmd) cmd = "";
3969
3970     for (s = cmd; *s; s++) cmdlen++;    /* (instead of strlen) */
3971     debug(F111,"MLOOK",cmd,cmdlen);
3972
3973     c1 = *cmd;
3974     if (isupper(c1))
3975       c1 = tolower(c1);
3976     if (cmdlen < 1)
3977       return(-3);
3978
3979 /* Not null, look it up */
3980
3981     if (n < 12) {                       /* Not worth it for small tables */
3982         i = 0;
3983     } else {                            /* Binary search for where to start */
3984         int lo = 0;
3985         int hi = n;
3986         int count = 0;
3987         while (lo+2 < hi && ++count < 12) {
3988             i = lo + ((hi - lo) / 2);
3989             c = *(table[i].kwd);
3990             if (isupper(c)) c = tolower(c);
3991             if (c < c1) {
3992                 lo = i;
3993             } else {
3994                 hi = i;
3995             }
3996         }
3997         i = (c < c1) ? lo+1 : lo;
3998     }
3999     for ( ; i < n-1; i++) {
4000         s = table[i].kwd;
4001         if (!s) s = "";
4002         if (!*s) continue;              /* Empty table entry */
4003         c = *s;
4004         if (isupper(c)) c = tolower(c);
4005         if (c1 != c) continue;          /* First char doesn't match */
4006         if (!ckstrcmp(s,cmd,-1,0))      /* Have exact match? */
4007           return(i);
4008         v = !ckstrcmp(s,cmd,cmdlen,0);
4009         w = ckstrcmp(table[i+1].kwd,cmd,cmdlen,0);
4010         if (v && w)                     /* Have abbreviated match? */
4011           return(i);
4012         if (v)                          /* Ambiguous? */
4013           return(-2);
4014         if (w > 0)                      /* Past our alphabetic area? */
4015           return(-1);
4016     }
4017
4018 /* Last (or only) element */
4019
4020     if (!ckstrcmp(table[n-1].kwd,cmd,cmdlen,0))
4021       return(n-1);
4022
4023     return(-1);
4024 }
4025
4026 /* mxlook is like mlook, but an exact full-length match is required */
4027
4028 int
4029 mxlook(table,cmd,n) char *cmd; struct mtab table[]; int n; {
4030     register int i;
4031     int w, cmdlen = 0, one = 0;
4032     register char c = 0, c1, * s;
4033
4034     if (!cmd) cmd = "";                 /* Check args */
4035
4036     for (s = cmd; *s; s++) cmdlen++;    /* (instead of strlen) */
4037     debug(F111,"MXLOOK",cmd,cmdlen);
4038
4039     c1 = *cmd;                          /* First char of string to look up */
4040     if (isupper(c1))
4041       c1 = tolower(c1);
4042     if (!*(cmd+1))                      /* Special handling for 1-char names */
4043       one = 1;
4044
4045     if (cmdlen < 1)                     /* Nothing to look up */
4046       return(-3);
4047
4048     if (n < 12) {                       /* Not worth it for small tables */
4049         i = 0;
4050     } else {                            /* Binary search for where to start */
4051         int lo = 0;
4052         int hi = n;
4053         int count = 0;
4054         while (lo+2 < hi && ++count < 12) {
4055             i = lo + ((hi - lo) / 2);
4056             c = *(table[i].kwd);
4057             if (isupper(c)) c = tolower(c);
4058             if (c < c1) {
4059                 lo = i;
4060             } else {
4061                 hi = i;
4062             }
4063         }
4064         i = (c < c1) ? lo+1 : lo;
4065     }
4066     for ( ; i < n; i++) {               /* Look thru table */
4067         s = table[i].kwd;               /* This entry */
4068         if (!s) s = "";
4069         if (!*s) continue;              /* Empty table entry */
4070         c = *s;
4071         if (isupper(c)) c = tolower(c);
4072         if (c1 != c) continue;          /* First char doesn't match */
4073         if (one) {                      /* Name is one char long */
4074             if (!*(s+1))
4075               return(i);                /* So is table entry */
4076         }
4077 #ifdef COMMENT
4078         if (((int)strlen(s) == cmdlen) &&
4079             (!ckstrcmp(s,cmd,cmdlen,0))) return(i);
4080 #else
4081         w = ckstrcmp(s,cmd,-1,0);
4082         if (!w) return(i);
4083         if (w > 0) return(-1);
4084 #endif /* COMMENT */
4085     }
4086     return(-1);
4087 }
4088
4089 /* mxxlook is like mxlook, but case-sensitive */
4090
4091 int
4092 mxxlook(table,cmd,n) char *cmd; struct mtab table[]; int n; {
4093     int i, cmdlen;
4094     if (!cmd) cmd = "";
4095     if (((cmdlen = strlen(cmd)) < 1) || (n < 1)) return(-3);
4096     /* debug(F111,"mxxlook target",cmd,n); */
4097     for (i = 0; i < n; i++) {
4098         if (((int)strlen(table[i].kwd) == cmdlen) &&
4099             (!strncmp(table[i].kwd,cmd,cmdlen)))
4100           return(i);
4101     }
4102     return(-1);
4103 }
4104
4105 static int
4106 traceval(nam, val) char * nam, * val; { /* For TRACE command */
4107     if (val)
4108       printf(">>> %s: \"%s\"\n", nam, val);
4109     else
4110       printf(">>> %s: (undef)\n", nam);
4111     return(0);
4112 }
4113
4114 #ifdef USE_VARLEN                       /* Not used */
4115
4116 /*  V A R L E N  --  Get length of variable's value.
4117
4118   Given a variable name, return the length of its definition or 0 if the
4119   variable is not defined.  If it is defined, set argument s to point to its
4120   definition.  Otherwise set s to NULL.
4121 */
4122 int
4123 varlen(nam,s) char *nam; char **s; {    /* Length of value of variable */
4124     int x, z;
4125     char *p = NULL, c;
4126
4127     *s = NULL;
4128     if (!nam) return(0);                /* Watch out for null pointer */
4129     if (*nam == CMDQ) {
4130         nam++;
4131         if (*nam == '%') {              /* If it's a variable name */
4132             if (!(c = *(nam+1))) return(0); /* Get letter or digit */
4133             p = (char *)0;              /* Initialize value pointer */
4134             if (maclvl > -1 && c >= '0' && c <= '9') { /* Digit? */
4135                 p = m_arg[maclvl][c - '0']; /* Pointer from macro-arg table */
4136             } else {                    /* It's a global variable */
4137                 if (c < 33 || c > GVARS) return(0);
4138                 p = g_var[c];           /* Get pointer from global-var table */
4139             }
4140         } else if (*nam == '&') {               /* An array reference? */
4141             char **q;
4142             if (arraynam(nam,&x,&z) < 0) /* If syntax is bad */
4143               return(-1);               /* return -1. */
4144             x -= ARRAYBASE;             /* Convert name to number. */
4145             if ((q = a_ptr[x]) == NULL) /* If array not declared, */
4146               return(0);                /* return -2. */
4147             if (z > a_dim[x])           /* If subscript out of range, */
4148               return(0);                /* return -3. */
4149             p = q[z];
4150         }
4151     } else {                            /* Macro */
4152         z = isaa(nam);
4153         x = z ? mxxlook(mactab,nam,nmac) : mlook(mactab,nam,nmac);
4154         if (x < 0)
4155           return(0);
4156         p = mactab[x].mval;
4157     }
4158     if (p)
4159       *s = p;
4160     else
4161       p = "";
4162     return((int)strlen(p));
4163 }
4164 #endif /* USE_VARLEN */
4165
4166 /*
4167   This routine is for the benefit of those compilers that can't handle
4168   long string constants or continued lines within them.  Long predefined
4169   macros like FOR, WHILE, and XIF have their contents broken up into
4170   arrays of string pointers.  This routine concatenates them back into a
4171   single string again, and then calls the real addmac() routine to enter
4172   the definition into the macro table.
4173 */
4174 int
4175 addmmac(nam,s) char *nam, *s[]; {       /* Add a multiline macro definition */
4176     int i, x, y; char *p;
4177     x = 0;                              /* Length counter */
4178     for (i = 0; (y = (int)strlen(s[i])) > 0; i++) { /* Add up total length */
4179         debug(F111,"addmmac line",s[i],y);
4180         x += y;
4181     }
4182     debug(F101,"addmmac lines","",i);
4183     debug(F101,"addmmac loop exit","",y);
4184     debug(F111,"addmmac length",nam,x);
4185     if (x < 0) return(-1);
4186
4187     p = malloc(x+1);                    /* Allocate space for all of it. */
4188     if (!p) {
4189         printf("?addmmac malloc error: %s\n",nam);
4190         debug(F110,"addmmac malloc error",nam,0);
4191         return(-1);
4192     }
4193     *p = '\0';                          /* Start off with null string. */
4194     for (i = 0; *s[i]; i++)             /* Concatenate them all together. */
4195       ckstrncat(p,s[i],x+1);
4196     y = (int)strlen(p);                 /* Final precaution. */
4197     debug(F111,"addmmac constructed string",p,y);
4198     if (y == x) {
4199         y = addmac(nam,p);              /* Add result to the macro table. */
4200     } else {
4201         debug(F100,"addmmac length mismatch","",0);
4202         printf("\n!addmmac internal error!\n");
4203         y = -1;
4204     }
4205     free(p);                            /* Free the temporary copy. */
4206     return(y);
4207 }
4208
4209 /* Here is the real addmac routine. */
4210
4211 /* Returns -1 on failure, macro table index >= 0 on success. */
4212
4213 int mtchanged = 0;
4214
4215 int
4216 addmac(nam,def) char *nam, *def; {      /* Add a macro to the macro table */
4217     int i, x, y, z, namlen, deflen, flag = 0;
4218     int replacing = 0, deleting = 0;
4219     char * p = NULL, c, *s;
4220     extern int tra_asg; int tra_tmp;
4221
4222     if (!nam) return(-1);
4223     if (!*nam) return(-1);
4224
4225 #ifdef IKSD
4226     if (inserver &&
4227 #ifdef IKSDCONF
4228         iksdcf
4229 #else /* IKSDCONF */
4230         1
4231 #endif /* IKSDCONF */
4232         ) {
4233         if (!ckstrcmp("on_exit",nam,-1,0) ||
4234             !ckstrcmp("on_logout",nam,-1,0))
4235           return(-1);
4236     }
4237 #endif /* IKSD */
4238
4239     namlen = 0;
4240     p = nam;
4241     while (*p++) namlen++;              /* (instead of strlen) */
4242
4243     tra_tmp = tra_asg;                  /* trace... */
4244     debug(F111,"addmac nam",nam,namlen);
4245     if (!def) {                         /* Watch out for null pointer */
4246         deflen = 0;
4247         debug(F111,"addmac def","(null pointer)",deflen);
4248     } else {
4249         deflen = 0;
4250         p = def;
4251         while (*p++) deflen++;          /* (instead of strlen) */
4252         debug(F010,"addmac def",def,0);
4253     }
4254 #ifdef USE_VARLEN                       /* NOT USED */
4255     /* This does not boost performance much because varlen() does a lot */
4256     x = varlen(nam,&s);
4257     if (x > 0 && x >= deflen) {
4258         strcpy(s,def);                  /* NOT USED */
4259         flag = 1;
4260         p = s;
4261     }
4262 #endif /* USE_VARLEN */
4263
4264     if (*nam == CMDQ) nam++;            /* Backslash quote? */
4265     if (*nam == '%') {                  /* Yes, if it's a variable name, */
4266         if (!(c = *(nam + 1))) return(-1); /* Variable name letter or digit */
4267         if (!flag) {
4268             tra_asg = 0;
4269             delmac(nam,0);              /* Delete any old value. */
4270             tra_asg = tra_tmp;
4271         }
4272         if (deflen < 1) {               /* Null definition */
4273             p = NULL;                   /* Better not malloc or strcpy! */
4274         } else if (!flag) {             /* A substantial definition */
4275             p = malloc(deflen + 1);     /* Allocate space for it */
4276             if (!p) {
4277                 printf("?addmac malloc error 2\n");
4278                 return(-1);
4279             } else strcpy(p,def);       /* Copy def into new space (SAFE) */
4280         }
4281
4282         /* Now p points to the definition, or is a null pointer */
4283
4284         if (c >= '0' && c <= '9') {     /* \%0-9 variable */
4285             if (maclvl < 0) {           /* Are we calling or in a macro? */
4286                 g_var[c] = p;           /* No, it's top level one */
4287                 makestr(&(toparg[c - '0']),p); /* Take care \&_[] too */
4288             } else {                    /* Yes, it's a macro argument */
4289                 m_arg[maclvl][c - '0'] = p; /* Assign the value */
4290                 makestr(&(m_xarg[maclvl][c - '0']),p); /* And a copy here */
4291             }
4292         } else {                        /* It's a \%a-z variable */
4293             if (c < 33 || (unsigned int)c > GVARS) return(-1);
4294             if (isupper(c)) c = (char) tolower(c);
4295             g_var[c] = p;               /* Put pointer in global-var table */
4296         }
4297         if (tra_asg) traceval(nam,p);
4298         return(0);
4299     } else if (*nam == '&') {           /* An array reference? */
4300         char **q = NULL;
4301         int rc = 0;
4302         if ((y = arraynam(nam,&x,&z)) < 0) /* If syntax is bad */
4303           return(-1);                   /* return -1. */
4304         if (chkarray(x,z) < 0)          /* If array not declared or */
4305           rc = -2;                      /* subscript out of range, ret -2 */
4306         if (!flag) {
4307             tra_asg = 0;
4308             delmac(nam,0);              /* Delete any old value. */
4309             tra_asg = tra_tmp;
4310         }
4311         x -= ARRAYBASE;                 /* Convert name letter to index. */
4312         if (x > 'z' - ARRAYBASE + 1)
4313           rc = -1;
4314         if (rc != -1) {
4315             if ((q = a_ptr[x]) == NULL) /* If array not declared, */
4316               return(-3);               /* return -3. */
4317         }
4318         if (rc < 0)
4319           return(rc);
4320         if (!flag) {
4321             if (deflen > 0) {
4322                 if ((p = malloc(deflen+1)) == NULL) { /* Allocate space */
4323                     printf("addmac macro error 7: %s\n",nam);
4324                     return(-4);         /* for new def, return -4 on fail. */
4325                 }
4326                 strcpy(p,def);          /* Copy def into new space (SAFE). */
4327             } else p = NULL;
4328         }
4329         q[z] = p;                       /* Store pointer to it. */
4330         if (x == 0) {                   /* Arg vector array */
4331             if (z >= 0 && z <= 9) {     /* Copy values to corresponding  */
4332                 if (maclvl < 0) {       /* \%1..9 variables. */
4333                     makestr(&(toparg[z]),p);
4334                 } else {
4335                     makestr(&(m_arg[maclvl][z]),p);
4336                 }
4337             }
4338         }
4339         if (tra_asg) traceval(nam,p);
4340         return(0);                      /* Done. */
4341     }
4342
4343 /* Not a macro argument or a variable, so it's a macro definition */
4344
4345 #ifdef USE_VARLEN
4346     if (flag) {
4347         if (tra_asg) traceval(nam,p);
4348         return(0);
4349     }
4350 #endif /* USE_VARLEN */
4351     x = isaa(nam) ?                     /* If it's an associative array */
4352       mxxlook(mactab,nam,nmac) :        /* look it up this way */
4353         mxlook(mactab,nam,nmac);        /* otherwise this way. */
4354     if (x > -1) {                       /* If found... */
4355         if (deflen > 0)                 /* and a new definition was given */
4356           replacing = 1;                /* we're replacing */
4357         else                            /* otherwise */
4358           deleting = 1;                 /* we're deleting */
4359     }
4360     if (deleting) {                     /* Deleting... */
4361         if (delmac(nam,0) < 0)
4362           return(-1);
4363         mtchanged++;
4364         if (tra_asg) traceval(nam,p);
4365         return(0);
4366     } else if (deflen < 1)              /* New macro with no definition */
4367       return(0);                        /* Nothing to do. */
4368
4369     if (replacing) {                    /* Replacing an existing macro */
4370         if (mactab[x].mval) {           /* If it currently has a definition, */
4371             free(mactab[x].mval);       /* free it. */
4372             mactab[x].mval = NULL;
4373         }
4374         mtchanged++;
4375         y = x;                          /* Replacement index. */
4376
4377     } else {                            /* Adding a new macro... */
4378         char c1, c2;                    /* Use fast lookup to find the */
4379         c1 = *nam;                      /* alphabetical slot. */
4380         if (isupper(c1)) c1 = (char) tolower(c1);
4381
4382         if (nmac < 5) {                 /* Not worth it for small tables */
4383             y = 0;
4384         } else {                        /* First binary search to find */
4385             int lo = 0;                 /* where to start */
4386             int hi = nmac;
4387             int count = 0;
4388             char c = 0;
4389             while (lo+2 < hi && ++count < 12) {
4390                 y = lo + ((hi - lo) / 2);
4391                 c = *(mactab[y].kwd);
4392                 if (isupper(c)) c = (char) tolower(c);
4393                 if (c < c1) {
4394                     lo = y;
4395                 } else {
4396                     hi = y;
4397                 }
4398             }
4399             y = (c < c1) ? lo+1 : lo;
4400         }
4401         /* Now search linearly from starting location */
4402         for ( ; y < MAC_MAX && mactab[y].kwd != NULL; y++) {
4403             c2 = *(mactab[y].kwd);
4404             if (isupper(c2)) c2 = (char) tolower(c2);
4405             if (c1 > c2)
4406               continue;
4407             if (c1 < c2)
4408               break;
4409             if (ckstrcmp(nam,mactab[y].kwd,-1,0) <= 0)
4410               break;
4411         }
4412         if (y == MAC_MAX) {             /* Macro table is full. */
4413             debug(F101,"addmac table overflow","",y);
4414             printf("?Macro table overflow\n");
4415             return(-1);
4416         }
4417         if (mactab[y].kwd != NULL) {    /* Must insert */
4418             for (i = nmac; i > y; i--) { /* Move the rest down one slot */
4419                 mactab[i].kwd = mactab[i-1].kwd;
4420                 mactab[i].mval = mactab[i-1].mval;
4421                 mactab[i].flgs = mactab[i-1].flgs;
4422             }
4423         }
4424         mtchanged++;
4425         p = malloc(namlen + 1);         /* Allocate space for name */
4426         if (!p) {
4427             printf("?Addmac: Out of memory - \"%s\"\n",nam);
4428             return(-1);
4429         }
4430         strcpy(p,nam);                  /* Copy name into new space (SAFE) */
4431         mactab[y].kwd = p;              /* Add pointer to table */
4432     }
4433     if (deflen > 0) {                   /* If we have a definition */
4434         p = malloc(deflen + 1);         /* Get space */
4435         if (p == NULL) {
4436             printf("?Space exhausted - \"%s\"\n", nam);
4437             if (mactab[y].kwd) {
4438                 free(mactab[y].kwd);
4439                 mactab[y].kwd = NULL;
4440             }
4441             return(-1);
4442         } else {
4443             strcpy(p,def);              /* Copy the definition (SAFE) */
4444         }
4445     } else {                            /* definition is empty */
4446         p = NULL;
4447     }
4448     mactab[y].mval = p;                 /* Macro points to definition */
4449     mactab[y].flgs = 0;                 /* No flags */
4450     if (!replacing)                     /* If new macro */
4451       nmac++;                           /* count it */
4452     if (tra_asg) traceval(nam,p);
4453     return(y);
4454 }
4455
4456 int
4457 xdelmac(x) int x; {                     /* Delete a macro given its index */
4458     int i;
4459     extern int tra_asg;
4460     if (x < 0) return(x);
4461     if (tra_asg)
4462       traceval(mactab[x].kwd,NULL);
4463
4464     if (mactab[x].kwd) {                /* Free the storage for the name */
4465         free(mactab[x].kwd);
4466         mactab[x].kwd = NULL;
4467     }
4468     if (mactab[x].mval) {               /* and for the definition */
4469         free(mactab[x].mval);
4470         mactab[x].mval = NULL;
4471     }
4472     for (i = x; i < nmac; i++) {        /* Now move up the others. */
4473         mactab[i].kwd = mactab[i+1].kwd;
4474         mactab[i].mval = mactab[i+1].mval;
4475         mactab[i].flgs = mactab[i+1].flgs;
4476     }
4477     nmac--;                             /* One less macro */
4478
4479     mactab[nmac].kwd = NULL;            /* Delete last item from table */
4480     mactab[nmac].mval = NULL;
4481     mactab[nmac].flgs = 0;
4482     mtchanged++;
4483     return(0);
4484 }
4485
4486 int
4487 delmac(nam,exact) char *nam; int exact; { /* Delete the named macro */
4488     int x, z;
4489     char *p, c;
4490     extern int tra_asg;
4491
4492     if (!nam) return(0);                /* Watch out for null pointer */
4493     debug(F110,"delmac nam",nam,0);
4494 #ifdef IKSD
4495     if ( inserver &&
4496 #ifdef IKSDCONF
4497         iksdcf
4498 #else /* IKSDCONF */
4499         1
4500 #endif /* IKSDCONF */
4501         ) {
4502         if (!ckstrcmp("on_exit",nam,-1,0) ||
4503             !ckstrcmp("on_logout",nam,-1,0))
4504           return(-1);
4505     }
4506 #endif /* IKSD */
4507
4508     if (*nam == CMDQ) nam++;
4509     if (*nam == '%') {                  /* If it's a variable name */
4510         if (!(c = *(nam+1))) return(0); /* Get variable name letter or digit */
4511         p = (char *)0;                  /* Initialize value pointer */
4512         if (maclvl < 0 && c >= '0' && c <= '9') { /* Top-level digit? */
4513             p = toparg[c - '0'];
4514             if (p) if (p != g_var[c]) {
4515                 free(p);
4516                 toparg[c - '0'] = NULL;
4517             }
4518             p = g_var[c];
4519             g_var[c] = NULL;            /* Zero the table entry */
4520         } else if (maclvl > -1 && c >= '0' && c <= '9') { /* Digit? */
4521             p = m_xarg[maclvl][c - '0'];
4522             if (p) if (p != g_var[c]) {
4523                 free(p);
4524                 m_xarg[maclvl][c - '0'] = NULL;
4525             }
4526             p = m_arg[maclvl][c - '0']; /* Get pointer from macro-arg table */
4527             m_arg[maclvl][c - '0'] = NULL; /* Zero the table pointer */
4528         } else {                        /* It's a global variable */
4529             if (c < 33 || (unsigned int)c > GVARS) return(0);
4530             p = g_var[c];               /* Get pointer from global-var table */
4531             g_var[c] = NULL;            /* Zero the table entry */
4532         }
4533         if (p) {
4534             debug(F010,"delmac def",p,0);
4535             free(p);                    /* Free the storage */
4536             p = NULL;
4537         } else debug(F110,"delmac def","(null pointer)",0);
4538         if (tra_asg) traceval(nam,NULL);
4539         return(0);
4540     }
4541     if (*nam == '&') {                  /* An array reference? */
4542         char **q;
4543         if (arraynam(nam,&x,&z) < 0)    /* If syntax is bad */
4544           return(-1);                   /* return -1. */
4545         x -= ARRAYBASE;                 /* Convert name to number. */
4546         if ((q = a_ptr[x]) == NULL)     /* If array not declared, */
4547           return(-2);                   /* return -2. */
4548         if (z > a_dim[x])               /* If subscript out of range, */
4549           return(-3);                   /* return -3. */
4550         if (q[z]) {                     /* If there is an old value, */
4551             debug(F010,"delmac def",q[z],0);
4552             if (x != 0)                 /* Macro arg vector is just a copy */
4553               free(q[z]);               /* Others are real so free them */
4554             q[z] = NULL;
4555             if (x == 0) {               /* Arg vector array */
4556                 if (z >= 0 && z <= 9) { /* Copy values to corresponding  */
4557                     if (maclvl < 0) {   /* \%1..9 variables. */
4558                         makestr(&(toparg[z]),NULL);
4559                     } else {
4560                         makestr(&(m_arg[maclvl][z]),NULL);
4561                     }
4562                 }
4563             }
4564             if (tra_asg) traceval(nam,NULL);
4565         } else debug(F010,"delmac def","(null pointer)",0);
4566     }
4567
4568    /* Not a variable or an array, so it must be a macro. */
4569
4570     z = isaa(nam);
4571     debug(F111,"delmac isaa",nam,z);
4572     debug(F111,"delmac exact",nam,exact);
4573     x = z ? mxxlook(mactab,nam,nmac) :
4574       exact ? mxlook(mactab,nam,nmac) :
4575         mlook(mactab,nam,nmac);
4576     if (x < 0) {
4577         debug(F111,"delmac mlook",nam,x);
4578         return(x);
4579     }
4580     return(xdelmac(x));
4581 }
4582
4583 VOID
4584 initmac() {                             /* Init macro & variable tables */
4585     int i, j, x;
4586
4587     nmac = 0;                           /* No macros */
4588     for (i = 0; i < MAC_MAX; i++) {     /* Initialize the macro table */
4589         mactab[i].kwd = NULL;
4590         mactab[i].mval = NULL;
4591         mactab[i].flgs = 0;
4592     }
4593     mtchanged++;
4594     x = (MAXARGLIST + 1) * sizeof(char **);
4595     for (i = 0; i < MACLEVEL; i++) {    /* Init the macro argument tables */
4596         m_xarg[i] = (char **) malloc(x);
4597         mrval[i] = NULL;                /* Macro return value */
4598         /* Pointer to entire argument vector, level i, for \&_[] array */
4599         for (j = 0; j <= MAXARGLIST; j++) { /* Macro argument list */
4600             if (j < 10)                 /* For the \%0..\%9 variables */
4601               m_arg[i][j] = NULL;       /* Pointer to arg j, level i. */
4602             if (m_xarg[i])              /* For \&_[] - all args. */
4603               m_xarg[i][j] = NULL;
4604         }
4605     }
4606     for (i = 0; i < GVARS; i++) {       /* And the global variables table */
4607         g_var[i] = NULL;
4608     }
4609     /* And the table of arrays */
4610     for (i = 0; i < (int) 'z' - ARRAYBASE + 1; i++) {
4611         a_ptr[i] = (char **) NULL;      /* Null pointer for each */
4612         a_dim[i] = 0;                   /* and a dimension of zero */
4613         a_link[i] = -1;
4614         for (j = 0; j < CMDSTKL; j++) {
4615             aa_ptr[j][i] = (char **) NULL;
4616             aa_dim[j][i] = 0;
4617         }
4618     }
4619 }
4620
4621 int
4622 popclvl() {                             /* Pop command level, return cmdlvl */
4623     extern int tra_cmd;
4624     struct localvar * v;
4625     int i, topcmd;
4626     debug(F101,"popclvl cmdlvl","",cmdlvl);
4627     if (cmdlvl > 0) {
4628         if ((v = localhead[cmdlvl])) {  /* Did we save any variables? */
4629             while (v) {                 /* Yes */
4630                 if (v->lv_value)        /* Copy old ones back */
4631                   addmac(v->lv_name,v->lv_value);
4632                 else
4633                   delmac(v->lv_name,1);
4634                 v = v->lv_next;
4635             }
4636             freelocal(cmdlvl);          /* Free local storage */
4637         }
4638         /* Automatic arrays do not use the localhead list */
4639
4640         for (i = 0; i < 28; i++) {      /* Free any local arrays */
4641             if (aa_ptr[cmdlvl][i]) {    /* Does this one exist? */
4642                 dclarray((char)(i+ARRAYBASE),-1); /* Destroy global one */
4643                 a_ptr[i] = aa_ptr[cmdlvl][i];
4644                 a_dim[i] = aa_dim[cmdlvl][i];
4645                 aa_ptr[cmdlvl][i] = (char **)NULL;
4646                 aa_dim[cmdlvl][i] = 0;
4647             } else if (aa_dim[cmdlvl][i] == -23) { /* Secret code */
4648                 dclarray((char)(i+ARRAYBASE),-1); /* (see pusharray()) */
4649                 aa_ptr[cmdlvl][i] = (char **)NULL;
4650                 aa_dim[cmdlvl][i] = 0;
4651             }
4652
4653             /* Otherwise do nothing - it is a local array that was declared */
4654             /* at a level above this one so leave it alone. */
4655         }
4656     }
4657     if (cmdlvl < 1) {                   /* If we're already at top level */
4658         cmdlvl = 0;                     /* just make sure all the */
4659         tlevel = -1;                    /* stack pointers are set right */
4660         maclvl = -1;                    /* and return */
4661     } else if (cmdstk[cmdlvl].src == CMD_TF) { /* Reading from TAKE file? */
4662         debug(F101,"popclvl tlevel","",tlevel);
4663         if (tlevel > -1) {              /* Yes, */
4664             fclose(tfile[tlevel]);      /* close it */
4665
4666             if (tra_cmd)
4667               printf("[%d] -F: \"%s\"\n",cmdlvl,tfnam[tlevel]);
4668             debug(F111,"CMD -F",tfnam[tlevel],cmdlvl);
4669             if (tfnam[tlevel]) {        /* free storage for name */
4670                 free(tfnam[tlevel]);
4671                 tfnam[tlevel] = NULL;
4672             }
4673             tlevel--;                   /* and pop take level */
4674             cmdlvl--;                   /* and command level */
4675             quiet = xquiet[cmdlvl];
4676             vareval = xvarev[cmdlvl];
4677         } else
4678           tlevel = -1;
4679     } else if (cmdstk[cmdlvl].src == CMD_MD) { /* In a macro? */
4680         topcmd = lastcmd[maclvl];
4681         debug(F101,"popclvl maclvl","",maclvl);
4682         if (maclvl > -1) {              /* Yes, */
4683 #ifdef COMMENT
4684             int i;
4685             char **q;
4686 #endif /* COMMENT */
4687             macp[maclvl] = "";          /* set macro pointer to null string */
4688             *cmdbuf = '\0';             /* clear the command buffer */
4689
4690             if ((maclvl > 0) &&         /* 2 May 1999 */
4691                 (m_arg[maclvl-1][0]) &&
4692                 (!strncmp(m_arg[maclvl-1][0],"_xif",4) ||
4693                  !strncmp(m_arg[maclvl-1][0],"_for",4) ||
4694                  !strncmp(m_arg[maclvl-1][0],"_swi",4) ||
4695                  !strncmp(m_arg[maclvl-1][0],"_whi",4)) &&
4696                 mrval[maclvl+1]) {
4697                 makestr(&(mrval[maclvl-1]),mrval[maclvl+1]);
4698             }
4699             if (maclvl+1 < MACLEVEL) {
4700                 if (mrval[maclvl+1]) {  /* Free any deeper return values. */
4701                     free(mrval[maclvl+1]);
4702                     mrval[maclvl+1] = NULL;
4703                 }
4704             }
4705             if (tra_cmd)
4706               printf("[%d] -M: \"%s\"\n",cmdlvl,m_arg[cmdstk[cmdlvl].lvl][0]);
4707             debug(F111,"CMD -M",m_arg[cmdstk[cmdlvl].lvl][0],cmdlvl);
4708
4709             maclvl--;                   /* Pop macro level */
4710             cmdlvl--;                   /* and command level */
4711             debug(F101,"popclvl mac new maclvl","",maclvl);
4712             debug(F010,"popclvl mac mrval[maclvl+1]",mrval[maclvl+2],0);
4713
4714             quiet = xquiet[cmdlvl];
4715             vareval = xvarev[cmdlvl];
4716             if (maclvl > -1) {
4717                 a_ptr[0] = m_xarg[maclvl];
4718                 a_dim[0] = n_xarg[maclvl] - 1;
4719                 debug(F111,"a_dim[0]","B",a_dim[0]);
4720             } else {
4721                 a_ptr[0] = topxarg;
4722                 a_dim[0] = topargc - 1;
4723                 debug(F111,"a_dim[0]","C",a_dim[0]);
4724             }
4725         } else {
4726             maclvl = -1;
4727         }
4728 #ifndef NOSEXP
4729         debug(F101,"popclvl topcmd","",topcmd);
4730         if (topcmd == XXSEXP) {
4731             extern char * sexpval;
4732             makestr(&(mrval[maclvl+1]),sexpval);
4733         }
4734 #endif /* NOSEXP */
4735     } else {
4736         cmdlvl--;
4737     }
4738     debug(F101,"popclvl cmdlvl","",cmdlvl);
4739     if (prstring[cmdlvl]) {
4740         cmsetp(prstring[cmdlvl]);
4741         makestr(&(prstring[cmdlvl]),NULL);
4742     }
4743 #ifndef MAC
4744     if (cmdlvl < 1 || xcmdsrc == CMD_KB) { /* If at prompt */
4745         setint();
4746         concb((char)escape);            /* Go into cbreak mode */
4747     }
4748 #endif /* MAC */
4749     xcmdsrc = cmdstk[cmdlvl].src;
4750     debug(F101,"popclvl xcmdsrc","",xcmdsrc);
4751     debug(F101,"popclvl tlevel","",tlevel);
4752     return(cmdlvl < 1 ? 0 : cmdlvl);    /* Return command level */
4753 }
4754 #else /* No script programming language */
4755 int popclvl() {                         /* Just close current take file. */
4756     if (tlevel > -1) {                  /* if any... */
4757         if (tfnam[tlevel]) {
4758             free(tfnam[tlevel]);
4759             tfnam[tlevel] = NULL;
4760         }
4761         fclose(tfile[tlevel--]);
4762     }
4763     if (tlevel == -1) {                 /* And if back at top level */
4764         setint();
4765         concb((char)escape);            /* and go back into cbreak mode. */
4766     }
4767     xcmdsrc = tlevel > -1 ? CMD_TF : 0;
4768     return(tlevel + 1);
4769 }
4770 #endif /* NOSPL */
4771
4772
4773 #ifndef NOSPL
4774 static int
4775 iseom(m) char * m; {                    /* Test if at end of macro def */
4776     if (!m)
4777       m = "";
4778     debug(F111,"iseom",m,maclvl);
4779     while (*m) {
4780         /* Anything but Space and Comma means more macro is left */
4781         if ((*m > SP) && (*m != ',')) {
4782             debug(F111,"iseom return",m,0);
4783             return(0);
4784         }
4785         m++;
4786     }
4787     debug(F111,"iseom return",m,1);
4788     return(1);                          /* Nothing left */
4789 }
4790 #endif /* NOSPL */
4791
4792 /* Pop all command levels that can be popped */
4793
4794 int
4795 prepop() {
4796     if (cmdlvl > 0) {                   /* If command level is > 0 and... */
4797         while (
4798 #ifndef NOSPL
4799                ((cmdstk[cmdlvl].src == CMD_TF) && /* Command source is file */
4800 #endif /* NOSPL */
4801             (tlevel > -1) &&
4802             feof(tfile[tlevel]))        /* And at end of file... */
4803 #ifndef NOSPL
4804                /* Or command source is macro... */
4805                || ((cmdstk[cmdlvl].src == CMD_MD) &&
4806                 (maclvl > -1) &&
4807                 iseom(macp[maclvl])))  /* and at end of macro, then... */
4808 #endif /* NOSPL */
4809         {
4810               popclvl();                /* pop command level. */
4811         }
4812     }
4813     return(cmdlvl < 1 ? 0 : cmdlvl);    /* Return command level */
4814 }
4815
4816 /* STOP - get back to C-Kermit prompt, no matter where from. */
4817
4818 int
4819 dostop() {
4820     extern int cmddep;
4821     while (popclvl()) ;         /* Pop all macros & take files */
4822 #ifndef NOSPL
4823     if (cmddep > -1)            /* And all recursive cmd pkg invocations */
4824       while (cmpop() > -1) ;
4825 #endif /* NOSPL */
4826     cmini(ckxech);              /* Clear the command buffer. */
4827     return(0);
4828 }
4829
4830 /* Close the given log */
4831
4832 int
4833 doclslog(x) int x; {
4834     int y;
4835     switch (x) {
4836 #ifdef DEBUG
4837       case LOGD:
4838         if (deblog <= 0) {
4839             printf("?Debugging log wasn't open\n");
4840             return(0);
4841         }
4842         debug(F100,"Debug Log Closed","",0L);
4843         *debfil = '\0';
4844         deblog = 0;
4845         return(zclose(ZDFILE));
4846 #endif /* DEBUG */
4847
4848 #ifndef NOXFER
4849       case LOGP:
4850         if (pktlog <= 0) {
4851             printf("?Packet log wasn't open\n");
4852             return(0);
4853         }
4854         *pktfil = '\0';
4855         pktlog = 0;
4856         return(zclose(ZPFILE));
4857 #endif /* NOXFER */
4858
4859 #ifndef NOLOCAL
4860       case LOGS:
4861         if (seslog <= 0) {
4862             printf("?Session log wasn't open\n");
4863             return(0);
4864         }
4865         *sesfil = '\0';
4866         setseslog(0);
4867         return(zclose(ZSFILE));
4868 #endif /* NOLOCAL */
4869
4870 #ifdef TLOG
4871       case LOGT: {
4872 #ifdef IKSD
4873           extern int iklogopen, xferlog;
4874 #endif /* IKSD */
4875           if (tralog <= 0
4876 #ifdef IKSD
4877               && !iklogopen
4878 #endif /* IKSD */
4879               ) {
4880               if (msgflg)
4881                 printf("?Transaction log wasn't open\n");
4882               return(0);
4883           }
4884 #ifdef IKSD
4885           if (iklogopen && !inserver) {
4886               close(xferlog);
4887               iklogopen = 0;
4888           }
4889 #endif /* IKSD */
4890           if (tralog) {
4891               tlog(F100,"Transaction Log Closed","",0L);
4892               zclose(ZTFILE);
4893           }
4894           *trafil = '\0';
4895           tralog = 0;
4896           return(1);
4897       }
4898 #endif /* TLOG */
4899
4900 #ifdef CKLOGDIAL
4901       case LOGM:
4902         if (dialog <= 0) {
4903             if (msgflg) printf("?Connection log wasn't open\n");
4904             return(0);
4905         }
4906         *diafil = '\0';
4907         dialog = 0;
4908         return(zclose(ZDIFIL));
4909 #endif /* CKLOGDIAL */
4910
4911 #ifndef NOSPL
4912       case LOGW:                        /* WRITE file */
4913       case LOGR:                        /* READ file */
4914         y = (x == LOGR) ? ZRFILE : ZWFILE;
4915         if (chkfn(y) < 1)               /* If no file to close */
4916           return(1);                    /* succeed silently. */
4917         return(zclose(y));              /* Otherwise, close the file. */
4918 #endif /* NOSPL */
4919
4920       default:
4921         printf("\n?Unexpected log designator - %d\n", x);
4922         return(0);
4923     }
4924 }
4925
4926 static int slc = 0;                     /* Screen line count */
4927
4928 char *
4929 showstring(s) char * s; {
4930     return(s ? s : "(null)");
4931 }
4932
4933 char *
4934 showoff(x) int x; {
4935     return(x ? "on" : "off");
4936 }
4937
4938 char *
4939 showooa(x) int x; {
4940     switch (x) {
4941       case SET_OFF:  return("off");
4942       case SET_ON:   return("on");
4943       case SET_AUTO: return("automatic");
4944       default:       return("(unknown)");
4945     }
4946 }
4947
4948 #ifdef GEMDOS
4949 isxdigit(c) int c; {
4950     return(isdigit(c) ||
4951            (c >= 'a' && c <= 'f') ||
4952            (c >= 'A' && c <= 'F'));
4953 }
4954 #endif /* GEMDOS */
4955
4956 #ifndef NOSETKEY
4957 #ifdef OS2
4958 static struct keytab shokeytab[] = {    /* SHOW KEY modes */
4959     "all",    1, 0,
4960     "one",    0, 0
4961 };
4962 static int nshokey = (sizeof(shokeytab) / sizeof(struct keytab));
4963
4964 #define SHKEYDEF TT_MAX+5
4965 struct keytab shokeymtab[] = {
4966     "aaa",       TT_AAA,     CM_INV,    /* AnnArbor */
4967     "adm3a",     TT_ADM3A,   0,         /* LSI ADM-3A */
4968     "adm5",      TT_ADM5,    0,         /* LSI ADM-5 */
4969     "aixterm",   TT_AIXTERM, 0,         /* IBM AIXterm */
4970     "annarbor",  TT_AAA,     0,         /* AnnArbor */
4971     "ansi-bbs",  TT_ANSI,    0,         /* ANSI.SYS (BBS) */
4972     "at386",     TT_AT386,   0,         /* Unixware ANSI */
4973     "avatar/0+", TT_ANSI,    0,         /* AVATAR/0+ */
4974     "ba80",      TT_BA80,    0,         /* Nixdorf BA80 */
4975     "be",        TT_BEOS,    CM_INV|CM_ABR,
4976     "beos-ansi", TT_BEOS,    CM_INV,    /* BeOS ANSI */
4977     "beterm",    TT_BEOS,    0,         /* BeOS Console */
4978     "d200",      TT_DG200,   CM_INV|CM_ABR, /* Data General DASHER 200 */
4979     "d210",      TT_DG210,   CM_INV|CM_ABR, /* Data General DASHER 210 */
4980     "d217",      TT_DG217,   CM_INV|CM_ABR, /* Data General DASHER 217 */
4981     "default",   SHKEYDEF,   0,
4982     "dg200",     TT_DG200,   0,         /* Data General DASHER 200 */
4983     "dg210",     TT_DG210,   0,         /* Data General DASHER 210 */
4984     "dg217",     TT_DG217,   0,         /* Data General DASHER 217 */
4985     "emacs",     TT_KBM_EMACS,   0,     /* Emacs mode */
4986     "h19",       TT_H19,     CM_INV,    /* Heath-19 */
4987     "heath19",   TT_H19,     0,         /* Heath-19 */
4988     "hebrew",    TT_KBM_HEBREW, 0,      /* Hebrew mode */
4989     "hft",       TT_HFT,     0,         /* IBM HFT */
4990     "hp2621a",   TT_HP2621,  0,         /* HP 2621A */
4991     "hpterm",    TT_HPTERM,  0,         /* HP TERM */
4992     "hz1500",    TT_HZL1500, 0,         /* Hazeltine 1500 */
4993     "ibm3151",   TT_IBM31,   0,         /* IBM 3101-xx,3161 */
4994     "linux",     TT_LINUX,   0,         /* Linux */
4995     "qansi",     TT_QANSI,   0,         /* QNX ANSI */
4996     "qnx",       TT_QNX,     0,         /* QNX */
4997     "russian",   TT_KBM_RUSSIAN, 0,     /* Russian mode */
4998     "scoansi",   TT_SCOANSI, 0,         /* SCO ANSI */
4999     "sni-97801", TT_97801,   0,         /* Sinix 97801 */
5000     "sun",       TT_SUN,     0,         /* Sun Console */
5001 #ifdef OS2PM
5002 #ifdef COMMENT
5003     "tek4014", TT_TEK40, 0,
5004 #endif /* COMMENT */
5005 #endif /* OS2PM */
5006     "tty",     TT_NONE,  0,
5007     "tvi910+", TT_TVI910, 0,
5008     "tvi925",  TT_TVI925, 0,
5009     "tvi950",  TT_TVI950, 0,
5010     "vc404",   TT_VC4404, 0,
5011     "vc4404",  TT_VC4404, CM_INV,
5012     "vip7809", TT_VIP7809, 0,
5013     "vt100",   TT_VT100, 0,
5014     "vt102",   TT_VT102, 0,
5015     "vt220",   TT_VT220, 0,
5016     "vt220pc", TT_VT220PC, 0,
5017     "vt320",   TT_VT320, 0,
5018     "vt320pc", TT_VT320PC, 0,
5019     "vt52",    TT_VT52,  0,
5020     "wp",      TT_KBM_WP, 0,
5021     "wy160",   TT_WY160,  0,
5022     "wy30",    TT_WY30,  0,
5023     "wy370",   TT_WY370, 0,
5024     "wy50",    TT_WY50,  0,
5025     "wy60",    TT_WY60,  0,
5026     "wyse30",  TT_WY30,  CM_INV,
5027     "wyse370", TT_WY370, CM_INV,
5028     "wyse50",  TT_WY50,  CM_INV,
5029     "wyse60",  TT_WY60,  CM_INV
5030 };
5031 int nshokeym = (sizeof(shokeymtab) / sizeof(struct keytab));
5032 #endif /* OS2 */
5033
5034 VOID
5035 #ifdef OS2
5036 shokeycode(c,m) int c, m;
5037 #else
5038 shokeycode(c) int c;
5039 #endif
5040 /* shokeycode */ {
5041     KEY ch;
5042     CHAR *s;
5043 #ifdef OS2
5044     int i;
5045     con_event km;
5046 #else /* OS2 */
5047     int km;
5048 #endif /* OS2 */
5049
5050 #ifdef OS2
5051     extern int mskkeys;
5052     char * mstr = "";
5053
5054     if (c >= KMSIZE) {
5055         bleep(BP_FAIL);
5056         return;
5057     }
5058 #else /* OS2 */
5059     printf(" Key code \\%d => ", c);
5060 #endif /* OS2 */
5061
5062 #ifndef OS2
5063     km = mapkey(c);
5064
5065 #ifndef NOKVERBS
5066     if (IS_KVERB(km)) {                 /* \Kverb? */
5067         int i, kv;
5068         kv = km & ~(F_KVERB);
5069         printf("Verb: ");
5070         for (i = 0; i < nkverbs; i++)
5071           if (kverbs[i].kwval == kv) {
5072               printf("\\K%s",kverbs[i].kwd);
5073               break;
5074           }
5075         printf("\n");
5076     } else
5077 #endif /* NOKVERBS */
5078       if (IS_CSI(km)) {
5079           int xkm = km & 0xFF;
5080           if (xkm <= 32 || xkm >= 127)
5081             printf("String: \\{27}[\\{%d}\n",xkm);
5082           else
5083             printf("String: \\{27}[%c\n",xkm);
5084       } else if (IS_ESC(km)) {
5085           int xkm = km & 0xFF;
5086           if (xkm <= 32 || xkm >= 127)
5087             printf("String: \\{27}\\{%d}\n",xkm);
5088           else
5089             printf("String: \\{27}%c\n",xkm);
5090       } else if (macrotab[c]) {         /* See if there's a macro */
5091           printf("String: ");           /* If so, display its definition */
5092           s = macrotab[c];
5093           shostrdef(s);
5094           printf("\n");
5095 #ifndef NOKVERBS
5096     } else if (km >= 0x100) {           /* This means "undefined" */
5097         printf("Undefined\n");
5098 #endif /* NOKVERBS */
5099     } else {                            /* No macro, show single character */
5100         printf("Character: ");
5101         ch = km;
5102         if (ch < 32 || ch == 127
5103 #ifdef OS2
5104             || ch > 255
5105 #endif /* OS2 */
5106 #ifndef NEXT
5107 #ifndef AUX
5108 #ifndef XENIX
5109 #ifndef OS2
5110             || (ch > 127 && ch < 160)
5111 #endif /* OS2 */
5112 #endif /* XENIX */
5113 #endif /* AUX */
5114 #endif /* NEXT */
5115             )
5116 /*
5117   These used to be %d, but gcc 1.93 & later complain about type mismatches.
5118   %u is supposed to be totally portable.
5119 */
5120           printf("\\%u",(unsigned int) ch);
5121         else printf("%c \\%u",(CHAR) (ch & 0xff),(unsigned int) ch);
5122         if (ch == (KEY) c)
5123           printf(" (self, no translation)\n");
5124         else
5125           printf("\n");
5126     }
5127 #else /* OS2 */
5128     if (m < 0) {
5129         km = mapkey(c);
5130         mstr = "default";
5131     } else {
5132         km = maptermkey(c,m);
5133         for (i = 0; i < nshokeym; i++) {
5134             if (m == shokeymtab[i].kwval) {
5135                 mstr = shokeymtab[i].kwd;
5136                 break;
5137             }
5138         }
5139     }
5140     s = keyname(c);
5141     debug(F111,"shokeycode mstr",mstr,m);
5142     debug(F111,"shokeycode keyname",s,c);
5143     printf(" %sKey code \\%d %s (%s) => ",
5144             mskkeys ? "mskermit " : "",
5145             mskkeys ? cktomsk(c) : c,
5146             s == NULL ? "" : s, mstr);
5147
5148     switch (km.type) {
5149 #ifndef NOKVERBS
5150       case kverb: {
5151           int i, kv;
5152           kv = km.kverb.id & ~(F_KVERB);
5153           printf("Verb: ");
5154           for (i = 0; i < nkverbs; i++) {
5155               if (kverbs[i].kwval == kv) {
5156                   printf("\\K%s",kverbs[i].kwd);
5157                   break;
5158               }
5159           }
5160           printf("\n");
5161           break;
5162       }
5163 #endif /* NOKVERBS */
5164       case csi: {
5165           int xkm = km.csi.key & 0xFF;
5166           if (xkm <= 32 || xkm >= 127)
5167             printf("String: \\{27}[\\{%d}\n",xkm);
5168           else
5169             printf("String: \\{27}[%c\n",xkm);
5170           break;
5171       }
5172       case esc: {
5173           int xkm = km.esc.key & 0xFF;
5174           if (xkm <= 32 || xkm >= 127)
5175             printf("String: \\{%d}\\{%d}\n",ISDG200(tt_type)?30:27,xkm);
5176           else
5177             printf("String: \\{%d}%c\n",ISDG200(tt_type)?30:27,xkm);
5178           break;
5179       }
5180       case macro: {
5181           printf("String: ");           /* Macro, display its definition */
5182           shostrdef(km.macro.string);
5183           printf("\n");
5184           break;
5185       }
5186       case literal: {
5187           printf("Literal string: ");   /* Literal, display its definition */
5188           shostrdef(km.literal.string);
5189           printf("\n");
5190           break;
5191       }
5192       case error: {
5193           if (c >= 0x100) {
5194               printf("Undefined\n");
5195           } else {
5196               printf("Character: ");
5197               ch = c;
5198               if (ch < 32 || ch == 127 || ch > 255
5199 #ifndef NEXT
5200 #ifndef AUX
5201 #ifndef XENIX
5202 #ifndef OS2
5203                    || (ch > 127 && ch < 160)
5204 #endif /* OS2 */
5205 #endif /* XENIX */
5206 #endif /* AUX */
5207 #endif /* NEXT */
5208                    )
5209 /*
5210   These used to be %d, but gcc 1.93 & later complain about type mismatches.
5211   %u is supposed to be totally portable.
5212 */
5213                   printf("\\%u",(unsigned int) ch);
5214               else printf("%c \\%u",(CHAR) (ch & 0xff),(unsigned int) ch);
5215               printf(" (self, no translation)\n");
5216           }
5217           break;
5218       }
5219       case key: {
5220           printf("Character: ");
5221           ch = km.key.scancode;
5222           if (ch < 32 || ch == 127 || ch > 255
5223 #ifndef NEXT
5224 #ifndef AUX
5225 #ifndef XENIX
5226 #ifndef OS2
5227               || (ch > 127 && ch < 160)
5228 #else
5229                || (ch > 127)
5230 #endif /* OS2 */
5231 #endif /* XENIX */
5232 #endif /* AUX */
5233 #endif /* NEXT */
5234               )
5235 /*
5236   These used to be %d, but gcc 1.93 & later complain about type mismatches.
5237   %u is supposed to be totally portable.
5238 */
5239             printf("\\%u",(unsigned int) ch);
5240           else printf("%c \\%u",(CHAR) (ch & 0xff),(unsigned int) ch);
5241           if (ch == (KEY) c)
5242             printf(" (self, no translation)\n");
5243           else
5244             printf("\n");
5245           break;
5246       }
5247     }
5248 #endif /* OS2 */
5249 }
5250 #endif /* NOSETKEY */
5251
5252 VOID
5253 shostrdef(s) CHAR * s; {
5254     CHAR ch;
5255     if (!s) s = (CHAR *)"";
5256     while ((ch = *s++)) {
5257         if (ch < 32 || ch == 127 || ch == 255
5258 /*
5259   Systems whose native character sets have graphic characters in C1...
5260 */
5261 #ifndef NEXT                            /* NeXT */
5262 #ifndef AUX                             /* Macintosh */
5263 #ifndef XENIX                           /* IBM PC */
5264 #ifdef OS2
5265 /*
5266   It doesn't matter whether the local host can display 8-bit characters;
5267   they are not portable among character-sets and fonts.  Who knows what
5268   would be displayed...
5269 */
5270             || (ch > 127)
5271 #else /* OS2 */
5272             || (ch > 127 && ch < 160)
5273 #endif /* OS2 */
5274 #endif /* XENIX */
5275 #endif /* AUX */
5276 #endif /* NEXT */
5277             )
5278           printf("\\{%d}",ch);          /* Display control characters */
5279         else putchar((char) ch);        /* in backslash notation */
5280     }
5281 }
5282
5283 #define xxdiff(v,sys) strncmp(v,sys,strlen(sys))
5284
5285 #ifndef NOSHOW
5286 VOID
5287 shover() {
5288 #ifdef OS2
5289     extern char ckxsystem[];
5290 #endif /* OS2 */
5291     extern char *ck_patch, * cklibv;
5292     printf("\nVersions:\n %s\n",versio);
5293     printf(" Numeric: %ld\n",vernum);
5294 #ifdef OS2
5295     printf(" Operating System: %s\n", ckxsystem);
5296 #else /* OS2 */
5297     printf(" Built for: %s\n", ckxsys);
5298 #ifdef CK_UTSNAME
5299     if (unm_nam[0])
5300       printf(" Running on: %s %s %s %s\n", unm_nam,unm_ver,unm_rel,unm_mch);
5301 #endif /* CK_UTSNAME */
5302     printf(" Patches: %s\n", *ck_patch ? ck_patch : "(none)");
5303 #endif /* OS2 */
5304     if (xxdiff(ckxv,ckxsys))
5305       printf(" %s for%s\n",ckxv,ckxsys);
5306     else
5307       printf(" %s\n",ckxv);
5308     if (xxdiff(ckzv,ckzsys))
5309       printf(" %s for%s\n",ckzv,ckzsys);
5310     else
5311       printf(" %s\n",ckzv);
5312     printf(" %s\n",cklibv);
5313     printf(" %s\n",protv);
5314     printf(" %s\n",fnsv);
5315     printf(" %s\n %s\n",cmdv,userv);
5316 #ifndef NOCSETS
5317     printf(" %s\n",xlav);
5318 #endif /* NOCSETS */
5319 #ifndef MAC
5320 #ifndef NOLOCAL
5321     printf(" %s\n",connv);
5322 #ifdef OS2
5323     printf(" %s\n",ckyv);
5324 #endif /* OS2 */
5325 #endif /* NOLOCAL */
5326 #endif /* MAC */
5327 #ifndef NODIAL
5328     printf(" %s\n",dialv);
5329 #endif /* NODIAL */
5330 #ifndef NOSCRIPT
5331     printf(" %s\n",loginv);
5332 #endif /* NOSCRIPT */
5333 #ifdef NETCONN
5334     printf(" %s\n",cknetv);
5335 #ifdef OS2
5336     printf(" %s\n",ckonetv);
5337 #ifdef CK_NETBIOS
5338     printf(" %s\n",ckonbiv);
5339 #endif /* CK_NETBIOS */
5340 #endif /* OS2 */
5341 #endif /* NETCONN */
5342 #ifdef TNCODE
5343     printf(" %s\n",cktelv);
5344 #endif /* TNCODE */
5345 #ifdef SSHBUILTIN
5346     printf(" %s\n",cksshv);
5347 #ifdef SFTP_BUILTIN
5348     printf(" %s\n",cksftpv);
5349 #endif /* SFTP_BUILTIN */
5350 #endif /* SSHBUILTIN */
5351 #ifdef OS2
5352 #ifdef OS2MOUSE
5353     printf(" %s\n",ckomouv);
5354 #endif /* OS2MOUSE */
5355 #endif /* OS2 */
5356 #ifdef NEWFTP
5357     printf(" %s\n",ckftpv);
5358 #endif /* NEWFTP */
5359 #ifdef CK_AUTHENTICATION
5360     printf(" %s\n",ckathv);
5361 #endif /* CK_AUTHENTICATION */
5362 #ifdef CK_ENCRYPTION
5363 #ifdef CRYPT_DLL
5364     printf(" %s\n",ck_crypt_dll_version());
5365 #else /* CRYPT_DLL */
5366     printf(" %s\n",ckcrpv);
5367 #endif /* CRYPT_DLL */
5368 #endif /* CK_ENCRYPTION */
5369 #ifdef CK_SSL
5370     printf(" %s\n",cksslv);
5371 #endif /* CK_SSL */
5372     printf("\n");
5373 }
5374
5375 #ifdef CK_LABELED
5376 VOID
5377 sholbl() {
5378 #ifdef VMS
5379     printf("VMS Labeled File Features:\n");
5380     printf(" acl %s (ACL info %s)\n",
5381            showoff(lf_opts & LBL_ACL),
5382            lf_opts & LBL_ACL ? "preserved" : "discarded");
5383     printf(" backup-date %s (backup date/time %s)\n",
5384            showoff(lf_opts & LBL_BCK),
5385            lf_opts & LBL_BCK ? "preserved" : "discarded");
5386     printf(" name %s (original filename %s)\n",
5387            showoff(lf_opts & LBL_NAM),
5388            lf_opts & LBL_NAM ? "preserved" : "discarded");
5389     printf(" owner %s (original file owner id %s)\n",
5390            showoff(lf_opts & LBL_OWN),
5391            lf_opts & LBL_OWN ? "preserved" : "discarded");
5392     printf(" path %s (original file's disk:[directory] %s)\n",
5393            showoff(lf_opts & LBL_PTH),
5394            lf_opts & LBL_PTH ? "preserved" : "discarded");
5395 #else
5396 #ifdef OS2
5397     printf("OS/2 Labeled File features (attributes):\n");
5398     printf(" archive:   %s\n", showoff(lf_opts & LBL_ARC));
5399     printf(" extended:  %s\n", showoff(lf_opts & LBL_EXT));
5400     printf(" hidden:    %s\n", showoff(lf_opts & LBL_HID));
5401     printf(" read-only: %s\n", showoff(lf_opts & LBL_RO ));
5402     printf(" system:    %s\n", showoff(lf_opts & LBL_SYS));
5403 #endif /* OS2 */
5404 #endif /* VMS */
5405 }
5406 #endif /* CK_LABELED */
5407
5408 VOID
5409 shotcs(csl,csr) int csl, csr; {         /* Show terminal character set */
5410 #ifndef NOCSETS
5411 #ifdef OS2
5412 #ifndef NOTERM
5413     extern struct _vtG G[4], *GL, *GR;
5414     extern int decnrcm, sni_chcode;
5415     extern int tt_utf8, dec_nrc, dec_kbd, dec_lang;
5416     extern prncs;
5417
5418     printf(" Terminal character-sets:\n");
5419     if (IS97801(tt_type_mode)) {
5420         if (cmask == 0377)
5421           printf("     Mode: 8-bit Mode\n");
5422         else
5423           printf("     Mode: 7-bit Mode\n");
5424         printf("     CH.CODE is %s\n",sni_chcode?"On":"Off");
5425     } else if (ISVT100(tt_type_mode)) {
5426         if (decnrcm)
5427           printf("     Mode: 7-bit National Mode\n");
5428         else
5429           printf("     Mode: 8-bit Multinational Mode\n");
5430     }
5431     if ( isunicode() )
5432         printf("    Local: Unicode display / %s input\n",
5433                 csl == TX_TRANSP ? "transparent" :
5434                 csl == TX_UNDEF ? "undefined" : txrinfo[csl]->keywd);
5435     else
5436         printf("    Local: %s\n",
5437                 csl == TX_TRANSP ? "transparent" :
5438                 csl == TX_UNDEF ? "undefined" : txrinfo[csl]->keywd);
5439
5440     if ( tt_utf8 ) {
5441         printf("   Remote: UTF-8\n");
5442     } else {
5443         printf("   Remote: %sG0: %s (%s)\n",
5444            GL == &G[0] ? "GL->" : GR == &G[0] ? "GR->" : "    ",
5445            txrinfo[G[0].designation]->keywd,
5446            G[0].designation == TX_TRANSP ? "" :
5447            G[0].size == cs94 ? "94 chars" :
5448            G[0].size == cs96 ? "96 chars" : "multi-byte");
5449         printf("           %sG1: %s (%s)\n",
5450            GL == &G[1] ? "GL->" : GR == &G[1] ? "GR->" : "    ",
5451            txrinfo[G[1].designation]->keywd,
5452            G[1].designation == TX_TRANSP ? "" :
5453            G[1].size == cs94 ? "94 chars" :
5454            G[1].size == cs96 ? "96 chars" : "multi-byte");
5455         printf("           %sG2: %s (%s)\n",
5456            GL == &G[2] ? "GL->" : GR == &G[2] ? "GR->" : "    ",
5457            txrinfo[G[2].designation]->keywd,
5458            G[2].designation == TX_TRANSP ? "" :
5459            G[2].size == cs94 ? "94 chars" :
5460            G[2].size == cs96 ? "96 chars" : "multi-byte");
5461         printf("           %sG3: %s (%s)\n",
5462            GL == &G[3] ? "GL->" : GR == &G[3] ? "GR->" : "    ",
5463            txrinfo[G[3].designation]->keywd,
5464            G[3].designation == TX_TRANSP ? "" :
5465            G[3].size == cs94 ? "94 chars" :
5466            G[3].size == cs96 ? "96 chars" : "multi-byte");
5467     }
5468     printf("\n");
5469     printf(" Keyboard character-sets:\n");
5470     printf("   Multinational: %s\n",txrinfo[dec_kbd]->keywd);
5471     printf("        National: %s\n",txrinfo[dec_nrc]->keywd);
5472     printf("\n");
5473     printf(" Printer character-set: %s\n",txrinfo[prncs]->keywd);
5474 #endif /* NOTERM */
5475 #else /* OS2 */
5476 #ifndef MAC
5477     char *s;
5478
5479     debug(F101,"TERM LOCAL CSET","",csl);
5480     debug(F101,"TERM REMOTE CSET","",csr);
5481     printf(" Terminal character-set: ");
5482     if (tcs_transp) {                   /* No translation */
5483         printf("transparent\n");
5484     } else {                            /* Translation */
5485         printf("%s (remote) %s (local)\n",
5486                fcsinfo[csr].keyword,fcsinfo[csl].keyword);
5487         if (csr != csl) {
5488             switch(gettcs(csr,csl)) {
5489               case TC_USASCII:  s = "ascii";        break;
5490               case TC_1LATIN:   s = "latin1-iso";   break;
5491               case TC_2LATIN:   s = "latin2-iso";   break;
5492               case TC_CYRILL:   s = "cyrillic-iso"; break;
5493               case TC_JEUC:     s = "japanese-euc"; break;
5494               case TC_HEBREW:   s = "hebrew-iso";   break;
5495               case TC_GREEK:    s = "greek-iso";    break;
5496               case TC_9LATIN:   s = "latin9-iso";   break;
5497               default:          s = "transparent";  break;
5498             }
5499             if (strcmp(s,fcsinfo[csl].keyword) &&
5500                 strcmp(s,fcsinfo[csr].keyword))
5501               printf("                         (via %s)\n",s);
5502         }
5503     }
5504 #endif /* MAC */
5505 #endif /* OS2 */
5506 #endif /* NOCSETS */
5507 }
5508
5509 #ifndef NOLOCAL
5510 #ifdef OS2
5511 extern char htab[];
5512 VOID
5513 shotabs() {
5514     int i,j,k,n;
5515
5516     printf("Tab Stops:\n\n");
5517     for (i = 0, j = 1, k = VscrnGetWidth(VCMD); i < MAXTERMCOL; ) {
5518         do {
5519             printf("%c",htab[++i]=='T'?'T':'-');
5520         } while (i % k && i < MAXTERMCOL);
5521         printf("\n");
5522         for ( ; j <= i; j++) {
5523             switch ( j%10 ) {
5524               case 1:
5525                 printf("%c",j == 1 ? '1' : '.');
5526                 break;
5527               case 2:
5528               case 3:
5529               case 4:
5530               case 5:
5531               case 6:
5532               case 7:
5533                 printf("%c",'.');
5534                 break;
5535               case 8:
5536                 n = (j+2)/100;
5537                 if (n)
5538                   printf("%d",n);
5539                 else 
5540                   printf("%c",'.');
5541                 break;
5542               case 9:
5543                 n = (j+1)%100/10;
5544                 if (n)
5545                   printf("%d",n);
5546                 else if (j>90)
5547                   printf("0");
5548                 else 
5549                   printf("%c",'.');
5550                 break;
5551               case 0:
5552                 printf("0");
5553                 break;
5554             }
5555         }
5556         printf("\n");
5557     }
5558 #ifdef COMMENT
5559     for (i = 1; i <= 70; i++)
5560       printf("%c",htab[i]=='T'?'T':'-');
5561     printf("\n1.......10........20........30........40........50........60\
5562 ........70\n\n");
5563     for (; i <= 140; i++)
5564       printf("%c",htab[i]=='T'?'T':'-');
5565     printf("\n........80........90.......100.......110.......120.......130\
5566 .......140\n\n");
5567     for (; i <= 210; i++)
5568       printf("%c",htab[i]=='T'?'T':'-');
5569     printf("\n.......150.......160.......170.......180.......190.......200\
5570 .......210\n\n");
5571     for (; i <= 255; i++)
5572       printf("%c",htab[i]=='T'?'T':'-');
5573     printf("\n.......220.......230.......240.......250..255\n");
5574 #endif
5575
5576 }
5577 #endif /* OS2 */
5578 #endif /* NOLOCAL */
5579
5580 #ifdef OS2MOUSE
5581 VOID
5582 shomou() {
5583     int button, event, id, i;
5584     char * name = "";
5585
5586     printf("Mouse settings:\n");
5587     printf("   Button Count:   %d\n",mousebuttoncount());
5588     printf("   Active:         %s\n\n",showoff(tt_mouse));
5589
5590     for (button = 0; button < MMBUTTONMAX; button++)
5591       for (event = 0; event < MMEVENTSIZE; event++)
5592         if (mousemap[button][event].type != error)
5593           switch (mousemap[button][event].type) {
5594             case key:
5595               printf("   %s = Character: %c \\%d\n",
5596                      mousename(button,event),
5597                      mousemap[button][event].key.scancode,
5598                      mousemap[button][event].key.scancode );
5599               break;
5600             case kverb:
5601               id = mousemap[button][event].kverb.id & ~(F_KVERB);
5602               if (id != K_IGNORE) {
5603                   for (i = 0; i< nkverbs; i++)
5604                     if (id == kverbs[i].kwval) {
5605                         name = kverbs[i].kwd;
5606                         break;
5607                     }
5608                   printf("   %s = Kverb: \\K%s\n",
5609                          mousename(button,event),
5610                          name
5611                          );
5612               }
5613               break;
5614             case macro:
5615               printf("   %s = Macro: ",
5616                      mousename(button,event) );
5617               shostrdef(mousemap[button][event].macro.string);
5618               printf("\n");
5619               break;
5620           }
5621 }
5622 #endif /* OS2MOUSE */
5623
5624 #ifndef NOLOCAL
5625 VOID
5626 shotrm() {
5627     char *s;
5628     extern char * getiact();
5629     extern int tt_print, adl_err;
5630 #ifndef NOTRIGGER
5631     extern char * tt_trigger[];
5632 #endif /* NOTRIGGER */
5633 #ifdef CKTIDLE
5634     extern char * tt_idlesnd_str;
5635     extern int tt_idlesnd_tmo;
5636     extern int tt_idlelimit, tt_idleact;
5637 #endif /* CKTIDLE */
5638 #ifdef OS2
5639     extern int wy_autopage, autoscroll, sgrcolors, colorreset, user_erasemode,
5640       decscnm, decscnm_usr, tt_diff_upd, tt_senddata,
5641       wy_blockend, marginbell, marginbellcol, tt_modechg, dgunix;
5642     int lines = 0;
5643 #ifdef KUI
5644     extern CKFLOAT tt_linespacing[];
5645     extern tt_cursor_blink;
5646 #endif /* KUI */
5647 #ifdef PCFONTS
5648     int i;
5649     char *font;
5650
5651     if (IsOS2FullScreen()) {            /* Determine the font name */
5652         if (!os2LoadPCFonts()) {
5653             for (i = 0; i < ntermfont; i++) {
5654                 if (tt_font == term_font[i].kwval) {
5655                     font = term_font[i].kwd;
5656                     break;
5657                 }
5658             }
5659         } else {
5660             font = "(DLL not available)";
5661         }
5662     } else {
5663         font =     "(full screen only)";
5664     }
5665 #endif /* PCFONTS */
5666 #ifdef KUI
5667     char font[64] = "(unknown)";
5668     if ( ntermfont > 0 ) {
5669         int i;
5670         for (i = 0; i < ntermfont; i++) {
5671             if (tt_font == term_font[i].kwval) {
5672                 ckstrncpy(font,term_font[i].kwd,59);
5673                 ckstrncat(font," ",64);
5674                 ckstrncat(font,ckitoa(tt_font_size/2),64);
5675                 if ( tt_font_size % 2 )
5676                     ckstrncat(font,".5",64);
5677                 break;
5678             }
5679         }
5680     }
5681 #endif /* KUI */
5682
5683     printf("Terminal parameters:\n");
5684     if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5685     printf(" %19s: %1d%-12s  %13s: %1d%-14s\n",
5686            "Bytesize: Command",
5687            (cmdmsk == 0377) ? 8 : 7,
5688            " bits","Terminal",
5689            (cmask == 0377) ? 8 : 7," bits");
5690     if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5691     printf(" %19s: %-13s","Type",
5692            (tt_type >= 0 && tt_type <= max_tt) ?
5693            tt_info[tt_type].x_name :
5694            "unknown" );
5695     if (tt_type >= 0 && tt_type <= max_tt)
5696       if (strlen(tt_info[tt_type].x_id))
5697         printf("  %13s: <ESC>%s","ID",tt_info[tt_type].x_id);
5698     printf("\n");
5699     if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5700     printf(" %19s: %-13s  %13s: %-15s\n","Echo",
5701            duplex ? "local" : "remote","Locking-shift",showoff(sosi));
5702     if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5703     printf(" %19s: %-13s  %13s: %-15s\n","Newline-mode", showoff(tnlm),
5704            "Cr-display",tt_crd ? "crlf" : "normal");
5705     if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5706     printf(" %19s: %-13s  %13s: %-15s\n","Cursor",
5707 #ifdef KUI
5708             (tt_cursor == 2) ? (tt_cursor_blink ? 
5709                                  "full (*)" : "full (.)") :
5710             (tt_cursor == 1) ? (tt_cursor_blink ? 
5711                                  "half (*)" : "half (.)") :
5712             (tt_cursor_blink ? "underline (*)" : "underline (.)"),
5713 #else /* KUI */
5714            (tt_cursor == 2) ? "full" :
5715            (tt_cursor == 1) ? "half" : "underline",
5716 #endif /* KUI */
5717 #ifdef CK_AUTODL
5718            "autodownload",autodl == TAD_ON ?
5719            (adl_err ? "on, error stop" : "on, error continue") : 
5720            autodl == TAD_ASK ? 
5721            (adl_err ? "ask, error stop" : "ask, error continue") :
5722            "off"
5723 #else /* CK_AUTODL */
5724            "", ""
5725 #endif /* CK_AUTODL */
5726            );
5727     if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5728     printf(" %19s: %-13s  %13s: %-15s\n","Arrow-keys",
5729            tt_arrow ? "application" : "cursor",
5730            "Keypad-mode", tt_keypad ? "application" : "numeric"
5731            );
5732
5733     if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5734
5735     /* Just to make sure we are using current info */
5736     updanswerbk();
5737
5738     /*
5739        This line doesn't end with '\n' because the answerback string
5740        is terminated with a newline
5741     */
5742     printf(" %19s: %-13s  %13s: %-15s","Answerback",
5743            showoff(tt_answer),"response",answerback);
5744     switch (tt_bell) {
5745       case XYB_NONE:
5746         s = "none";
5747         break;
5748       case XYB_VIS:
5749         s= "visible";
5750         break;
5751       case XYB_AUD | XYB_BEEP:
5752         s="beep";
5753         break;
5754       case XYB_AUD | XYB_SYS:
5755         s="system sounds";
5756         break;
5757       default:
5758         s="(unknown)";
5759     }
5760     printf(" %19s: %-13s  %13s: %-15s\n","Bell",s,
5761            "Wrap",showoff(tt_wrap));
5762     if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5763     printf(" %19s: %-13s  %13s: %-15s\n","Autopage",showoff(wy_autopage),
5764            "Autoscroll",showoff(autoscroll));
5765     if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5766     printf(" %19s: %-13s  %13s: %-15s\n","SGR Colors",showoff(sgrcolors),
5767            "ESC[0m color",colorreset?"default-color":"current-color");
5768     if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5769     printf(" %19s: %-13s  %13s: %-15s\n",
5770             "Erase color",user_erasemode?"default-color":"current-color",
5771            "Screen mode",decscnm?"reverse":"normal");
5772     if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5773
5774     printf(" %19s: %-13d  %13s: %-15d\n","Transmit-timeout",tt_ctstmo,
5775            "Output-pacing",tt_pacing);
5776     if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5777
5778     printf(" %19s: %-13d  %13s: %s\n","Idle-timeout",tt_idlelimit,
5779            "Idle-action", getiact());
5780
5781     if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5782     printf(" %19s: %-13s  %13s: %-15s\n","Send data",
5783           showoff(tt_senddata),"End of Block", wy_blockend?"crlf/etx":"us/cr");
5784     if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5785 #ifndef NOTRIGGER
5786     printf(" %19s: %-13s  %13s: %d seconds\n","Auto-exit trigger",
5787            tt_trigger[0],"Output pacing",tt_pacing );
5788     if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5789 #endif /* NOTRIGGER */
5790     printf(" %19s: %-13s  %13s: %-15d\n","Margin bell",
5791            showoff(marginbell),"at column", marginbellcol);
5792     if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5793     switch (tt_modechg) {
5794       case TVC_DIS: s = "disabled"; break;
5795       case TVC_ENA: s = "enabled";  break;
5796       case TVC_W95: s = "win95-restricted"; break;
5797       default: s = "(unknown)";
5798     }
5799     printf(" %19s: %-13s  %13s: %-15s\n","DG Unix mode",
5800            showoff(dgunix),"Video change", s);
5801     if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5802
5803 #ifdef CK_APC
5804     if (apcstatus == APC_ON) s = "on";
5805     else if (apcstatus == APC_OFF) s = "off";
5806     else if (apcstatus == APC_ON|APC_UNCH) s = "unchecked";
5807     else if (apcstatus == APC_ON|APC_NOINP) s = "no-input";
5808     else if (apcstatus == APC_ON|APC_UNCH|APC_NOINP) s = "unchecked-no-input";
5809     printf(" %19s: %-13s  %13s: %-15s\n",
5810            "APC", s,
5811 #ifdef PCFONTS
5812            "Font (VGA)",font
5813 #else /* PCFONTS */
5814 #ifdef KUI
5815            "Font",font
5816 #else
5817            "Font","(not supported)"
5818 #endif /* KUI */
5819 #endif /* PCFONTS */
5820
5821            );
5822 #endif /* CK_APC */
5823     if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5824
5825 #ifdef CK_TTGWSIZ                       /* Console terminal screen size */
5826     if (tt_cols[VTERM] < 0 || tt_rows[VTERM] < 0)
5827       ttgwsiz();                        /* Try to get latest size */
5828 #endif /* CK_TTGWSIZ */
5829     printf(" %19s: %-13d  %13s: %-15d\n","Height",tt_rows[VTERM],
5830            "Width",tt_cols[VTERM]);
5831     if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5832 #ifdef KUI
5833     printf(" %19s: %-12f  %14s: %-15d\n","Line spacing",tt_linespacing[VTERM],
5834            "Display Height",VscrnGetDisplayHeight(VTERM));
5835     if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5836 #endif /* KUI */
5837     printf(" %19s: %-13s  %13s: %d lines\n","Roll-mode",
5838           tt_roll[VTERM]?"insert":"overwrite","Scrollback", tt_scrsize[VTERM]);
5839     if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5840
5841     if (updmode == tt_updmode)
5842       if (updmode == TTU_FAST)
5843         s = "fast (fast)";
5844       else
5845         s = "smooth (smooth)";
5846     else
5847       if (updmode == TTU_FAST)
5848         s = "fast (smooth)";
5849       else
5850         s = "smooth (fast)";
5851
5852     printf(" %19s: %-13s  %13s: %d ms\n","Screen-update: mode",s,
5853            "interval",tt_update);
5854     if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5855     printf(" %19s: %-13s  %13s: %-15s\n",
5856            "Screen-optimization",showoff(tt_diff_upd),
5857            "Status line",showoff(tt_status[VTERM]));
5858     if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5859     printf(" %19s: %-13s  %13s: %-15s\n","Debug",
5860            showoff(debses),"Session log", seslog? sesfil : "(none)" );
5861     if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5862
5863     /* Display colors (should become SHOW COLORS) */
5864     {
5865         USHORT row, col;
5866         char * colors[16] = {
5867             "black","blue","green","cyan","red","magenta","brown","lgray",
5868             "dgray","lblue","lgreen","lcyan","lred","lmagent","yellow","white"
5869         };
5870         printf("\n");
5871         if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5872
5873         printf(" Color:");
5874 #ifndef ONETERMUPD
5875         GetCurPos(&row, &col);
5876         WrtCharStrAtt("border",    6, row, 9, &colorborder );
5877         WrtCharStrAtt("debug",     5, row, 17, &colordebug );
5878         WrtCharStrAtt("helptext",  8, row, 25, &colorhelp );
5879         WrtCharStrAtt("reverse",   7, row, 34, &colorreverse );
5880         WrtCharStrAtt("select",    6, row, 42, &colorselect );
5881         WrtCharStrAtt("status",    6, row, 50, &colorstatus );
5882         WrtCharStrAtt("terminal",  8, row, 58, &colornormal );
5883         WrtCharStrAtt("underline", 9, row, 67, &colorunderline );
5884 #endif /* ONETERMUPD */
5885         row = VscrnGetCurPos(VCMD)->y+1;
5886         VscrnWrtCharStrAtt(VCMD, "border",    6, row, 9, &colorborder );
5887         VscrnWrtCharStrAtt(VCMD, "debug",     5, row, 17, &colordebug );
5888         VscrnWrtCharStrAtt(VCMD, "helptext",  8, row, 25, &colorhelp );
5889         VscrnWrtCharStrAtt(VCMD, "reverse",   7, row, 34, &colorreverse );
5890         VscrnWrtCharStrAtt(VCMD, "select",    6, row, 42, &colorselect );
5891         VscrnWrtCharStrAtt(VCMD, "status",    6, row, 50, &colorstatus );
5892         VscrnWrtCharStrAtt(VCMD, "terminal",  8, row, 58, &colornormal );
5893         VscrnWrtCharStrAtt(VCMD, "underline",  9, row, 67, &colorunderline );
5894         printf("\n");
5895         if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5896
5897         /* Foreground color names */
5898         printf("%6s: %-8s%-8s%-9s%-8s%-8s%-8s%-9s%-9s\n","fore",
5899                 "",
5900                 colors[colordebug&0x0F],
5901                 colors[colorhelp&0x0F],
5902                 colors[colorreverse&0x0F],
5903                 colors[colorselect&0x0F],
5904                 colors[colorstatus&0x0F],
5905                 colors[colornormal&0x0F],
5906                 colors[colorunderline&0x0F]);
5907         if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5908
5909         /* Background color names */
5910         printf("%6s: %-8s%-8s%-9s%-8s%-8s%-8s%-9s%-9s\n","back",
5911                 colors[colorborder],
5912                 colors[colordebug>>4],
5913                 colors[colorhelp>>4],
5914                 colors[colorreverse>>4],
5915                 colors[colorselect>>4],
5916                 colors[colorstatus>>4],
5917                 colors[colornormal>>4],
5918                 colors[colorunderline>>4] );
5919         if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5920         printf("\n");
5921         if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5922         printf(" Color:");
5923 #ifndef ONETERMUPD
5924         GetCurPos(&row, &col);
5925         WrtCharStrAtt("graphic",   7, row, 9, &colorgraphic );
5926         WrtCharStrAtt("command",   7, row, 17, &colorcmd );
5927         WrtCharStrAtt("italic",    6, row, 26, &coloritalic );
5928 #endif /* ONETERMUPD */
5929         row = VscrnGetCurPos(VCMD)->y+1;
5930         VscrnWrtCharStrAtt(VCMD, "graphic",   7, row, 9,  &colorgraphic );
5931         VscrnWrtCharStrAtt(VCMD, "command",   7, row, 17, &colorcmd );
5932         VscrnWrtCharStrAtt(VCMD, "italic",    6, row, 26, &coloritalic );
5933         printf("\n");
5934         if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5935
5936         /* Foreground color names */
5937         printf("%6s: %-8s%-8s%-8s\n","fore",
5938                 colors[colorgraphic&0x0F],
5939                 colors[colorcmd&0x0F],
5940                 colors[coloritalic&0x0F]);
5941         if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5942
5943         /* Background color names */
5944         printf("%6s: %-8s%-8s%-8s\n","back",
5945                 colors[colorgraphic>>4],
5946                 colors[colorcmd>>4],
5947                 colors[coloritalic>>4]);
5948         if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5949     }
5950     printf("\n");
5951     if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5952     {
5953         extern int trueblink, truedim, truereverse, trueunderline, trueitalic;
5954         printf(
5955             " Attribute:  \
5956 blink: %-3s  dim: %-3s  italic: %-3s  reverse: %-3s  underline: %-3s\n",
5957             trueblink?"on":"off", truedim?"on":"off", trueitalic?"on":"off", 
5958             truereverse?"on":"off", trueunderline?"on":"off");
5959         if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5960     }
5961     {
5962         extern vtattrib WPattrib;
5963         printf(" ASCII Protected chars: %s%s%s%s%s%s%s\n",
5964                 WPattrib.blinking?"blink ":"",
5965                 WPattrib.italic?"italic ":"",
5966                 WPattrib.reversed?"reverse ":"",
5967                 WPattrib.underlined?"underline ":"",
5968                 WPattrib.bold?"bold ":"",
5969                 WPattrib.dim?"dim ":"",
5970                 WPattrib.invisible?"invisible ":"");
5971         if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5972     }
5973
5974     printf("\n");
5975     if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5976     (VOID) shoesc(escape);
5977     if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5978     printf(" See SHOW CHARACTER-SETS for character-set info\n");
5979     if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5980
5981 #else /* OS2 */   /* Beginning of new non-OS2 version */
5982
5983     printf("\n");
5984     printf("Terminal parameters:\n");
5985     printf(" %19s: %1d%-12s  %13s: %1d%-14s\n",
5986            "Bytesize: Command",
5987            (cmdmsk == 0377) ? 8 : 7,
5988            " bits","Terminal",
5989            (cmask == 0377) ? 8 : 7," bits");
5990     s = getenv("TERM");
5991 #ifdef XPRINT
5992     printf(" %19s: %-13s  %13s: %-15s\n",
5993            "Type",
5994            s ? s : "(unknown)",
5995            "Print",
5996            showoff(tt_print)
5997            );
5998 #else
5999     printf(" %19s: %-13s\n","Type", s ? s : "(unknown)");
6000 #endif /* XPRINT */
6001     printf(" %19s: %-13s  %13s: %-15s\n","Echo",
6002            duplex ? "local" : "remote","Locking-shift",showoff(sosi));
6003     printf(" %19s: %-13s  %13s: %-15s\n","Newline-mode",
6004            showoff(tnlm),"Cr-display",tt_crd ? "crlf" : "normal");
6005
6006 #ifdef CK_APC
6007     if (apcstatus == APC_ON) s = "on";
6008     else if (apcstatus == APC_OFF) s = "off";
6009     else if (apcstatus == (APC_ON|APC_UNCH)) s = "unchecked";
6010     else if (apcstatus == (APC_ON|APC_NOINP)) s = "no-input";
6011     else if (apcstatus == (APC_ON|APC_UNCH|APC_NOINP))
6012       s = "unchecked-no-input";
6013     printf(" %19s: %-13s  %13s: %-15s\n",
6014            "APC", s,
6015 #ifdef CK_AUTODL
6016            "Autodownload", autodl ?
6017            (adl_err ? "on, error stop" : "on, error continue") : "off"
6018 #else
6019            "",""
6020 #endif /* CK_AUTODL */
6021            );
6022 #endif /* CK_APC */
6023
6024 #ifdef CK_TTGWSIZ                       /* Console terminal screen size */
6025     ttgwsiz();                          /* Try to get latest size */
6026     printf(" %19s: %-13d  %13s: %-15d\n","Height",tt_rows, "Width", tt_cols);
6027 #endif /* CK_TTGWSIZ */
6028
6029     printf(" %19s: %-13s  %13s: %-15s\n","Debug",
6030            showoff(debses),"Session log", seslog? sesfil : "(none)" );
6031
6032 #ifdef CKTIDLE
6033     printf(" %19s: %-13d  %13s: %s\n","Idle-timeout",tt_idlelimit,
6034            "Idle-action", getiact());
6035 #endif /* CKTIDLE */
6036
6037     printf(" %19s: %-13s  ","Lf-display", tt_lfd ? "crlf" : "normal");
6038 #ifdef UNIX
6039 #ifndef NOJC
6040     printf("%13s: %-15s","Suspend", showoff(xsuspend));
6041 #endif /* NOJC */
6042 #endif /* UNIX */
6043     printf("\n");
6044
6045 #ifndef NOTRIGGER
6046     printf(" %19s: %-13s\n","Trigger",
6047            tt_trigger[0] ? tt_trigger[0] : "(none)");
6048 #endif /* NOTRIGGER */
6049     printf("\n");
6050
6051     (VOID) shoesc(escape);
6052 #ifndef NOCSETS
6053     shotcs(tcsl,tcsr);          /* Show terminal character sets */
6054 #endif /* NOCSETS */
6055
6056 #endif /* OS2 */
6057 }
6058
6059 VOID
6060 shmdmlin() {                            /* Briefly show modem & line */
6061 #ifndef NODIAL
6062 #ifndef MINIDIAL
6063 #ifdef OLDTBCODE
6064     extern int tbmodel;
6065     _PROTOTYP( char * gtbmodel, (void) );
6066 #endif /* OLDTBCODE */
6067 #endif /* MINIDIAL */
6068 #endif /* NODIAL */
6069     if (local)
6070 #ifdef OS2
6071       printf(" Port: %s, Modem type: ",ttname);
6072 #else
6073       printf(" Line: %s, Modem type: ",ttname);
6074 #endif /* OS2 */
6075     else
6076       printf(
6077 #ifdef OS2
6078 " Communication device not yet selected with SET PORT\n Modem type: "
6079 #else
6080 " Communication device not yet selected with SET LINE\n Modem type: "
6081 #endif /* OS2 */
6082              );
6083 #ifndef NODIAL
6084     printf("%s",gmdmtyp());
6085 #ifndef MINIDIAL
6086 #ifdef OLDTBCODE
6087     if (tbmodel) printf(" (%s)",gtbmodel()); /* Telebit model info */
6088 #endif /* OLDTBCODE */
6089 #endif /* MINIDIAL */
6090 #else
6091     printf("(disabled)");
6092 #endif /* NODIAL */
6093 }
6094
6095 #ifdef CK_TAPI
6096 void
6097 shotapi(int option) {
6098     int rc=0,k ;
6099     char *s=NULL;
6100     LPDEVCFG        lpDevCfg = NULL;
6101     LPCOMMCONFIG    lpCommConfig = NULL;
6102     LPMODEMSETTINGS lpModemSettings = NULL;
6103     DCB *           lpDCB = NULL;
6104     extern struct keytab * tapiloctab;  /* Microsoft TAPI Locations */
6105     extern int ntapiloc;
6106     extern struct keytab * tapilinetab; /* Microsoft TAPI Line Devices */
6107     extern int ntapiline;
6108     extern int tttapi;                  /* TAPI in use */
6109     extern int tapipass;                /* TAPI Passthrough mode */
6110     extern int tapiconv;                /* TAPI Conversion mode */
6111     extern int tapilights;
6112     extern int tapipreterm;
6113     extern int tapipostterm;
6114     extern int tapimanual;
6115     extern int tapiinactivity;
6116     extern int tapibong;
6117     extern int tapiusecfg;
6118     extern char tapiloc[];
6119     extern int tapilocid;
6120     extern int TAPIAvail;
6121
6122     if (!TAPIAvail) {
6123         printf("TAPI Support not enabled\r\n");
6124         return;
6125     }
6126     switch (option) {
6127       case 0:
6128         printf("TAPI Settings:\n");
6129         printf("  Line:                      %s\n",
6130                tttapi ? ttname : "(none in use)");
6131
6132         cktapiBuildLocationTable(&tapiloctab, &ntapiloc);
6133         if (tapilocid == -1)
6134           tapilocid = cktapiGetCurrentLocationID();
6135
6136         /* Find the current tapiloc entry */
6137         /* and use it as the default. */
6138         for (k = 0; k < ntapiloc; k++) {
6139             if (tapiloctab[k].kwval == tapilocid)
6140               break;
6141         }
6142         if (k >= 0 && k < ntapiloc)
6143           s = tapiloctab[k].kwd;
6144         else
6145           s = "(unknown)";
6146         printf("  Location:                  %s\n",s);
6147         printf("  Modem-dialing:             %s\n",tapipass?"off":"on");
6148         printf("  Phone-number-conversions:  %s\n",
6149                 tapiconv==CK_ON?"on":tapiconv==CK_AUTO?"auto":"off");
6150         printf("  Modem-lights:              %s %s\n",tapilights?"on ":"off",
6151                 tapipass?"(n/a)":"");
6152         printf("  Predial-terminal:          %s %s\n",tapipreterm?"on ":"off",
6153                 tapipass?"(n/a)":"");
6154         printf("  Postdial-terminal:         %s %s\n",tapipostterm?"on ":"off",
6155                 tapipass?"(n/a)":"");
6156         printf("  Manual-dial:               %s %s\n",tapimanual?"on ":"off",
6157                 tapipass?"(n/a)":"");
6158         printf("  Inactivity-timeout:        %d seconds %s\n",tapiinactivity,
6159                 tapipass?"(n/a)":"");
6160         printf("  Wait-for-bong:             %d seconds %s\n",tapibong,
6161                 tapipass?"(n/a)":"");
6162         printf("  Use-windows-configuration: %s %s\n",
6163                 tapiusecfg?"on ":"off", tapipass?"(n/a)":"");
6164         printf("\n");
6165
6166 #ifdef BETATEST
6167         if (tapipass) {
6168 printf("K-95 uses the TAPI Line in an exclusive mode.  Other applications\n");
6169 printf("may open the device but may not place calls nor answer calls.\n");
6170 printf("Dialing is performed using the K-95 dialing procedures.  SET MODEM\n");
6171 printf("TYPE TAPI after the SET TAPI LINE command to activate the modem\n");
6172 printf("definition associated with the active TAPI LINE device.\n\n");
6173
6174         } else {
6175
6176 printf("K-95 uses the TAPI Line in a cooperative mode.  Other applications\n");
6177 printf("may open the device, place and answer calls.  Dialing is performed\n");
6178 printf("by TAPI.  K-95 SET MODEM commands are not used.\n\n");
6179         }
6180
6181         if (tapiconv == CK_ON ||
6182             tapiconv == CK_AUTO && !tapipass) {
6183 printf(
6184 "Phone numbers are converted from canonical to dialable form by TAPI\n");
6185 printf("using the dialing rules specified in the TAPI Dialing Properties\n");
6186 printf("dialog.\n\n");
6187
6188         } else {
6189
6190 printf(
6191 "Phone numbers are converted from canonical to dialable form by K-95\n");
6192 printf(
6193 "using the dialing rules specified with the SET DIAL commands.  TAPI\n");
6194 printf(
6195 "Dialing Properties are imported automaticly upon startup and whenever\n");
6196 printf("the TAPI Dialing Properties are altered or when the TAPI Location\n");
6197 printf("is changed.\n\n");
6198         }
6199 #endif /* BETATEST */
6200
6201         if (tapipass) {
6202             printf("Type SHOW MODEM to see MODEM configuration.\n");
6203             if (tapiconv == CK_ON)
6204               printf("Type SHOW DIAL to see DIAL-related items.\n");
6205         } else {
6206             if (tapiconv == CK_ON || tapiconv == CK_AUTO)
6207               printf("Type SHOW DIAL to see DIAL-related items.\n");
6208         }
6209         break;
6210       case 1:
6211         cktapiDisplayTapiLocationInfo();
6212         break;
6213       case 2:
6214         rc = cktapiGetModemSettings(&lpDevCfg,&lpModemSettings,
6215                                      &lpCommConfig,&lpDCB);
6216         if (rc) {
6217             cktapiDisplayModemSettings(lpDevCfg,lpModemSettings,
6218                                          lpCommConfig,lpDCB);
6219         } else {
6220             printf("?Unable to retrieve Modem Settings\n");
6221         }
6222         break;
6223       case 3: {
6224           HANDLE hModem = GetModemHandleFromLine((HLINE)0);
6225           if (hModem)
6226             DisplayCommProperties(hModem);
6227           else
6228             printf("?Unable to retrieve a valid Modem Handle\n");
6229           CloseHandle(hModem);
6230           break;
6231       }
6232     }
6233     printf("\n");
6234 }
6235 #endif /* CK_TAPI */
6236 #endif /* NOLOCAL */
6237
6238 #ifdef PATTERNS
6239 static VOID
6240 shopat() {
6241     extern char * binpatterns[], * txtpatterns[];
6242     extern int patterns, filepeek;
6243     char **p, *s;
6244     int i, j, k, n, flag, width;
6245 #ifdef CK_TTGWSIZ
6246     ttgwsiz();                          /* Try to get latest size */
6247 #ifdef OS2
6248     width = tt_cols[VCMD];
6249 #else /* OS2 */
6250     width = tt_cols;
6251 #endif /* OS2 */
6252     if (width < 1)
6253 #endif /* CK_TTGWSIZ */
6254       width = 80;
6255     printf("\n");
6256     printf(" Set file type:            %s\n",gfmode(binary,1));
6257     printf(" Set file patterns:        %s", showooa(patterns));
6258 #ifdef CK_LABELED
6259     if (binary == XYFT_L)
6260       printf(" (but SET FILE TYPE LABELED overrides)\n");
6261     else
6262 #endif /* CK_LABELED */
6263 #ifdef VMS
6264     if (binary == XYFT_I)
6265       printf(" (but SET FILE TYPE IMAGE overrides)\n");
6266     else
6267 #endif /* VMS */
6268     if (filepeek)
6269       printf(" (but SET FILE SCAN ON overrides)\n");
6270     else
6271       printf("\n");
6272     printf(" Maximum patterns allowed: %d\n", FTPATTERNS);
6273     for (k = 0; k < 2; k++) {           /* For each kind of patter */
6274         printf("\n");
6275         if (k == 0) {                   /* binary... */
6276             printf(" File binary-patterns: ");
6277             p = binpatterns;
6278         } else {                        /* text... */
6279             printf(" File text-patterns:   ");
6280             p = txtpatterns;
6281         }
6282         if (!p[0]) {
6283             printf("(none)\n");
6284         } else {
6285             printf("\n ");
6286             n = 2;
6287             for (i = 0; i < FTPATTERNS; i++) { /* For each pattern */
6288                 if (!p[i])              /* Done */
6289                   break;
6290                 s = p[i];               /* Look for embedded space */
6291                 for (j = 0, flag = 1; *s; s++, j++) /* and also get length */
6292                   if (*s == SP)
6293                     flag = 3;
6294                 n += j + flag;          /* Length of this line */
6295                 if (n >= width - 1) {
6296                     printf("\n ");
6297                     n = j+2;
6298                 }
6299                 printf(flag == 3 ? " {%s}" : " %s", p[i]);
6300             }
6301             if (n > 2)
6302               printf("\n");
6303         }
6304     }
6305     printf("\n");
6306 }
6307 #endif /* PATTERNS */
6308
6309 #ifndef NOSPL
6310 static VOID
6311 shooutput() {
6312     printf(" Output pacing:          %d (milliseconds)\n",pacing);
6313     printf(" Output special-escapes: %s\n", showoff(outesc));
6314 }
6315
6316 static VOID
6317 shoinput() {
6318 #ifdef CKFLOAT
6319     extern char * inpscale;
6320 #endif  /* CKFLOAT */
6321
6322 #ifdef CK_AUTODL
6323     printf(" Input autodownload:     %s\n", showoff(inautodl));
6324 #endif /* CK_AUTODL */
6325     printf(" Input cancellation:     %s\n", showoff(inintr));
6326     printf(" Input case:             %s\n", inpcas[cmdlvl] ?
6327            "observe" : "ignore");
6328     printf(" Input buffer-length:    %d\n", inbufsize);
6329     printf(" Input echo:             %s\n", showoff(inecho));
6330     printf(" Input silence:          %d (seconds)\n", insilence);
6331 #ifdef OS2
6332     printf(" Input terminal:         %s\n", showoff(interm));
6333 #endif /* OS2 */
6334     printf(" Input timeout:          %s\n", intime[cmdlvl] ?
6335            "quit" : "proceed");
6336 #ifdef CKFLOAT
6337     printf(" Input scale-factor:     %s\n", inpscale ? inpscale : "1.0");
6338 #endif  /* CKFLOAT */
6339
6340     if (instatus < 0)
6341       printf(" Last INPUT:             -1 (INPUT command not yet given)\n");
6342     else
6343       printf(" Last INPUT:             %d (%s)\n", instatus,i_text[instatus]);
6344 }
6345 #endif /* NOSPL */
6346
6347 #ifndef NOSPL
6348 int
6349 showarray() {
6350 #ifdef COMMENT
6351     char * p, * q, ** ap;
6352     int i;
6353 #endif /* COMMENT */
6354     char *s; int x = 0, y;
6355     int range[2];
6356
6357     if ((y = cmfld("Array name","",&s,NULL)) < 0)
6358       if (y != -3)
6359         return(y);
6360     ckstrncpy(line,s,LINBUFSIZ);
6361     s = line;
6362     if ((y = cmcfm()) < 0)
6363       return(y);
6364     if (*s) {
6365         char ** ap;
6366         if ((x = arraybounds(s,&(range[0]),&(range[1]))) < 0) {
6367             printf("?Bad array: %s\n",s);
6368             return(-9);
6369         }
6370         ap = a_ptr[x];
6371         if (!ap) {
6372             printf("Array not declared: %s\n", s);
6373             return(success = 1);
6374         } else {
6375             int i, n, max;
6376             max = (range[1] > 0) ?
6377               range[1] :
6378                 ((range[0] > 0) ? range[0] : a_dim[x]);
6379             if (range[0] < 0)
6380               range[0] = 0;
6381             if (max > a_dim[x])
6382               max = a_dim[x];
6383             n = 1;
6384             printf("\\&%c[]: Dimension = %d",arrayitoa(x),a_dim[x]);
6385             if (a_link[x] > -1)
6386               printf(" (Link to \\&%c[])",arrayitoa(a_link[x]));
6387             printf("\n");
6388             for (i = range[0]; i <= max; i++) {
6389                 if (ap[i]) {
6390                     printf("%3d. %s\n",i,ap[i]);
6391                     if (xaskmore) {
6392                         if (cmd_cols > 0) {
6393                             x = strlen(ap[i]) + 5;
6394                             y = (x % cmd_cols) ? 1 : 0;
6395                             n += (x / cmd_cols) + y;
6396                         } else {
6397                             n++;
6398                         }
6399                         if (n > (cmd_rows - 3)) {
6400                             if (!askmore())
6401                               break;
6402                             else
6403                               n = 0;
6404                         }
6405                     }
6406                 }
6407             }
6408         }
6409         return(1);
6410     }
6411
6412     /* All arrays - just show name and dimension */
6413
6414     for (y = 0; y < (int) 'z' - ARRAYBASE + 1; y++) {
6415         if (a_ptr[y]) {
6416             if (x == 0) printf("Declared arrays:\n");
6417             x = 1;
6418             printf(" \\&%c[%d]",
6419                    (y == 1) ? 64 : y + ARRAYBASE, a_dim[y]);
6420             if (a_link[y] > -1)
6421               printf(" => \\&%c[]",arrayitoa(a_link[y]));
6422             printf("\n");
6423         }
6424         if (!x) printf(" No arrays declared\n");
6425     }
6426     return(1);
6427 }
6428 #endif /* NOSPL */
6429
6430 int
6431 doshow(x) int x; {
6432     int y, z, i; long zz;
6433     extern int optlines;
6434     char *s;
6435 #ifdef OS2
6436     extern int os2gks;
6437     extern int tt_kb_mode;
6438 #endif /* OS2 */
6439     extern int srvcdmsg;
6440     extern char * cdmsgstr, * ckcdpath;
6441
6442 #ifndef NOSETKEY
6443     if (x == SHKEY) {                   /* SHOW KEY */
6444         int c;
6445 #ifdef OS2
6446         if ((x = cmkey(shokeytab,nshokey,"How many keys should be shown?",
6447                         "one",xxstring)) < 0) return(x);
6448         switch (tt_kb_mode) {
6449           case KBM_EM:
6450             s = "emacs";
6451             break;
6452           case KBM_HE:
6453             s = "hebrew";
6454             break;
6455           case KBM_RU:
6456             s = "russian";
6457             break;
6458           case KBM_EN:
6459           default:
6460             s = "default";
6461             break;
6462         }
6463         if ((z = cmkey(shokeymtab,nshokeym,"Which definition should be shown?",
6464                         s,xxstring)) < 0) return(z);
6465         if (z == SHKEYDEF)
6466           z = -1;
6467 #endif /* OS2 */
6468         if ((y = cmcfm()) < 0) return(y);
6469 #ifdef IKSD
6470         if (inserver) {
6471             printf("Sorry, command disabled.\r\n");
6472             return(success = 0);
6473         }
6474 #endif /* IKSD */
6475
6476 #ifdef MAC
6477         printf("Not implemented\n");
6478         return(0);
6479 #else /* Not MAC */
6480 #ifdef OS2
6481         if (x) {
6482             con_event evt;
6483             for (c = 0; c < KMSIZE; c++) {
6484                 evt = (z < 0) ? mapkey(c) : maptermkey(c,z);
6485                 if (evt.type != error) {
6486                     shokeycode(c,z);
6487                 }
6488             }
6489         } else {
6490 #endif /* OS2 */
6491             printf(" Press key: ");
6492 #ifdef UNIX
6493 #ifdef NOSETBUF
6494             fflush(stdout);
6495 #endif /* NOSETBUF */
6496 #endif /* UNIX */
6497             conbin((char)escape);       /* Put terminal in binary mode */
6498 #ifdef OS2
6499             os2gks = 0;                 /* Raw scancode processing */
6500 #endif /* OS2 */
6501             c = congks(0);              /* Get character or scan code */
6502 #ifdef OS2
6503             os2gks = 1;                 /* Cooked scancode processing */
6504 #endif /* OS2 */
6505             concb((char)escape);        /* Restore terminal to cbreak mode */
6506             if (c < 0) {                /* Check for error */
6507                 printf("?Error reading key\n");
6508                 return(0);
6509             }
6510 #ifndef OS2
6511 /*
6512   Do NOT mask when it can be a raw scan code, perhaps > 255
6513 */
6514             c &= cmdmsk;                /* Apply command mask */
6515 #endif /* OS2 */
6516             printf("\n");
6517 #ifdef OS2
6518             shokeycode(c,z);
6519 #else /* OS2 */
6520             shokeycode(c);
6521 #endif /* OS2 */
6522 #ifdef OS2
6523         }
6524 #endif /* OS2 */
6525         return(1);
6526 #endif /* MAC */
6527     }
6528 #ifndef NOKVERBS
6529     if (x == SHKVB) {                   /* SHOW KVERBS */
6530         if ((y = cmcfm()) < 0) return(y);
6531 #ifdef IKSD
6532         if (inserver) {
6533             printf("Sorry, command disabled.\r\n");
6534             return(success = 0);
6535         }
6536 #endif /* IKSD */
6537         printf("\nThe following %d keyboard verbs are available:\n\n",nkverbs);
6538         kwdhelp(kverbs,nkverbs,"","\\K","",3,0);
6539         printf("\n");
6540         return(1);
6541     }
6542 #ifdef OS2
6543     if (x == SHUDK) {                   /* SHOW UDKs */
6544         extern void showudk(void);
6545         if ((y = cmcfm()) < 0) return(y);
6546 #ifdef IKSD
6547         if (inserver) {
6548             printf("Sorry, command disabled.\r\n");
6549             return(success = 0);
6550         }
6551 #endif /* IKSD */
6552         showudk();
6553         return(1);
6554     }
6555 #endif /* OS2 */
6556 #endif /* NOKVERBS */
6557 #endif /* NOSETKEY */
6558
6559 #ifndef NOSPL
6560     if (x == SHMAC) {                   /* SHOW MACRO */
6561         struct FDB kw, fl, cm;
6562         int i, k, n = 0, left, flag, confirmed = 0;
6563         char * p, *q[64];
6564         for (i = 0; i < nmac; i++) {    /* copy the macro table */
6565             mackey[i].kwd = mactab[i].kwd; /* into a regular keyword table */
6566             mackey[i].kwval = i;        /* with value = pointer to macro tbl */
6567             mackey[i].flgs = mactab[i].flgs;
6568         }
6569         p = line;
6570         left = LINBUFSIZ;
6571         while (!confirmed && n < 64) {
6572             cmfdbi(&kw,                 /* First FDB - macro table */
6573                    _CMKEY,              /* fcode */
6574                    "Macro name",        /* hlpmsg */
6575                    "",                  /* default */
6576                    "",                  /* addtl string data */
6577                    nmac,                /* addtl numeric data 1: tbl size */
6578                    0,                   /* addtl numeric data 2: 4 = cmswi */
6579                    xxstring,            /* Processing function */
6580                    mackey,              /* Keyword table */
6581                    &fl                  /* Pointer to next FDB */
6582                    );
6583             cmfdbi(&fl,                 /* 2nd FDB - something not in mactab */
6584                    _CMFLD,              /* fcode */
6585                    "",                  /* hlpmsg */
6586                    "",                  /* default */
6587                    "",                  /* addtl string data */
6588                    0,                   /* addtl numeric data 1 */
6589                    0,                   /* addtl numeric data 2 */
6590                    xxstring,
6591                    NULL,
6592                    &cm
6593                    );
6594             cmfdbi(&cm,                 /* 3rd FDB - Confirmation */
6595                    _CMCFM,              /* fcode */
6596                    "",                  /* hlpmsg */
6597                    "",                  /* default */
6598                    "",                  /* addtl string data */
6599                    0,                   /* addtl numeric data 1 */
6600                    0,                   /* addtl numeric data 2 */
6601                    NULL,
6602                    NULL,
6603                    NULL
6604                    );
6605             x = cmfdb(&kw);             /* Parse something */
6606             if (x < 0)
6607               return(x);
6608             s = atmbuf;                 /* What the user typed */
6609             switch (cmresult.fcode) {
6610               case _CMKEY:              /* If it was a keyword */
6611                 y = mlook(mactab,atmbuf,nmac); /* get full name */
6612                 if (y > -1)
6613                   s = mactab[y].kwd;    /* (fall thru on purpose...) */
6614               case _CMFLD:
6615                 k = ckstrncpy(p,s,left) + 1; /* Copy result to list */
6616                 left -= k;
6617                 if (left <= 0) {
6618                     *p = NUL;
6619                     break;
6620                 }
6621                 q[n++] = p;             /* Point to this item */
6622                 p += k;                 /* Move buffer pointer past it */
6623                 break;
6624               case _CMCFM:              /* End of command */
6625                 confirmed++;
6626               default:
6627                 break;
6628             }
6629         }
6630         if (n == 0) {
6631             printf("Macros:\n");
6632             slc = 1;
6633             for (y = 0; y < nmac; y++)
6634               if (shomac(mactab[y].kwd,mactab[y].mval) < 0) break;
6635             return(1);
6636         }
6637         slc = 0;
6638         for (i = 0; i < n; i++) {
6639             flag = 0;
6640             s = q[i];
6641             if (!s) s = "";
6642             if (!*s) continue;
6643             if (iswild(s)) {            /* Pattern match */
6644                 for (k = 0, x = 0; x < nmac; x++) {
6645                     if (ckmatch(s,mactab[x].kwd,0,1)) {
6646                         shomac(mactab[x].kwd,mactab[x].mval);
6647                         k++;
6648                     }
6649                 }
6650                 if (!k)
6651                   x = -1;
6652                 else
6653                   continue;
6654             } else {                    /* Exact match */
6655                 x = mxlook(mactab,s,nmac);
6656                 flag = 1;
6657             }
6658             if (flag && x == -1)
6659               x = mlook(mactab,s,nmac);
6660             switch (x) {
6661               case -3:                  /* Nothing to look up */
6662               case -1:                  /* Not found */
6663                 printf("%s - (not defined)\n",s);
6664                 break;
6665               case -2:                  /* Ambiguous, matches more than one */
6666                 printf("%s - ambiguous\n",s);
6667                 break;
6668               default:                  /* Matches one exactly */
6669                 shomac(mactab[x].kwd,mactab[x].mval);
6670                 break;
6671             }
6672         }
6673         return(1);
6674     }
6675 #endif /* NOSPL */
6676
6677 /*
6678   Other SHOW commands only have two fields.  Get command confirmation here,
6679   then handle with big switch() statement.
6680 */
6681 #ifndef NOSPL
6682     if (x != SHBUI && x != SHARR)
6683 #endif /* NOSPL */
6684       if ((y = cmcfm()) < 0)
6685         return(y);
6686
6687 #ifdef COMMENT
6688     /* This restriction is too general. */
6689 #ifdef IKSD
6690     if (inserver &&
6691 #ifdef CK_LOGIN
6692         isguest
6693 #else
6694         0
6695 #endif /* CK_LOGIN */
6696         ) {
6697         printf("Sorry, command disabled.\r\n");
6698         return(success = 0);
6699     }
6700 #endif /* IKSD */
6701 #endif /* COMMENT */
6702
6703     switch (x) {
6704
6705 #ifdef ANYX25
6706 #ifndef IBMX25
6707       case SHPAD:
6708         shopad(0);
6709         break;
6710 #endif /* IBMX25 */
6711 #endif /* ANYX25 */
6712
6713       case SHNET:
6714 #ifdef NOLOCAL
6715         printf(" No network support in this version of C-Kermit.\n");
6716 #else
6717 #ifndef NETCONN
6718         printf(" No network support in this version of C-Kermit.\n");
6719 #else
6720         shonet();
6721 #endif /* NETCONN */
6722 #endif /* NOLOCAL */
6723         break;
6724
6725       case SHPAR:
6726         shopar();
6727         break;
6728
6729 #ifndef NOXFER
6730       case SHATT:
6731         shoatt();
6732         break;
6733 #endif /* NOXFER */
6734
6735 #ifndef NOSPL
6736       case SHCOU:
6737         printf(" %d\n",count[cmdlvl]);
6738         break;
6739 #endif /* NOSPL */
6740
6741 #ifndef NOSERVER
6742       case SHSER:                       /* Show Server */
6743         i = 0;
6744 #ifndef NOFRILLS
6745         printf("Function:          Status:\n");
6746         i++;
6747         printf(" GET                %s\n",nm[en_get]);
6748         i++;
6749         printf(" SEND               %s\n",nm[en_sen]);
6750         i++;
6751         printf(" MAIL               %s\n",nm[inserver ? 0 : en_mai]);
6752         i++;
6753         printf(" PRINT              %s\n",nm[inserver ? 0 : en_pri]);
6754         i++;
6755 #ifndef NOSPL
6756         printf(" REMOTE ASSIGN      %s\n",nm[en_asg]);
6757         i++;
6758 #endif /* NOSPL */
6759         printf(" REMOTE CD/CWD      %s\n",nm[en_cwd]);
6760         i++;
6761 #ifdef ZCOPY
6762         printf(" REMOTE COPY        %s\n",nm[en_cpy]);
6763         i++;
6764 #endif /* ZCOPY */
6765         printf(" REMOTE DELETE      %s\n",nm[en_del]);
6766         printf(" REMOTE DIRECTORY   %s\n",nm[en_dir]);
6767         printf(" REMOTE HOST        %s\n",nm[inserver ? 0 : en_hos]);
6768         i += 3;
6769 #ifndef NOSPL
6770         printf(" REMOTE QUERY       %s\n",nm[en_que]);
6771         i++;
6772 #endif /* NOSPL */
6773         printf(" REMOTE MKDIR       %s\n",nm[en_mkd]);
6774         printf(" REMOTE RMDIR       %s\n",nm[en_rmd]);
6775         printf(" REMOTE RENAME      %s\n",nm[en_ren]);
6776         printf(" REMOTE SET         %s\n",nm[en_set]);
6777         printf(" REMOTE SPACE       %s\n",nm[en_spa]);
6778         printf(" REMOTE TYPE        %s\n",nm[en_typ]);
6779         printf(" REMOTE WHO         %s\n",nm[inserver ? 0 : en_who]);
6780         printf(" BYE                %s\n",nm[en_bye]);
6781         printf(" FINISH             %s\n",nm[en_fin]);
6782         printf(" EXIT               %s\n",nm[en_xit]);
6783         printf(" ENABLE             %s\n",nm[en_ena]);
6784         i += 11;
6785 #endif /* NOFRILLS */
6786         if (i > cmd_rows - 3) { if (!askmore()) return(1); else i = 0; }
6787         printf("Server timeout:      %d\n",srvtim);
6788         if (++i > cmd_rows - 3) { if (!askmore()) return(1); else i = 0; }
6789         printf("Server idle-timeout: %d\n",srvidl);
6790         if (++i > cmd_rows - 3) { if (!askmore()) return(1); else i = 0; }
6791         printf("Server keepalive     %s\n", showoff(srvping));
6792         if (++i > cmd_rows - 3) { if (!askmore()) return(1); else i = 0; }
6793         printf("Server cd-message    %s\n", showoff(srvcdmsg));
6794         if (srvcdmsg && cdmsgstr)
6795           printf("Server cd-message    %s\n", cdmsgstr);
6796         if (++i > cmd_rows - 3) { if (!askmore()) return(1); else i = 0; }
6797         printf("Server display:      %s\n", showoff(srvdis));
6798         if (++i > cmd_rows - 3) { if (!askmore()) return(1); else i = 0; }
6799         printf("Server login:        ");
6800         if (!x_user) {
6801             printf("(none)\n");
6802         } else {
6803             printf("\"%s\", \"%s\", \"%s\"\n",
6804                    x_user,
6805                    x_passwd ? x_passwd : "",
6806                    x_acct ? x_acct : ""
6807                    );
6808         }
6809         if (++i > cmd_rows - 3) { if (!askmore()) return(1); else i = 0; }
6810         printf("Server get-path: ");
6811         if (ngetpath == 0) {
6812             printf("    (none)\n");
6813         } else {
6814             printf("\n");
6815             i += 3;
6816             for (x = 0; x < ngetpath; x++) {
6817                 if (getpath[x]) printf(" %d. %s\n", x, getpath[x]);
6818                 if (++i > (cmd_rows - 3)) { /* More than a screenful... */
6819                     if (!askmore())
6820                       break;
6821                     else
6822                       i = 0;
6823                 }
6824             }
6825         }
6826         break;
6827 #endif /* NOSERVER */
6828
6829       case SHSTA:                       /* Status of last command */
6830         printf(" %s\n", success ? "SUCCESS" : "FAILURE");
6831         return(0);                      /* Don't change it */
6832
6833       case SHSTK: {                     /* Stack for MAC debugging */
6834 #ifdef MAC
6835           long sp;
6836           sp = -1;
6837           loadA0 ((char *)&sp);         /* set destination address */
6838           SPtoaA0();                    /* move SP to destination */
6839           printf("Stack at 0x%x\n", sp);
6840           show_queue();                 /* more debugging */
6841           break;
6842 #else
6843           shostack();
6844 #endif /* MAC */
6845           break;
6846       }
6847
6848
6849 #ifndef NOLOCAL
6850 #ifdef OS2
6851       case SHTAB:                       /* SHOW TABS */
6852 #ifdef IKSD
6853         if (inserver) {
6854             printf("Sorry, command disabled.\r\n");
6855             return(success = 0);
6856         }
6857 #endif /* IKSD */
6858         shotabs();
6859         break;
6860 #endif /* OS2 */
6861
6862       case SHTER:                       /* SHOW TERMINAL */
6863 #ifdef IKSD
6864         if (inserver) {
6865             printf("Sorry, command disabled.\r\n");
6866             return(success = 0);
6867         }
6868 #endif /* IKSD */
6869         shotrm();
6870         break;
6871
6872 #ifdef OS2
6873       case SHVSCRN:                     /* SHOW Virtual Screen - for debug */
6874         shovscrn();
6875         break;
6876 #endif /* OS2 */
6877 #endif /* NOLOCAL */
6878
6879 #ifdef OS2MOUSE
6880       case SHMOU:                       /* SHOW MOUSE */
6881 #ifdef IKSD
6882         if (inserver) {
6883             printf("Sorry, command disabled.\r\n");
6884             return(success = 0);
6885         }
6886 #endif /* IKSD */
6887         shomou();
6888         break;
6889 #endif /* OS2MOUSE */
6890
6891 #ifndef NOFRILLS
6892       case SHVER:
6893         shover();
6894         break;
6895 #endif /* NOFRILLS */
6896
6897 #ifndef NOSPL
6898       case SHBUI:                       /* Built-in variables */
6899         line[0] = NUL;
6900         if ((y = cmtxt("Variable name or pattern","",&s,xxstring)) < 0)
6901           return(y);
6902         ckstrncpy(line,s,LINBUFSIZ);
6903         /* if (line[0]) ckstrncat(line,"*",LINBUFSIZ); */
6904
6905       case SHFUN:                       /* or built-in functions */
6906 #ifdef CK_TTGWSIZ
6907 #ifdef OS2
6908         if (tt_cols[VTERM] < 0 || tt_rows[VTERM] < 0)
6909           ttgwsiz();
6910 #else /* OS2 */
6911         if (ttgwsiz() > 0) {            /* Get current screen size */
6912             if (tt_rows > 0 && tt_cols > 0) {
6913                 cmd_rows = tt_rows;
6914                 cmd_cols = tt_cols;
6915             }
6916         }
6917 #endif /* OS2 */
6918 #endif /* CK_TTGWSIZ */
6919
6920         if (x == SHFUN) {               /* Functions */
6921             printf("\nThe following functions are available:\n\n");
6922             kwdhelp(fnctab,nfuncs,"","\\F","()",3,0);
6923             printf("\n");
6924 #ifndef NOHELP
6925             printf(
6926 "HELP FUNCTION <name> gives the calling conventions of the given function.\n\n"
6927                    );
6928 #endif /* NOHELP */
6929             break;
6930         } else {                        /* Variables */
6931             int j, flag = 0, havearg = 0;
6932             struct stringarray * q = NULL;
6933             char ** pp;
6934             if (line[0]) {              /* Have something to search for */
6935                 havearg = 1;            /* Maybe a list of things */
6936                 q = cksplit(1,0,line,NULL,"_-^$*?[]{}",0,0,0);
6937                 if (!q) break;
6938                 pp = q->a_head;
6939             }
6940             i = 0;
6941             for (y = 0; y < nvars; y++) {
6942                 if ((vartab[y].flgs & CM_INV))
6943                   continue;
6944                 if (havearg) {          /* If I have something to match */
6945                     char * s2;
6946                     for (flag = 0, j = 1; j <= q->a_size && !flag; j++) {
6947                         s2 = pp[j] ? pp[j] : "";
6948 #ifdef COMMENT
6949 /* This is not needed because it's what the 4 arg does in ckmatch() */
6950                         len = strlen(s2);
6951                         if (len > 0) {
6952                             if (s2[len-1] != '$') {/* To allow anchors */
6953                                 ckmakmsg(line,LINBUFSIZ,pp[j],"*",NULL,NULL);
6954                                 s2 = line;
6955                             }
6956                         }
6957 #endif /* COMMENT */
6958                         if (ckmatch(s2,vartab[y].kwd,0,4) > 0) {
6959                             flag = 1;   /* Matches */
6960                             break;
6961                         }
6962                     }
6963                     if (!flag)          /* Doesn't match */
6964                       continue;
6965                 }
6966                 s = nvlook(vartab[y].kwd);
6967                 printf(" \\v(%s) = ",vartab[y].kwd);
6968                 if (vartab[y].kwval == VN_NEWL) { /* \v(newline) */
6969                     while (*s)          /* Show control chars symbolically */
6970                       printf("\\{%d}",*s++);
6971                     printf("\n");
6972                 } else if (vartab[y].kwval == VN_IBUF  || /* \v(input) */
6973                            vartab[y].kwval == VN_QUE   || /* \v(query) */
6974 #ifdef OS2
6975                            vartab[y].kwval == VN_SELCT || /* \v(select) */
6976 #endif /* OS2 */
6977                            (vartab[y].kwval >= VN_M_AAA && /* modem ones */
6978                             vartab[y].kwval <= VN_M_ZZZ)
6979                            ) {
6980                     int r = 12;         /* This one can wrap around */
6981                     char buf[10];
6982                     while (*s) {
6983                         if (isprint(*s)) {
6984                             buf[0] = *s;
6985                             buf[1] = NUL;
6986                             r++;
6987                         } else {
6988                             sprintf(buf,"\\{%d}",*s); /* SAFE */
6989                             r += (int) strlen(buf);
6990                         }
6991                         if (r >= cmd_cols - 1) {
6992                             printf("\n");
6993                             r = 0;
6994                             i++;
6995                         }
6996                         printf("%s",buf);
6997                         s++;
6998                     }
6999                     printf("\n");
7000                 } else
7001                   printf("%s\n",s);
7002                 if (++i > (cmd_rows - 3)) { /* More than a screenful... */
7003                     if ((y >= nvars - 1) || !askmore())
7004                       break;
7005                     else
7006                       i = 0;
7007                 }
7008             }
7009         }
7010         break;
7011
7012       case SHVAR:                       /* Global variables */
7013         x = 0;                          /* Variable count */
7014         slc = 1;                        /* Screen line count for "more?" */
7015         for (y = 33; y < GVARS; y++)
7016           if (g_var[y]) {
7017               if (x++ == 0) printf("Global variables:\n");
7018               sprintf(line," \\%%%c",y); /* SAFE */
7019               if (shomac(line,g_var[y]) < 0) break;
7020           }
7021         if (!x) printf(" No variables defined\n");
7022         break;
7023
7024       case SHARG: {                     /* Args */
7025           char * s1, * s2;
7026           if (maclvl > -1) {
7027               printf("Macro arguments at level %d (\\v(argc) = %d):\n",
7028                      maclvl,
7029                      macargc[maclvl]
7030                      );
7031               for (y = 0; y < macargc[maclvl]; y++) {
7032                   s1 = m_arg[maclvl][y];
7033                   if (!s1) s1 = "(NULL)";
7034                   s2 = m_xarg[maclvl][y];
7035                   if (!s2) s2 = "(NULL)";
7036                   if (y < 10)
7037                     printf(" \\%%%d = %s\n",y,s1);
7038                   else
7039                     printf(" \\&_[%d] = %s\n",y,s2);
7040               }
7041           } else {
7042               printf("Top-level arguments (\\v(argc) = %d):\n", topargc);
7043               for (y = 0; y < topargc; y++) {
7044                   s1 = g_var[y + '0'];
7045                   if (!s1) s1 = "(NULL)";
7046                   s2 = toparg[y];
7047                   if (!s2) s2 = "(NULL)";
7048                   if (y < 10 && g_var[y])
7049                     printf(" \\%%%d = %s\n",y,s1);
7050                   if (toparg[y])
7051                     printf(" \\&_[%d] = %s\n",y,s2);
7052               }
7053           }
7054         }
7055         break;
7056
7057       case SHARR:                       /* Arrays */
7058         return(showarray());
7059 #endif /* NOSPL */
7060
7061 #ifndef NOXFER
7062       case SHPRO:                       /* Protocol parameters */
7063         shoparp();
7064         printf("\n");
7065         break;
7066 #endif /* NOXFER */
7067
7068 #ifndef NOLOCAL
7069       case SHCOM:                       /* Communication parameters */
7070         printf("\n");
7071         shoparc();
7072 #ifdef OS2
7073         {
7074             int i;
7075             char *s = "(unknown)";
7076             for (i = 0; i < nprty; i++)
7077               if (prtytab[i].kwval == priority) {
7078                   s = prtytab[i].kwd;
7079                   break;
7080               }
7081             printf(" Priority: %s\n", s );
7082         }
7083 #endif /* OS2 */
7084
7085         printf("\n");
7086 #ifdef NETCONN
7087         if (!network
7088 #ifdef IKSD
7089              && !inserver
7090 #endif /* IKSD */
7091              ) {
7092 #endif /* NETCONN */
7093             shomdm();
7094             printf("\n");
7095 #ifdef NETCONN
7096         }
7097 #endif /* NETCONN */
7098
7099 #ifndef NODIAL
7100 #ifdef IKSD
7101         if ( !inserver )
7102 #endif /* IKSD */
7103         {
7104             printf("Type SHOW DIAL to see DIAL-related items.\n");
7105             printf("Type SHOW MODEM to see modem-related items.\n");
7106 #ifdef CK_TAPI
7107             printf("Type SHOW TAPI to see TAPI-related items.\n");
7108 #endif /* CK_TAPI */
7109             printf("\n");
7110         }
7111 #endif /* NODIAL */
7112         break;
7113 #endif /* NOLOCAL */
7114
7115       case SHFIL:                       /* File parameters */
7116         shofil();
7117         /* printf("\n"); */             /* (out o' space) */
7118         break;
7119
7120 #ifndef NOCSETS
7121       case SHLNG:                       /* Languages */
7122         shoparl();
7123         break;
7124 #endif /* NOCSETS */
7125
7126 #ifndef NOSPL
7127       case SHSCR:                       /* Scripts */
7128         printf(" Command quoting:        %s\n", showoff(cmdgquo()));
7129         printf(" Take  echo:             %s\n", showoff(techo));
7130         printf(" Take  error:            %s\n", showoff(takerr[cmdlvl]));
7131         printf(" Macro echo:             %s\n", showoff(mecho));
7132         printf(" Macro error:            %s\n", showoff(merror[cmdlvl]));
7133         printf(" Quiet:                  %s\n", showoff(quiet));
7134         printf(" Variable evaluation:    %s [\\%%x and \\&x[] variables]\n",
7135                vareval ? "recursive" : "simple");
7136         printf(" Function diagnostics:   %s\n", showoff(fndiags));
7137         printf(" Function error:         %s\n", showoff(fnerror));
7138 #ifdef CKLEARN
7139         {
7140             extern char * learnfile;
7141             extern int learning;
7142             if (learnfile) {
7143                 printf(" LEARN file:             %s (%s)\n",
7144                        learnfile,
7145                        learning ? "ON" : "OFF"
7146                        );
7147             } else
7148               printf(" LEARN file:             (none)\n");
7149         }
7150 #endif /* CKLEARN */
7151         shoinput();
7152         shooutput();
7153 #ifndef NOSCRIPT
7154         printf(" Script echo:            %s\n", showoff(secho));
7155 #endif /* NOSCRIPT */
7156         printf(" Command buffer length:  %d\n", CMDBL);
7157         printf(" Atom buffer length:     %d\n", ATMBL);
7158         break;
7159 #endif /* NOSPL */
7160
7161 #ifndef NOXMIT
7162       case SHXMI:
7163         printf("\n");
7164         printf(" File type:                       %s\n",
7165                binary ? "binary" : "text");
7166 #ifndef NOCSETS
7167         printf(" File character-set:              %s\n",
7168                fcsinfo[fcharset].keyword);
7169 #ifdef OS2
7170         if ( isunicode() ) {
7171         printf(" Terminal Character (remote):     %s\n",
7172               tt_utf8 ? "utf-8" : tcsr == TX_TRANSP ? "transparent" :
7173               tcsr == TX_UNDEF ? "undefined" : txrinfo[tcsr]->keywd);
7174         printf(" Terminal Character (local):      %s\n",
7175               tcsl == TX_TRANSP ? "transparent" :
7176               tcsl == TX_UNDEF ? "undefined" : txrinfo[tcsl]->keywd);
7177         } else {
7178         printf(" Terminal Character (remote):     %s\n",
7179               tt_utf8 ? "utf-8" : tcsr == TX_TRANSP ? "transparent" :
7180               tcsr == TX_UNDEF ? "undefined" : txrinfo[tcsr]->keywd);
7181         printf(" Terminal Character (local):      %s\n",
7182               tcsl == TX_TRANSP ? "transparent" :
7183               tcsl == TX_UNDEF ? "undefined" : txrinfo[tcsl]->keywd);
7184         }
7185 #else /* OS2 */
7186         printf(" Terminal character-set (remote): %s\n",
7187                fcsinfo[tcsr].keyword);
7188         printf(" Terminal character-set (local):  %s\n",
7189                fcsinfo[tcsl].keyword);
7190 #endif /* OS2 */
7191 #endif /* NOCSETS */
7192         printf(" Terminal bytesize:               %d\n",
7193                (cmask == 0xff) ? 8 : 7);
7194         printf(" Terminal echo:                   %s\n",
7195                duplex ? "local" : "remote");
7196         printf(" Transmit EOF:                    ");
7197         if (*xmitbuf == NUL) {
7198             printf("(none)\n");
7199         } else {
7200             char *p;
7201             p = xmitbuf;
7202             while (*p) {
7203                 if (*p < SP)
7204                   printf("^%c",ctl(*p));
7205                 else
7206                   printf("%c",*p);
7207                 p++;
7208             }
7209             printf("\n");
7210         }
7211         if (xmitf)
7212           printf(" Transmit Fill:                   %d\n", xmitf);
7213         else
7214           printf(" Transmit Fill:                   (none)\n");
7215         printf(" Transmit Linefeed:               %s\n",showoff(xmitl));
7216         if (xmitp)
7217           printf(" Transmit Prompt:                 %d (%s)\n",
7218                  xmitp,
7219                  chartostr(xmitp)
7220                  );
7221         else
7222           printf(" Transmit Prompt:                 (none)\n");
7223         printf(" Transmit Echo:                   %s\n", showoff(xmitx));
7224         printf(" Transmit Locking-Shift:          %s\n", showoff(xmits));
7225         printf(" Transmit Pause:                  %d (millisecond%s)\n",
7226                xmitw,
7227                (xmitw == 1) ? "" : "s"
7228                );
7229         printf(" Transmit Timeout:                %d (second%s)\n",
7230                xmitt,
7231                (xmitt == 1) ? "" : "s"
7232                );
7233         printf("\n");
7234         break;
7235 #endif /* NOXMIT */
7236
7237 #ifndef NODIAL
7238       case SHMOD:                       /* SHOW MODEM */
7239 #ifdef IKSD
7240         if (inserver) {
7241             printf("Sorry, command disabled.\r\n");
7242             return(success = 0);
7243         }
7244 #endif /* IKSD */
7245         shomodem();                     /* Show SET MODEM items */
7246         break;
7247 #endif /* NODIAL */
7248
7249 #ifndef MAC
7250       case SHDFLT:
7251         printf("%s\n",zgtdir());
7252         break;
7253 #endif /* MAC */
7254
7255 #ifndef NOLOCAL
7256       case SHESC:
7257 #ifdef IKSD
7258         if (inserver) {
7259             printf("Sorry, command disabled.\r\n");
7260             return(success = 0);
7261         }
7262 #endif /* IKSD */
7263         return(shoesc(escape));
7264
7265 #ifndef NODIAL
7266       case SHDIA:                       /* SHOW DIAL */
7267 #ifdef IKSD
7268         if (inserver) {
7269             printf("Sorry, command disabled.\r\n");
7270             return(success = 0);
7271         }
7272 #endif /* IKSD */
7273         shmdmlin();
7274         printf(", speed: ");
7275         if ((zz = ttgspd()) < 0) {
7276             printf("unknown");
7277         } else {
7278             if (zz == 8880) printf("75/1200"); else printf("%ld",zz);
7279         }
7280         if (carrier == CAR_OFF) s = "off";
7281         else if (carrier == CAR_ON) s = "on";
7282         else if (carrier == CAR_AUT) s = "auto";
7283         else s = "unknown";
7284         printf(", carrier: %s", s);
7285         if (carrier == CAR_ON) {
7286             if (cdtimo) printf(", timeout: %d sec", cdtimo);
7287             else printf(", timeout: none");
7288         }
7289         printf("\n");
7290         doshodial();
7291         if (local
7292 #ifdef NETCONN
7293             && !network
7294 #endif /* NETCONN */
7295             ) {
7296             printf("Type SHOW MODEM to see modem settings.\n");
7297 #ifdef CK_TAPI
7298             printf("Type SHOW TAPI to see TAPI-related items\n");
7299 #endif /* CK_TAPI */
7300             printf("Type SHOW COMMUNICATIONS to see modem signals.\n");
7301         }
7302         break;
7303 #endif /* NODIAL */
7304 #endif /* NOLOCAL */
7305
7306 #ifndef NOXFER
7307 #ifdef CK_LABELED
7308       case SHLBL:                       /* Labeled file info */
7309         sholbl();
7310         break;
7311 #endif /* CK_LABELED */
7312 #endif /* NOXFER */
7313
7314       case SHCSE:                       /* Character sets */
7315 #ifdef NOCSETS
7316         printf(
7317 " Character set translation is not supported in this version of C-Kermit\n");
7318 #else
7319         shocharset();
7320 #ifndef NOXFER
7321         printf("\n Unknown-Char-Set: %s\n",
7322                unkcs ? "Keep" : "Discard");
7323 #endif /* NOXFER */
7324 #ifdef OS2
7325         printf("\n");
7326 #endif /* OS2 */
7327         shotcs(tcsl,tcsr);
7328         printf("\n");
7329 #ifdef OS2
7330         /* PC Code Page information */
7331         {
7332             char cpbuf[128];
7333             int cplist[16], cps;
7334             int activecp;
7335             cps = os2getcplist(cplist, sizeof(cplist));
7336
7337             sprintf(cpbuf,              /* SAFE */
7338                     "%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d",
7339                      cps > 1 ? cplist[1] : 0,
7340                      cps > 2 ? cplist[2] : 0, cps > 3 ? cplist[3] : 0,
7341                      cps > 4 ? cplist[4] : 0, cps > 5 ? cplist[5] : 0,
7342                      cps > 6 ? cplist[6] : 0, cps > 7 ? cplist[7] : 0,
7343                      cps > 8 ? cplist[8] : 0, cps > 9 ? cplist[9] : 0,
7344                      cps > 10 ? cplist[10] : 0, cps > 11 ? cplist[11] : 0,
7345                      cps > 12 ? cplist[12] : 0
7346                      );
7347             printf(" Code Pages:\n");
7348             activecp = os2getcp();
7349             if ( activecp ) {
7350               printf("     Active: %d\n",activecp);
7351               if (!isWin95())
7352                 printf("  Available: %s\n",cpbuf);
7353             } else
7354               printf("     Active: n/a\n");
7355             printf("\n");
7356         }
7357 #endif /* OS2 */
7358 #endif /* NOCSETS */
7359         break;
7360
7361       case SHFEA:                       /* Features */
7362         shofea();
7363         break;
7364
7365 #ifdef CK_SPEED
7366       case SHCTL:                       /* Control-Prefix table */
7367         shoctl();
7368         break;
7369 #endif /* CK_SPEED */
7370
7371       case SHEXI: {
7372           extern int exithangup;
7373           printf("\n Exit warning %s\n", xitwarn ?
7374                  (xitwarn == 1 ? "on" : "always") : "off");
7375           printf(" Exit on-disconnect: %s\n", showoff(exitonclose));
7376           printf(" Exit hangup: %s\n", showoff(exithangup));
7377           printf(" Current exit status: %d\n\n", xitsta);
7378           break;
7379       }
7380       case SHPRT: {
7381 #ifdef PRINTSWI
7382           extern int printtimo, printertype, noprinter;
7383           extern char * printterm, * printsep;
7384           extern int prncs;
7385 #ifdef BPRINT
7386           extern int printbidi;
7387 #endif /* BPRINT */
7388 #endif /* PRINTSWI */
7389
7390 #ifdef IKSD
7391         if (inserver &&
7392 #ifdef CK_LOGIN
7393             isguest
7394 #else /* CK_LOGIN */
7395             0
7396 #endif /* CK_LOGIN */
7397              ) {
7398             printf("Sorry, command disabled.\r\n");
7399             return(success = 0);
7400         }
7401 #endif /* IKSD */
7402 #ifdef PRINTSWI
7403           if (noprinter) {
7404               printf("Printer: (none)\n\n");
7405               break;
7406           }
7407 #endif /* PRINTSWI */
7408
7409           printf("Printer: %s%s\n",
7410
7411                  printpipe ? "| " : "",
7412                  printername ? printername :
7413 #ifdef OS2
7414                  "PRN"
7415 #else
7416                  "(default)"
7417 #endif /* OS2 */
7418                  );
7419 #ifdef PRINTSWI
7420 #ifdef BPRINT
7421           if (printbidi) {
7422               printf(" /BIDIRECTIONAL\n");
7423               if (pportspeed > 0)
7424                 printf(" /SPEED:%ld\n",pportspeed);
7425               printf(" /PARITY:%s\n",parnam((char)pportparity));
7426               printf(" /FLOW:%s\n",
7427                      pportflow == FLO_NONE ? "NONE" :
7428                      (pportflow == FLO_RTSC ? "RTS/CTS" : "XON/XOFF")
7429                      );
7430           } else
7431             printf(" /OUTPUT-ONLY\n");
7432 #endif /* BPRINT */
7433           switch (printertype) {
7434             case PRT_NON: printf(" /NONE\n"); break;
7435             case PRT_FIL: printf(" /FILE\n"); break;
7436             case PRT_PIP: printf(" /PIPE\n"); break;
7437             case PRT_DOS: printf(" /DOS-DEVICE\n"); break;
7438             case PRT_WIN: printf(" /WINDOWS-QUEUE\n"); break;
7439           }
7440           printf(" /TIMEOUT:%d\n",printtimo);
7441           if (printterm) {
7442               printf(" /END-OF-JOB-STRING:");
7443               shostrdef(printterm);
7444               printf("\n");
7445           } else
7446             printf(" /END-OF-JOB-STRING:(none)\n");
7447           printf(" /JOB-HEADER-FILE:%s\n",printsep ? printsep : "(none)");
7448           printf(" /CHARACTER-SET: %s\n",txrinfo[prncs]->keywd);
7449 #endif /* PRINTSWI */
7450           printf("\n");
7451           break;
7452       }
7453
7454       case SHCMD: {
7455 #ifdef DOUBLEQUOTING
7456           extern int dblquo;
7457 #endif /* DOUBLEQUOTING */
7458 #ifdef CK_AUTODL
7459           printf(" Command autodownload: %s\n",showoff(cmdadl));
7460 #else
7461           printf(" Command autodownload: (not available)\n");
7462 #endif /* CK_AUTODL */
7463           printf(" Command bytesize: %d bits\n", (cmdmsk == 0377) ? 8 : 7);
7464           printf(" Command error-display: %d\n", cmd_err);
7465 #ifdef CK_RECALL
7466           printf(" Command recall-buffer-size: %d\n",cm_recall);
7467 #else
7468           printf(" Command recall-buffer not available in this version\n");
7469 #endif /* CK_RECALL */
7470 #ifdef CK_RECALL
7471           printf(" Command retry: %s\n",showoff(cm_retry));
7472 #else
7473           printf(" Command retry not available in this version\n");
7474 #endif /* CK_RECALL */
7475           printf(" Command interruption: %s\n", showoff(cmdint));
7476           printf(" Command quoting: %s\n", showoff(cmdgquo()));
7477 #ifdef DOUBLEQUOTING
7478           printf(" Command doublequoting: %s\n", showoff(dblquo));
7479 #endif /* DOUBLEQUOTING */
7480           printf(" Command more-prompting: %s\n", showoff(xaskmore));
7481           printf(" Command height: %d\n", cmd_rows);
7482           printf(" Command width:  %d\n", cmd_cols);
7483 #ifndef IKSDONLY
7484 #ifdef OS2
7485           printf(" Command statusline: %s\n",showoff(tt_status[VCMD]));
7486 #endif /* OS2 */
7487 #endif /* IKSDONLY */
7488 #ifdef LOCUS
7489           printf(" Locus:          %s",
7490                  autolocus ? (autolocus == 2 ? "ask" : "auto") :
7491                  (locus ? "local" : "remote"));
7492           if (autolocus)
7493             printf(" (%s)", locus ? "local" : "remote");
7494           printf("\n");
7495 #endif /* LOCUS */
7496           printf(" Hints:          %s\n", showoff(hints));
7497           printf(" Quiet:          %s\n", showoff(quiet));
7498           printf(" Maximum command length: %d\n", CMDBL);
7499 #ifndef NOSPL
7500           {
7501               char * s;
7502               int k;
7503               printf(" Maximum number of macros: %d\n", MAC_MAX);
7504               printf(" Macros defined: %d\n", nmac);
7505               printf(" Maximum macro depth: %d\n", MACLEVEL);
7506               printf(" Maximum TAKE depth: %d\n", MAXTAKE);
7507               s = "(not defined)";
7508               k = mlook(mactab,"on_unknown_command",nmac);
7509               if (k > -1) if (mactab[k].mval) s = mactab[k].mval;
7510               printf(" ON_UNKNOWN_COMMAND: %s\n",s);
7511           }
7512 #endif /* NOSPL */
7513 #ifdef UNIX
7514 #ifndef NOJC
7515           printf(" Suspend: %s\n", showoff(xsuspend));
7516 #endif /* NOJC */
7517 #endif /* UNIX */
7518           printf(" Access to external commands and programs%s allowed\n",
7519 #ifndef NOPUSH
7520                  !nopush ? "" :
7521 #endif /* NOPUSH */
7522                   " not");
7523           break;
7524       }
7525
7526 #ifndef NOSPL
7527       case SHALRM:
7528         if (ck_alarm)
7529           printf("Alarm at %s %s\n",alrm_date,alrm_time);
7530         else
7531           printf("(no alarm set)\n");
7532         break;
7533 #endif /* NOSPL */
7534
7535 #ifndef NOMSEND
7536       case SHSFL: {
7537           extern struct filelist * filehead;
7538           if (!filehead) {
7539               printf("send-list is empty\n");
7540           } else {
7541               struct filelist * flp;
7542               char * s;
7543               flp = filehead;
7544               while (flp) {
7545                   s = flp->fl_alias;
7546                   if (!s) s = "(none)";
7547                   printf("%s, mode: %s, alias: %s\n",
7548                          flp->fl_name,
7549                          gfmode(flp->fl_mode,0),
7550                          s
7551                          );
7552                   flp = flp->fl_next;
7553               }
7554           }
7555       }
7556       break;
7557 #endif /* NOMSEND */
7558
7559 #ifdef CKXXCHAR
7560       case SHDBL:
7561         shodbl();
7562         break;
7563 #endif /* CKXXCHAR */
7564
7565 #ifndef NOPUSH
7566 #ifndef NOFRILLS
7567       case SHEDIT:
7568         if (!editor[0]) {
7569             s = getenv("EDITOR");
7570             if (s) ckstrncpy(editor,s,CKMAXPATH);
7571         }
7572         printf("\n editor:  %s\n", editor[0] ? editor : "(none)");
7573         if (editor[0]) {
7574             printf(" options: %s\n", editopts[0] ? editopts : "(none)");
7575             printf(" file:    %s\n", editfile[0] ? editfile : "(none)");
7576         }
7577         printf("\n");
7578         break;
7579
7580 #ifdef BROWSER
7581       case SHBROWSE:
7582         if (!browser[0]) {
7583             s = getenv("BROWSER");
7584             if (s) ckstrncpy(browser,s,CKMAXPATH);
7585         }
7586         printf("\n browser: %s\n", browser[0] ? browser : "(none)");
7587         if (browser[0]) {
7588             printf(" options: %s\n", browsopts[0] ? browsopts : "(none)");
7589             printf(" url:     %s\n", browsurl[0] ? browsurl : "(none)");
7590         }
7591         printf("\n");
7592         break;
7593 #endif /* BROWSER */
7594 #endif /*  NOFRILLS */
7595 #endif /* NOPUSH */
7596
7597 #ifndef NOLOCAL
7598 #ifdef CK_TAPI
7599       case SHTAPI:                      /* TAPI options */
7600 #ifdef IKSD
7601         if (inserver) {
7602             printf("Sorry, command disabled.\r\n");
7603             return(success = 0);
7604         }
7605 #endif /* IKSD */
7606         shotapi(0);
7607         break;
7608       case SHTAPI_L:                    /* TAPI Locations */
7609 #ifdef IKSD
7610         if (inserver) {
7611             printf("Sorry, command disabled.\r\n");
7612             return(success = 0);
7613         }
7614 #endif /* IKSD */
7615         shotapi(1);
7616         break;
7617       case SHTAPI_M:                    /* TAPI Modem */
7618 #ifdef IKSD
7619         if (inserver) {
7620             printf("Sorry, command disabled.\r\n");
7621             return(success = 0);
7622         }
7623 #endif /* IKSD */
7624         shotapi(2);
7625         break;
7626       case SHTAPI_C:                    /* TAPI Comm */
7627 #ifdef IKSD
7628         if (inserver) {
7629             printf("Sorry, command disabled.\r\n");
7630             return(success = 0);
7631         }
7632 #endif /* IKSD */
7633         shotapi(3);
7634         break;
7635 #endif /* CK_TAPI */
7636
7637       case SHTCP:                       /* SHOTCP */
7638         printf("\n");
7639         shotcp(0);
7640         printf("\n");
7641         break;
7642
7643 #ifdef TNCODE
7644       case SHTEL:                       /* TELNET */
7645         printf("\n");
7646         shotel(0);
7647         printf("\n");
7648         break;
7649
7650       case SHTOPT:                      /* TELNET OPTIONS */
7651         printf("\n");
7652         shotopt(0);
7653         printf("\n");
7654         break;
7655 #endif /* TNCODE */
7656
7657 #ifdef CK_TRIGGER
7658       case SHTRIG: {
7659           extern char * tt_trigger[], * triggerval;
7660           int i;
7661           if (!tt_trigger[0]) {
7662               printf(" Triggers: (none)\n");
7663           } else {
7664               printf(" Triggers:\n");
7665               for (i = 0; i < TRIGGERS; i++) {
7666                   if (!tt_trigger[i])
7667                     break;
7668                   printf("  \"%s\"\n",tt_trigger[i]);
7669               }
7670               printf(" Most recent trigger encountered: ");
7671               if (triggerval)
7672                 printf("\"%s\"\n",triggerval);
7673               else
7674                 printf("(none)\n");
7675           }
7676           break;
7677       }
7678 #endif /* CK_TRIGGER */
7679 #endif /* NOLOCAL */
7680
7681 #ifndef NOSPL
7682       case SHINP:
7683         shoinput();
7684         break;
7685 #endif /* NOSPL */
7686
7687       case SHLOG: {
7688 #ifndef MAC
7689 #ifdef IKSD
7690           if (inserver &&
7691 #ifdef CK_LOGIN
7692               isguest
7693 #else /* CK_LOGIN */
7694               0
7695 #endif /* CK_LOGIN */
7696              ) {
7697             printf("Sorry, command disabled.\r\n");
7698             return(success = 0);
7699         }
7700 #endif /* IKSD */
7701 #ifdef DEBUG
7702           printf("\n Debug log:       %s", deblog ? debfil : "(none)");
7703           {
7704               extern int debtim;
7705               if (debtim) printf(" (timestamps)");
7706               printf("\n");
7707           }
7708 #endif /* DEBUG */
7709 #ifndef NOXFER
7710           printf(" Packet log:      %s\n",   pktlog ? pktfil : "(none)");
7711 #endif /* NOXFER */
7712 #ifndef NOLOCAL
7713           printf(" Session log:     %s",   seslog ? sesfil : "(none)");
7714           {
7715               extern int sessft, slogts, slognul;
7716               switch (sessft) {
7717                 case XYFT_T: printf(" (text)"); break;
7718                 case XYFT_B: printf(" (binary)"); break;
7719                 case XYFT_D: printf(" (debug)"); break;
7720               }
7721               if (slogts) printf("(timestamped)");
7722               if (slognul) printf("(null-padded)");
7723               printf("\n");
7724           }
7725
7726 #endif /* NOLOCAL */
7727 #ifdef TLOG
7728           printf(" Transaction log: %s (%s)\n",
7729                  (tralog ? (*trafil ? trafil : "(none)") : "(none)"),
7730                  (tlogfmt ? ((tlogfmt == 2) ? "ftp" : "verbose") : "brief")
7731                  );
7732 #endif /* TLOG */
7733 #ifdef CKLOGDIAL
7734             printf(" Connection log:  %s\n", dialog ? diafil : "(none)");
7735 #endif /* CKLOGDIAL */
7736           printf("\n");
7737 #endif /* MAC */
7738           break;
7739       }
7740
7741 #ifndef NOSPL
7742       case SHOUTP:                      /* OUTPUT */
7743         shooutput();
7744         break;
7745 #endif /* NOSPL */
7746
7747 #ifdef PATTERNS
7748       case SHOPAT:                      /* PATTERNS */
7749         shopat();
7750         break;
7751 #endif /* PATTERNS */
7752
7753 #ifdef STREAMING
7754       case SHOSTR: {                    /* STREAMING */
7755           extern int streamrq, clearrq, cleared;
7756           extern long tfcps;
7757           debug(F101,"SHOW RELIABLE reliable","",reliable);
7758           printf("\n Reliable:     %s\n",showooa(reliable));
7759           printf(" Clearchannel: %s\n",showooa(clearrq));
7760           printf(" Streaming:    %s\n\n",showooa(streamrq));
7761           if ((!local && (streamrq == SET_ON)) ||
7762               (streamrq == SET_AUTO && reliable))
7763             printf(" Streaming will be done if requested.\n");
7764           else if ((streamrq == SET_OFF) ||
7765                    ((streamrq == SET_AUTO) && !reliable))
7766             printf(" Streaming will not be requested and will not be done.\n");
7767           else if ((streamrq == SET_ON) ||
7768                    ((streamrq == SET_AUTO) && reliable))
7769             printf(
7770 " Streaming will be requested and will be done if the other Kermit agrees.\n");
7771           printf(" Last transfer: %sstreaming%s, %ld cps.\n",
7772                  streamed > 0 ? "" : "no ",
7773                  cleared ? ", clearchannel" : "",
7774                  tfcps
7775                  );
7776           printf("\n");
7777           break;
7778       }
7779 #endif /* STREAMING */
7780
7781       case SHOIKS:
7782         return(sho_iks());
7783         break;
7784
7785 #ifdef CK_AUTHENTICATION
7786       case SHOAUTH:
7787         return(sho_auth(0));
7788 #endif /* CK_AUTHENTICATION */
7789
7790 #ifndef NOFTP
7791       case SHOFTP: {
7792 #ifdef IKSD
7793         if (inserver) {
7794             printf("Sorry, command disabled.\r\n");
7795             return(success = 0);
7796         }
7797 #endif /* IKSD */
7798 #ifdef SYSFTP
7799         {
7800             extern char ftpapp[], ftpopts[];
7801             printf(" ftp-client:  %s\n", ftpapp[0] ? ftpapp : "(none)");
7802             if (ftpapp[0])
7803               printf(" ftp options: %s\n", ftpopts[0] ? ftpopts : "(none)");
7804         }
7805 #else
7806 #ifdef NEWFTP
7807         shoftp(0);
7808 #else
7809         printf("(No FTP client included in this version of Kermit.)\n");
7810 #endif /* NEWFTP */
7811 #endif /* SYSFTP */
7812         break;
7813       }
7814 #endif /* NOFTP */
7815
7816 #ifndef NOCMDL
7817       case SHXOPT: {
7818 #ifdef IKSDB
7819           extern int dbenabled;
7820           extern char * dbfile, * dbdir;
7821 #endif /* IKSDB */
7822 #ifdef CKWTMP
7823           extern int ckxwtmp;
7824           extern char * wtmpfile;
7825 #endif /* CKWTMP */
7826 #ifdef CK_LOGIN
7827           extern int ckxanon, xferlog, logintimo;
7828           extern char * xferfile;
7829 #ifdef UNIX
7830           extern int ckxpriv;
7831 #endif /* UNIX */
7832 #ifdef CK_PERMS
7833           extern int ckxperms;
7834 #endif /* CK_PERMS */
7835 #endif /* CK_LOGIN */
7836           extern char * bannerfile, * helpfile;
7837
7838 #ifdef IKSD
7839           if (inserver &&
7840 #ifdef CK_LOGIN
7841               isguest
7842 #else /* CK_LOGIN */
7843               0
7844 #endif /* CK_LOGIN */
7845               ) {
7846               printf("Sorry, command disabled.\r\n");
7847               return(success = 0);
7848           }
7849 #endif /* IKSD */
7850           printf("\n");
7851           if (!cmdint)
7852             printf(" --nointerrupts\n");
7853           printf(" --bannerfile=%s\n",bannerfile ? bannerfile : "(null)");
7854           printf(" --cdfile:%s\n",cdmsgstr ? cdmsgstr : "(null)");
7855           printf(" --cdmessage:%d\n",srvcdmsg);
7856           printf(" --helpfile:%d\n",helpfile);
7857           if (inserver) {
7858               printf("\n");
7859               break;
7860           }
7861 #ifdef CKSYSLOG
7862 #ifdef SYSLOGLEVEL
7863           printf(" --syslog:%d (forced)\n",ckxsyslog);
7864 #else
7865           printf(" --syslog:%d\n",ckxsyslog);
7866 #endif /* SYSLOGLEVEL */
7867 #endif /* CKSYSLOG */
7868 #ifdef CKWTMP
7869           printf(" --wtmplog:%d\n",ckxwtmp);
7870           printf(" --wtmpfile=%s\n",wtmpfile ? wtmpfile : "(null)");
7871 #endif /* CKWTMP */
7872 #ifdef IKSD
7873 #ifdef CK_LOGIN
7874           printf(" --anonymous:%d\n",ckxanon);
7875 #ifdef UNIX
7876           printf(" --privid:%d\n",ckxpriv);
7877 #endif /* UNIX */
7878 #ifdef CK_PERMS
7879           printf(" --permission:%04o\n",ckxperms);
7880 #endif /* CK_PERMS */
7881           printf(" --initfile:%s\n",anonfile ? anonfile : "(null)");
7882           printf(" --userfile:%s\n",userfile ? userfile : "(null)");
7883           printf(" --root:%s\n",anonroot ? anonroot : "(null)");
7884           printf(" --xferlog=%d\n",xferlog);
7885           printf(" --xferfile=%s\n",xferfile ? xferfile : "(null)");
7886           printf(" --timeout=%d\n",logintimo);
7887 #endif /* CK_LOGIN */
7888 #ifdef IKSDB
7889           printf(" --database=%d\n",dbenabled);
7890           printf(" --dbfile=%s\n",dbfile ? dbfile : "(null)");
7891           if (dbdir)
7892             printf("   (db directory=[%s])\n",dbdir);
7893 #endif /* IKSDB */
7894 #ifdef IKSDCONF
7895           printf(" IKSD conf=%s\n",iksdconf);
7896 #endif /* IKSDCONF */
7897 #endif /* IKSD */
7898           printf("\n");
7899           break;
7900       }
7901 #endif /* NOCMDL */
7902
7903       case SHCD: {
7904           extern char * myhome;
7905           s = getenv("CDPATH");
7906           if (!s) s = "(none)";
7907           printf("\n current directory:  %s\n", zgtdir());
7908           printf(" previous directory: %s\n", prevdir ? prevdir : "(none)");
7909           printf(" cd home:            %s\n", homepath());
7910           printf(" cd path:            %s\n", ckcdpath ? ckcdpath : s);
7911           printf(" cd message:         %s\n", showoff(srvcdmsg & 2));
7912           printf(" server cd-message:  %s\n", showoff(srvcdmsg & 1));
7913           printf(" cd message file:    %s\n\n",cdmsgstr ? cdmsgstr : "(none)");
7914           break;
7915       }
7916 #ifndef NOCSETS
7917       case SHASSOC:
7918         (VOID) showassoc();
7919         break;
7920 #endif /* NOCSETS */
7921
7922 #ifdef CKLOGDIAL
7923       case SHCONNX:
7924 #ifdef NEWFTP
7925         if (ftpisconnected()) {
7926             extern char cxlogbuf[];
7927             dologshow(W_FTP | 1);
7928             if (cxlogbuf[0])
7929               dologshow(1);
7930         } else {
7931 #endif /* NEWFTP */
7932             dologshow(1);
7933 #ifdef NEWFTP
7934         }
7935 #endif /* NEWFTP */
7936         break;
7937 #endif /* CKLOGDIAL */
7938
7939       case SHOPTS:
7940         optlines = 0;
7941 #ifndef NOFRILLS
7942         (VOID) showdelopts();
7943 #endif /* NOFRILLS */
7944 #ifdef DOMYDIR
7945         (VOID) showdiropts();
7946 #endif /* DOMYDIR */
7947 #ifdef CKPURGE
7948         (VOID) showpurgopts();
7949 #endif /* CKPURGE */
7950         (VOID) showtypopts();
7951         break;
7952
7953 #ifndef NOLOCAL
7954       case SHOFLO:
7955         (VOID) shoflow();
7956         break;
7957 #endif /* NOLOCAL */
7958
7959 #ifndef NOXFER
7960       case SHOXFER:
7961         (VOID) shoxfer();
7962         break;
7963 #endif /* NOXFER */
7964
7965 #ifdef CK_RECALL
7966       case SHHISTORY:
7967         (VOID) cmhistory();
7968         break;
7969 #endif /* CK_RECALL */
7970
7971 #ifndef NOSEXP
7972 #ifndef NOSPL
7973       case SHSEXP:
7974         (VOID) shosexp();
7975         break;
7976 #endif /* NOSPL */
7977 #endif /* NOSEXP */
7978
7979 #ifdef ANYSSH
7980       case SHOSSH:
7981         (VOID) shossh();
7982         break;
7983 #endif /* ANYSSH */
7984
7985 #ifdef KUI
7986       case SHOGUI:
7987         (VOID) shogui();
7988         break;
7989 #endif /* KUI */
7990
7991 #ifndef NOFRILLS
7992 #ifndef NORENAME
7993       case SHOREN:
7994         (VOID) shorename();
7995         break;
7996 #endif  /* NORENAME */
7997 #endif  /* NOFRILLS */
7998
7999       default:
8000         printf("\nNothing to show...\n");
8001         return(-2);
8002     }
8003     return(success = 1);
8004 }
8005
8006 #ifndef NOXFER
8007 int
8008 shoatt() {
8009     printf("Attributes: %s\n", showoff(atcapr));
8010     if (!atcapr) return(0);
8011     printf(" Blocksize: %s\n", showoff(atblki));
8012     printf(" Date: %s\n", showoff(atdati));
8013     printf(" Disposition: %s\n", showoff(atdisi));
8014     printf(" Encoding (Character Set): %s\n", showoff(atenci));
8015     printf(" Length: %s\n", showoff(atleni));
8016     printf(" Type (text/binary): %s\n", showoff(attypi));
8017     printf(" System ID: %s\n", showoff(atsidi));
8018     printf(" System Info: %s\n", showoff(atsysi));
8019 #ifdef CK_PERMS
8020     printf(" Permissions In:  %s\n", showoff(atlpri));
8021     printf(" Permissions Out: %s\n", showoff(atlpro));
8022 #endif /* CK_PERMS */
8023 #ifdef STRATUS
8024     printf(" Format: %s\n", showoff(atfrmi));
8025     printf(" Creator: %s\n", showoff(atcrei));
8026     printf(" Account: %s\n", showoff(atacti));
8027 #endif /* STRATUS */
8028     return(0);
8029 }
8030 #endif /* NOXFER */
8031
8032 #ifndef NOSPL
8033 int                                     /* SHOW MACROS */
8034 shomac(s1, s2) char *s1, *s2; {
8035     int x, n, pp;
8036     pp = 0;                             /* Parenthesis counter */
8037
8038     debug(F110,"shomac s1",s1,0);
8039     debug(F110,"shomac s2",s2,0);
8040
8041 #ifdef IKSD
8042     if ( inserver &&
8043 #ifdef IKSDCONF
8044         iksdcf
8045 #else /* IKSDCONF */
8046         1
8047 #endif /* IKSDCONF */
8048         ) {
8049         if (!ckstrcmp("on_exit",s1,-1,0) ||
8050             !ckstrcmp("on_logout",s1,-1,0))
8051           return(0);
8052     }
8053 #endif /* IKSD */
8054
8055     if (!s1)
8056       return(0);
8057     else
8058       printf("%s = ",s1);               /* Print blank line and macro name */
8059     n = (int)strlen(s1) + 4;            /* Width of current line */
8060     if (!s2) s2 = "(not defined)";
8061
8062     while ((x = *s2++)) {               /* Loop thru definition */
8063         if (x == '(') pp++;             /* Treat commas within parens */
8064         if (x == ')') pp--;             /* as ordinary text */
8065         if (pp < 0) pp = 0;             /* Outside parens, */
8066         if (x == ',' && pp == 0) {      /* comma becomes comma-dash-NL. */
8067             putchar(',');
8068             putchar('-');
8069             x = '\n';
8070         }
8071         if (inserver && (x == '\n'))    /* Send CR before LF */
8072           putchar(CR);
8073         putchar((CHAR)x);               /* Output the character */
8074         if (x == '\n') {                /* If it was a newline */
8075 #ifdef UNIX
8076 #ifdef NOSETBUF
8077             fflush(stdout);
8078 #endif /* NOSETBUF */
8079 #endif /* UNIX */
8080             putchar(' ');               /* Indent the next line 1 space */
8081             while(*s2 == ' ') s2++;     /* skip past leading blanks */
8082             n = 2;                      /* restart the character counter */
8083             slc++;                      /* and increment the line counter. */
8084         } else if (++n > (cmd_cols - 1)) { /* If line is too wide */
8085             putchar('-');               /* output a dash */
8086             if (inserver)
8087               putchar(CR);              /* and a carriage return */
8088             putchar(NL);                /* and a newline */
8089 #ifdef UNIX
8090 #ifdef NOSETBUF
8091             fflush(stdout);
8092 #endif /* NOSETBUF */
8093 #endif /* UNIX */
8094             n = 1;                      /* and restart the char counter */
8095             slc++;                      /* and increment the line counter */
8096         }
8097         if (n < 3 && slc > (cmd_rows - 3)) { /* If new line and screen full */
8098             if (!askmore()) return(-1); /* ask if they want more. */
8099             n = 1;                      /* They do, start a new line */
8100             slc = 0;                    /* and restart line counter */
8101         }
8102     }
8103     if (inserver)
8104       putchar(CR);
8105     putchar(NL);                        /* End of definition */
8106     if (++slc > (cmd_rows - 3)) {
8107         if (!askmore()) return(-1);
8108         slc = 0;
8109     }
8110     return(0);
8111 }
8112 #endif /* NOSPL */
8113 #endif /* NOSHOW */
8114
8115 int x_ifnum = 0;                        /* Flag for IF NUMERIC active */
8116
8117 #ifndef NOSPL
8118 /* Evaluate an arithmetic expression. */
8119 /* Code adapted from ev, by Howie Kaye of Columbia U & others. */
8120
8121 static int xerror = 0;
8122 int divbyzero = 0;
8123 static char *cp;
8124 static CK_OFF_T tokval;
8125 static char curtok;
8126 static CK_OFF_T expval;
8127
8128 #define LONGBITS (8*sizeof (CK_OFF_T))
8129 #define NUMBER 'N'
8130 #define N_EOT 'E'
8131
8132 /*
8133  Replacement for strchr() and index(), neither of which seem to be universal.
8134 */
8135
8136 static char *
8137 #ifdef CK_ANSIC
8138 windex(char * s, char c)
8139 #else
8140 windex(s,c) char *s, c;
8141 #endif /* CK_ANSIC */
8142 /* windex */ {
8143     while (*s != NUL && *s != c) s++;
8144     if (*s == c) return(s); else return(NULL);
8145 }
8146
8147
8148 /*
8149  g e t t o k
8150
8151  Returns the next token.  If token is a NUMBER, sets tokval appropriately.
8152 */
8153 static char
8154 gettok() {
8155     char tbuf[80] /* ,*tp */ ;          /* Buffer to accumulate number */
8156
8157     while (isspace(*cp))                /* Skip past leading spaces */
8158       cp++;
8159
8160     debug(F110,"GETTOK",cp,0);
8161
8162     switch (*cp) {
8163       case '$':                         /* ??? */
8164       case '+':                         /* Add */
8165       case '-':                         /* Subtract or Negate */
8166       case '@':                         /* Greatest Common Divisor */
8167       case '*':                         /* Multiply */
8168       case '/':                         /* Divide */
8169       case '%':                         /* Modulus */
8170       case '<':                         /* Left shift */
8171       case '>':                         /* Right shift */
8172       case '&':                         /* And */
8173       case '|':                         /* Or */
8174       case '#':                         /* Exclusive Or */
8175       case '~':                         /* Not */
8176       case '^':                         /* Exponent */
8177       case '!':                         /* Factorial */
8178       case '(':                         /* Parens for grouping */
8179       case ')': return(*cp++);          /* operator, just return it */
8180       case '\n':
8181       case '\0': return(N_EOT);         /* End of line, return that */
8182     }
8183 #ifdef COMMENT
8184 /* This is the original code, which allows only integer numbers. */
8185
8186     if (isxdigit(*cp)) {                /* Digit, must be a number */
8187         int radix = 10;                 /* Default radix */
8188         for (tp = tbuf; isxdigit(*cp); cp++)
8189           *tp++ = (char) (isupper(*cp) ? tolower(*cp) : *cp);
8190         *tp = '\0';                     /* End number */
8191         switch(isupper(*cp) ? tolower(*cp) : *cp) { /* Examine break char */
8192           case 'h':
8193           case 'x': radix = 16; cp++; break; /* if radix signifier... */
8194           case 'o':
8195           case 'q': radix = 8; cp++; break;
8196           case 't': radix = 2; cp++; break;
8197         }
8198         for (tp = tbuf, tokval = 0; *tp != '\0'; tp++)  {
8199             int dig;
8200             dig = *tp - '0';            /* Convert number */
8201             if (dig > 10) dig -= 'a'-'0'-10;
8202             if (dig >= radix) {
8203                 if (cmdlvl == 0 && !x_ifnum && !xerror)
8204                   printf("?Invalid digit '%c' in number\n",*tp);
8205                 xerror = 1;
8206                 return(NUMBER);
8207             }
8208             tokval = radix*tokval + dig;
8209         }
8210         return(NUMBER);
8211     }
8212     if (cmdlvl == 0 && !x_ifnum && !xerror)
8213       printf("Invalid character '%c' in input\n",*cp);
8214     xerror = 1;
8215     cp++;
8216     return(gettok());
8217 #else
8218 /* This code allows non-numbers to be treated as macro names */
8219     {
8220         int i, x;
8221         char * s, * cp1;
8222         cp1 = cp;
8223         tp = tbuf;
8224         for (i = 0; i < 80; i++) {
8225             /* Look ahead to next break character */
8226             /* pretty much anything that is not in the switch() above. */
8227             if (isalpha(*cp) || isdigit(*cp) ||
8228                 *cp == '_' || *cp == ':' || *cp == '.' ||
8229                 *cp == '[' || *cp == ']' ||
8230                 *cp == '{' || *cp == '}'
8231                 )
8232               tbuf[i] = *cp++;
8233             else
8234               break;
8235         }
8236         if (i >= 80) {
8237             printf("Too long - \"%s\"\n", cp1);
8238             xerror = 1;
8239             cp++;
8240             return(gettok());
8241         }
8242         if (xerror) return(NUMBER);
8243
8244         tbuf[i] = NUL;
8245         s = tbuf;
8246         if (!isdigit(tbuf[0])) {
8247             char * s2 = NULL;
8248             x = mxlook(mactab,tbuf,nmac);
8249             debug(F111,"gettok mxlook",tbuf,x);
8250             if (x < 0) {
8251                 if (cmdlvl == 0 && !x_ifnum && !xerror)
8252                   printf("Bad number - \"%s\"\n",tbuf);
8253                 xerror = 1;
8254                 cp++;
8255                 return(gettok());
8256             }
8257             s2 = mactab[x].mval;
8258             if (!s2) s2 = "";
8259             if (*s2) s = s2;
8260         }
8261 #ifdef CKFLOAT
8262         x = isfloat(s,0);
8263 #else
8264         x = chknum(s);
8265 #endif /* CKFLOAT */
8266         if (x > 0) {
8267             tokval = ckatofs(s);
8268         } else {
8269             if (cmdlvl == 0 && !x_ifnum && !xerror)
8270               printf("Bad number - \"%s\"\n",tbuf);
8271             xerror = 1;
8272             cp++;
8273             return(gettok());
8274         }
8275         return(NUMBER);
8276     }
8277 #endif /* COMMENT */
8278 }
8279
8280 static CK_OFF_T
8281 #ifdef CK_ANSIC
8282 expon(CK_OFF_T x, CK_OFF_T y)
8283 #else
8284 expon(x,y) CK_OFF_T x,y;
8285 #endif /* CK_ANSIC */
8286 /* expon */ {
8287     CK_OFF_T result = 1;
8288     int sign = 1;
8289     if (y < 0) return(0);
8290     if (x < 0) {
8291         x = -x;
8292         if (y & 1) sign = -1;
8293     }
8294     while (y != 0) {
8295         if (y & 1) result *= x;
8296         y >>= 1;
8297         if (y != 0) x *= x;
8298   }
8299   return(result * sign);
8300 }
8301
8302 /*
8303  * factor ::= simple | simple ^ factor
8304  *
8305  */
8306 static VOID
8307 factor() {
8308     CK_OFF_T oldval;
8309     simple();
8310     if (curtok == '^') {
8311         oldval = expval;
8312         curtok = gettok();
8313         factor();
8314         expval = expon(oldval,expval);
8315     }
8316 }
8317
8318 /*
8319  * termp ::= NULL | {*,/,%,&} factor termp
8320  *
8321  */
8322 static VOID
8323 termp() {
8324     while (curtok == '*' || curtok == '/' || curtok == '%' || curtok == '&') {
8325         CK_OFF_T oldval;
8326         char op;
8327         op = curtok;
8328         curtok = gettok();              /* skip past operator */
8329         oldval = expval;
8330         factor();
8331         switch(op) {
8332           case '*': expval = oldval * expval; break;
8333           case '/':
8334           case '%':
8335             if (expval == 0) {
8336                 if (!x_ifnum)
8337                   printf("?Divide by zero\n");
8338                 xerror = 1;
8339                 divbyzero = 1;
8340                 expval = -1;
8341             } else
8342               expval = (op == '/') ? (oldval / expval) : (oldval % expval);
8343             break;
8344           case '&':
8345             expval = oldval & expval; break;
8346         }
8347     }
8348 }
8349
8350 static CK_OFF_T
8351 #ifdef CK_ANSIC
8352 fact(CK_OFF_T x)
8353 #else
8354 fact(x) CK_OFF_T x;
8355 #endif /* CK_ANSIC */
8356 /* fact */ {                            /* factorial */
8357     CK_OFF_T result = 1;
8358     while (x > 1)
8359       result *= x--;
8360     return(result);
8361 }
8362
8363 /*
8364  * term ::= factor termp
8365  *
8366  */
8367 static VOID
8368 term() {
8369     factor();
8370     termp();
8371 }
8372
8373 static CK_OFF_T
8374 #ifdef CK_ANSIC
8375 gcd(CK_OFF_T x, CK_OFF_T y)
8376 #else
8377 gcd(x,y) CK_OFF_T x,y;
8378 #endif /* CK_ANSIC */
8379 /* gcd */ {                             /* Greatest Common Divisor */
8380     int nshift = 0;
8381     if (x < 0) x = -x;
8382     if (y < 0) y = -y;                  /* validate arguments */
8383     if (x == 0 || y == 0) return(x + y);    /* this is bogus */
8384
8385     while (!((x & 1) | (y & 1))) {      /* get rid of powers of 2 */
8386         nshift++;
8387         x >>= 1;
8388         y >>= 1;
8389     }
8390     while (x != 1 && y != 1 && x != 0 && y != 0) {
8391         while (!(x & 1)) x >>= 1;       /* eliminate unnecessary */
8392         while (!(y & 1)) y >>= 1;       /* powers of 2 */
8393         if (x < y) {                    /* force x to be larger */
8394             CK_OFF_T t;
8395             t = x;
8396             x = y;
8397             y = t;
8398         }
8399         x -= y;
8400     }
8401     if (x == 0 || y == 0) return((x + y) << nshift); /* gcd is non-zero one */
8402     else return((CK_OFF_T) 1 << nshift);    /* else gcd is 1 */
8403 }
8404
8405 /*
8406  * exprp ::= NULL | {+,-,|,...} term exprp
8407  *
8408  */
8409 static VOID
8410 exprp() {
8411     while (windex("+-|<>#@",curtok) != NULL) {
8412         CK_OFF_T oldval;
8413         char op;
8414         op = curtok;
8415         curtok = gettok();              /* skip past operator */
8416         oldval = expval;
8417         term();
8418         switch(op) {
8419           case '+' : expval = oldval + expval; break;
8420           case '-' : expval = oldval - expval; break;
8421           case '|' : expval = oldval | expval; break;
8422           case '#' : expval = oldval ^ expval; break;
8423           case '@' : expval = gcd(oldval,expval); break;
8424           case '<' : expval = oldval << expval; break;
8425           case '>' : expval = oldval >> expval; break;
8426         }
8427     }
8428 }
8429
8430 /*
8431  * expr ::= term exprp
8432  *
8433  */
8434 static VOID
8435 expr() {
8436     term();
8437     exprp();
8438 }
8439
8440 static CK_OFF_T
8441 xparse() {
8442     curtok = gettok();
8443     expr();
8444 #ifdef COMMENT
8445     if (curtok == '$') {
8446         curtok = gettok();
8447         if (curtok != NUMBER) {
8448             if (cmdlvl == 0 && !x_ifnum)
8449               printf("?Illegal radix\n");
8450             xerror = 1;
8451             return(0);
8452         }
8453         curtok = gettok();
8454     }
8455 #endif /* COMMENT */
8456     if (curtok != N_EOT) {
8457         if (cmdlvl == 0 && !x_ifnum && !xerror)
8458           printf("?Extra characters after expression\n");
8459         xerror = 1;
8460     }
8461     return(expval);
8462 }
8463
8464 char *                                  /* Silent front end for evala() */
8465 evalx(s) char *s; {
8466     char * p;
8467     int t;
8468     t = x_ifnum;
8469     x_ifnum = 1;
8470     p = evala(s);
8471     x_ifnum = t;
8472     return(p);
8473 }
8474
8475 char *
8476 evala(s) char *s; {
8477     CK_OFF_T v;                         /* Numeric value */
8478     if (!s) return("");
8479     xerror = 0;                         /* Start out with no error */
8480     divbyzero = 0;
8481     cp = s;                             /* Make the argument global */
8482     v = xparse();                       /* Parse the string */
8483     return(xerror ? "" : ckfstoa(v));   /* Return empty string on error */
8484 }
8485
8486 /*
8487  * simplest ::= NUMBER | ( expr )
8488  *
8489  */
8490 static VOID
8491 simplest() {
8492     char * p;
8493     p = cp;
8494     if (curtok == NUMBER)
8495       expval = tokval;
8496     else if (curtok == '(') {
8497         curtok = gettok();              /* skip over paren */
8498         expr();
8499         if (curtok != ')') {
8500             if (cmdlvl == 0 && !x_ifnum && !xerror)
8501               printf("?Missing right parenthesis\n");
8502             xerror = 1;
8503         }
8504         debug(F110,"GETTOK SIMPLEST ()",p,0);
8505
8506     } else {
8507         if (cmdlvl == 0 && !x_ifnum && !xerror)
8508           printf("?Operator unexpected\n");
8509         xerror = 1;
8510     }
8511     curtok = gettok();
8512 }
8513
8514 /*
8515  * simpler ::= simplest | simplest !
8516  *
8517  */
8518 static VOID
8519 simpler() {
8520     simplest();
8521     if (curtok == '!') {
8522         curtok = gettok();
8523         expval = fact(expval);
8524     }
8525 }
8526
8527 /*
8528  * simple ::= {-,~,!} simpler | simpler
8529  *
8530  */
8531
8532 static VOID
8533 simple() {
8534     if (curtok == '-' || curtok == '~' || curtok == '!' || curtok == '+') {
8535         int op = curtok;
8536         curtok = gettok();              /* skip over - sign */
8537         simpler();                      /* parse the factor again */
8538         if (op != '+')
8539           expval = (op == '-') ? -expval : ((op == '!') ? !expval : ~expval);
8540     } else simpler();
8541 }
8542
8543 /*  D C L A R R A Y  --  Declare an array  */
8544 /*
8545   Call with:
8546    char a = single character designator for the array, e.g. "a".
8547    int  n = size of array.  -1 means to undeclare the array.
8548   Returns:
8549    0 or greater on success, having created the requested array with
8550      with n+1 elements, 0..n.  If an array of the same name existed
8551      previously, it is destroyed.  The new array has all its elements
8552      initialized to NULL pointers.  When an array is successfully created,
8553      the return value is its index (0 = 'a', 1 = 'b', and so on.)
8554   -1 on failure (because 'a' out of range or malloc failure).
8555 */
8556 int
8557 #ifdef CK_ANSIC
8558 dclarray(char a, int n)
8559 #else
8560 dclarray(a,n) char a; int n;
8561 #endif /* CK_ANSIC */
8562 /* dclarray */ {
8563     char c, **p; int i, n2, rc;
8564
8565     if (a > 63 && a < 91) a += 32;      /* Convert letters to lowercase */
8566     if (a < ARRAYBASE || a > 122)       /* Verify name */
8567       return(-1);
8568
8569     if (n < 0)                          /* Check arg */
8570       return(-1);
8571     if (n+1 < 0)                        /* MAXINT+1 wraps around */
8572       return(-1);
8573
8574     c = a;
8575     a -= ARRAYBASE;                     /* Convert name to number */
8576     rc = a;                             /* Array index will be return code */
8577     if ((p = a_ptr[a]) != NULL) {       /* Delete old array of same name */
8578         if (a_link[a] > -1) {           /* Is it a link? */
8579             if (n == 0) {               /* If we're just deleting it */
8580                 a_ptr[a] = (char **) NULL; /* clear all the info. */
8581                 a_dim[a] = 0;
8582                 a_link[a] = -1;
8583                 return(0);
8584             }                           /* Not deleting */
8585             a = a_link[a];              /* Switch to linked-to array */
8586         }
8587         n2 = a_dim[a];                  /* Real array */
8588         for (i = 0; i <= n2; i++) {     /* First delete its elements */
8589             if (p[i]) {
8590                 free(p[i]);
8591                 p[i] = NULL;
8592             }
8593         }
8594         free((char *)a_ptr[a]);         /* Then the element list */
8595         if (n == 0) {                   /* If undeclaring this array... */
8596             for (i = 0; i < 122 - ARRAYBASE; i++) { /* Any linked arrays? */
8597                 if (i != a && a_link[i] == a) {     /* Find them */
8598                     a_ptr[i] = (char **) NULL;      /* and remove them */
8599                     a_dim[i] = 0;
8600                     a_link[i] = -1;
8601                 }
8602             }
8603         }
8604         a_ptr[a] = (char **) NULL;      /* Remove pointer to element list */
8605         a_dim[a] = 0;                   /* Set dimension at zero. */
8606         a_link[a] = -1;                 /* Unset link word */
8607     }
8608     if (n < 0)                          /* If only undeclaring, */
8609       return(0);                        /*  we're done. */
8610     p = (char **) malloc((n+1) * sizeof(char **)); /* Allocate for new array */
8611     if (p == NULL) return(-1);          /* Check */
8612     a_ptr[a] = p;                       /* Save pointer to member list */
8613     a_dim[a] = n;                       /* Save dimension */
8614     for (i = 0; i <= n; i++)            /* Initialize members to null */
8615       p[i] = NULL;
8616     for (i = 0; i < (int) 'z' - ARRAYBASE; i++) { /* Any linked arrays? */
8617         if (i != a && a_link[i] == a) { /* Find and update them */
8618             a_ptr[i] = p;
8619             a_dim[i] = n;
8620         }
8621     }
8622     return(rc);
8623 }
8624
8625 /*  X A R R A Y  -- Convert array name to array index  */
8626
8627 int
8628 xarray(s) char * s; {
8629     char buf[8];
8630     int x;
8631     char c;
8632
8633     if (!s) s = "";
8634     debug(F110,"xarray",s,0);
8635     if (!*s)
8636       return(-1);
8637     x = strlen(s);
8638
8639     buf[0] = NUL;
8640     buf[1] = NUL;
8641     buf[2] = s[0];
8642     buf[3] = (x > 0) ? s[1] : NUL;
8643     buf[4] = (x > 1) ? s[2] : NUL;
8644     buf[5] = (x > 2) ? s[3] : NUL;
8645     buf[6] = NUL;
8646     debug(F110,"xarray buf[3]",&buf[3],0);
8647     s = buf+2;
8648     if (*s == '&') {
8649         buf[1] = CMDQ;
8650         s--;
8651     } else if (*s != CMDQ) {
8652         buf[0] = CMDQ;
8653         buf[1] = '&';
8654         s = buf;
8655     }
8656     debug(F110,"xarray s",s,0);
8657     c = *(s+2);
8658     if (isupper(c))
8659       c = tolower(c);
8660     if (c == '@')
8661       c = 96;
8662     x = (int)c - ARRAYBASE;
8663     if (*(s+3) == '[')
8664       *(s+3) = NUL;
8665     if (x < 0) {
8666         return(-1);
8667     }
8668     if (x > ('z' - ARRAYBASE)) {
8669         debug(F101,"xarray x out of range","",x);
8670         return(-1);
8671     }
8672     if (*(s+3)) {
8673         debug(F110,"xarray syntax",s,0);
8674         return(-1);
8675     }
8676     return(x);
8677 }
8678
8679 /*
8680   boundspair() -- parses blah[n:m]
8681
8682   For use with array segment specifiers and compact substring notation.
8683   Ignores the "blah" part, gets the values of n and m, which can be
8684   numbers, variables, or arithmetic expressions; anything that resolves
8685   to a number.
8686
8687   Call with:
8688    s    - string to parse
8689    sep  - array of permissible bounds separator chars
8690    lo   - pointer to low-bound result (or -1)
8691    hi   - pointer to hi-bound result (or -1)
8692    zz   - pointer to separator char that was encountered (or NUL)
8693   Returns:
8694    -1 on failure
8695     0 on success
8696 */      
8697
8698 int
8699 #ifdef CK_ANSIC
8700 boundspair(char *s, char *sep, int *lo, int *hi, char *zz)
8701 #else
8702 boundspair(s,sep,lo,hi,zz) char *s, *sep, *zz; int *lo, *hi;
8703 #endif /* CK_ANSIC */
8704 {
8705     int i, x, y, range[2], bc = 0;
8706     char c = NUL, *s2 = NULL, buf[256], *p, *q, *r, *e[2], *tmp = NULL;
8707
8708     debug(F110,"boundspair s",s,0);
8709     debug(F110,"boundspair sep",sep,0);
8710
8711     *lo = -1;                           /* Default bounds */
8712     *hi = -1;
8713     *zz = 0;                            /* Default bounds separator */
8714
8715     range[0] = -1;                      /* It's OK -- get contents */
8716     range[1] = -1;                      /* of subscript brackets */
8717     if (!s) s = "";
8718     if (!*s)
8719       return(-1);
8720     makestr(&tmp,s);                    /* Make a pokeable copy */
8721     p = tmp;
8722     q = NULL;
8723     r = NULL;
8724     for (p = s; *p; p++) {              /* Get the two elements */
8725         if (*p == '[') {
8726             bc++;                       /* Bracket counter */
8727             if (bc == 1 && !q) q = p+1;
8728         } else if (*p == ']') {
8729             bc--;
8730             if (bc == 0 && q) *p = NUL;
8731         } else if (bc == 1) {           /* If within brackers */
8732             s2 = ckstrchr(sep,*p);      /* Check for separator */
8733             if (s2) {
8734                 debug(F000,"boundspair *s2","",*s2);
8735                 if (c) {        
8736                     debug(F000,"boundspair","Too many separators",*s2);
8737                     makestr(&tmp,NULL);
8738                     return(-1);
8739                 }
8740                 c = *s2;                /* Separator character */
8741                 *p = NUL;
8742                 r = p+1;
8743             }
8744         }
8745     }
8746     if (bc == 0 && !q) {
8747         /* This allows such constructions as "show array a" */
8748         debug(F110,"boundspair","no brackets",0);
8749         makestr(&tmp,NULL);
8750         return(0);
8751     }
8752     if (bc != 0 || !q) {
8753         debug(F110,"boundspair","unbalanced or missing brackets",0);
8754         makestr(&tmp,NULL);
8755         return(-1);
8756     }
8757     if (!q) q = "";
8758     if (!*q) q = "-1";
8759     if (!r) r = "";
8760     if (!*r) r = "-1";
8761
8762     e[0] = q;
8763     e[1] = r;
8764
8765     debug(F000,"boundspair c","",c);
8766     debug(F110,"boundspair q",q,0);
8767     debug(F110,"boundspair r",r,0);
8768
8769     for (i = 0; i < 2 && e[i]; i++) {
8770         y = 255;                        /* Expand variables, etc. */
8771         s = buf;
8772         zzstring(e[i],&s,&y);
8773         s = evalx(buf);                 /* Evaluate it arithmetically */
8774         if (s) if (*s)
8775           ckstrncpy(buf,s,256);
8776         if (!chknum(buf)) {             /* Did we get a number? */
8777             debug(F110,"boundspair element not numeric",buf,0);
8778             makestr(&tmp,NULL);         /* No, fail. */
8779             return(-1);
8780         }
8781         range[i] = atoi(buf);
8782     }
8783     makestr(&tmp,NULL);                 /* Free temporary poked string */
8784     *lo = range[0];                     /* Return what we got */
8785     *hi = range[1];
8786     *zz = c;
8787     debug(F101,"boundspair lo","",*lo);
8788     debug(F101,"boundspair hi","",*hi);
8789     return(0);
8790 }
8791
8792 /*  A R R A Y B O U N D S  --  Parse array segment notation \&a[n:m]  */
8793
8794 /*
8795   Call with s = array reference, plus two pointers to ints.
8796   Returns -1 on error, or array index, with the two ints set as follows:
8797    \&a[]     -1, -1
8798    \&a[3]     3, -1
8799    \&a[3:17]  3, 17
8800   The array need not be declared -- this routine is just for parsing.
8801 */
8802 int
8803 arraybounds(s,lo,hi) char * s; int * lo, * hi; {
8804     int i, x, y, range[2];
8805     char zz, buf[256], * p, * q;
8806     char * tmp = NULL;
8807
8808     *lo = -1;                           /* Default bounds */
8809     *hi = -1;
8810
8811     if (!s) s = "";                     /* Defense de null args */
8812     if (!*s)
8813       return(-1);
8814
8815     x = xarray(s);                      /* Check basic structure */
8816     debug(F111,"arraybounds xarray",s,x);
8817     if (x < 0)                          /* Not OK, fail. */
8818       return(-1);
8819     y = boundspair(s,":",lo,hi,&zz);
8820     debug(F111,"arraybounds boundspair",s,y);
8821     debug(F101,"arraybounds lo","",*lo);
8822     debug(F101,"arraybounds hi","",*hi);
8823     if (y < 0)                          /* Get bounds */
8824       return(-1);
8825     return(x);
8826 }
8827
8828 /*  A R R A Y N A M  --  Parse an array name  */
8829
8830 /*
8831   Call with pointer to string that starts with the array reference.
8832   String may begin with either \& or just &.
8833   On success,
8834     Returns letter ID (always lowercase) in argument c,
8835       which can also be accent grave (` = 96; '@' is converted to grave);
8836     Dimension or subscript in argument n;
8837     IMPORTANT: These arguments must be provided by the caller as addresses
8838     of ints (not chars), for example:
8839       char *s; int x, y;
8840       arraynam(s,&x,&y);
8841   On failure, returns a negative number, with args n and c set to zero.
8842 */
8843 int
8844 arraynam(ss,c,n) char *ss; int *c; int *n; {
8845     int i, y, pp, len;
8846     char x;
8847     char *s, *p, *sx, *vnp;
8848     /* On stack to allow for recursive calls... */
8849     char vnbuf[ARRAYREFLEN+1];          /* Entire array reference */
8850     char ssbuf[ARRAYREFLEN+1];          /* Subscript in "plain text" */
8851     char sxbuf[16];                     /* Evaluated subscript */
8852
8853     *c = *n = 0;                        /* Initialize return values */
8854     len = strlen(ss);
8855     for (pp = 0,i = 0; i < len; i++) {          /* Check length */
8856         if (ss[i] == '[') {
8857             pp++;
8858         } else if (ss[i] == ']') {
8859             if (--pp == 0)
8860               break;
8861         }
8862     }
8863     if (i > ARRAYREFLEN) {
8864         printf("?Array reference too long - %s\n",ss);
8865         return(-9);
8866     }
8867     ckstrncpy(vnbuf,ss,ARRAYREFLEN);
8868     vnp = vnbuf;
8869     if (vnbuf[0] == CMDQ && vnbuf[1] == '&') vnp++;
8870     if (*vnp != '&') {
8871         printf("?Not an array - %s\n",vnbuf);
8872         return(-9);
8873     }
8874     x = *(vnp + 1);                     /* Fold case of array name */
8875
8876     /* We don't use isupper & tolower here on purpose because these */
8877     /* would produce undesired effects with accented letters. */
8878     if (x > 63 && x < 91) x  = *(vnp + 1) = (char) (x + 32);
8879     if ((x < ARRAYBASE) || (x > 122) || (*(vnp+2) != '[')) {
8880         if (msgflg) {
8881             printf("?Invalid format for array name - %s\n",vnbuf);
8882             return(-9);
8883         } else
8884           return(-2);
8885     }
8886     *c = x;                             /* Return the array name */
8887     s = vnp+3;                          /* Get dimension */
8888     p = ssbuf;
8889     pp = 1;                             /* Bracket counter */
8890     for (i = 0; i < ARRAYREFLEN && *s != NUL; i++) { /* Copy up to ] */
8891         if (*s == '[') pp++;
8892         if (*s == ']' && --pp == 0) break;
8893         *p++ = *s++;
8894     }
8895     if (*s != ']') {
8896         printf("?No closing bracket on array dimension - %s\n",vnbuf);
8897         return(-9);
8898     }
8899     p--;                                /* Trim whitespace from end */
8900     while (*p == SP || *p == HT)
8901       p--;
8902     p++;
8903     *p = NUL;                           /* Terminate subscript with null */
8904     p = ssbuf;                          /* Point to beginning of subscript */
8905     while (*p == SP || *p == HT)        /* Trim whitespace from beginning */
8906       p++;
8907     sx = sxbuf;                         /* Where to put expanded subscript */
8908     y = 16;
8909     {
8910         /* Even if VARIABLE-EVALUATION SIMPLE use RECURSIVE for subscripts */
8911         /* NOTE: This is vulnerable to SIGINT and whatnot... */
8912         int tmp = vareval;              /* Save VARIABLE-EVALUATION setting */
8913         vareval = 1;                    /* Force it to RECURSIVE */
8914         zzstring(p,&sx,&y);             /* Convert variables, etc. */
8915         vareval = tmp;                  /* Restore VARIABLE-EVALUATION */
8916     }
8917     sx = sxbuf;
8918     while (*sx == SP) sx++;
8919     /* debug(F110,"arraynam sx","",sx); */
8920     if (!*sx) {                         /* Empty brackets... */
8921         *n = -17;                       /* (Secret code :-) */
8922         return(-2);
8923     }
8924     p = evala(sx);                      /* Run it thru \fneval()... */
8925     if (p) if (*p) ckstrncpy(sxbuf,p,16); /* We know it has to be a number. */
8926
8927     if (!chknum(sxbuf)) {               /* Make sure it's all digits */
8928         if (msgflg) {
8929             printf("?Array dimension or subscript missing or not numeric\n");
8930             return(-9);
8931         } else
8932           return(-2);
8933     }
8934     if ((y = atoi(sxbuf)) < 0) {
8935         if (cmflgs == 0) printf("\n");
8936         if (msgflg) {
8937             printf("?Array dimension or subscript not positive or zero\n");
8938             return(-9);
8939         } else
8940           return(-2);
8941     }
8942     *n = y;                             /* Return the subscript or dimension */
8943     return(0);
8944 }
8945
8946 /* chkarray returns 0 or greater if array exists, negative otherwise */
8947
8948 int
8949 chkarray(a,i) int a, i; {               /* Check if array is declared */
8950     int x;                              /* and if subscript is in range */
8951     if (a == 64) a = 96;                /* Convert atsign to grave accent */
8952     x = a - ARRAYBASE;                  /* Values must be in range 95-122 */
8953 #ifdef COMMENT
8954     if (x == 0 && maclvl < 0)           /* Macro arg vector but no macro */
8955       return(0);
8956 #endif /* COMMENT */
8957     if (x < 0 || x > 'z' - ARRAYBASE)   /* Not in range */
8958       return(-2);
8959     if (a_ptr[x] == NULL) return(-1);   /* Not declared */
8960     if (i > a_dim[x]) return(-2);       /* Declared but out of range. */
8961     return(a_dim[x]);                   /* All ok, return dimension */
8962 }
8963
8964 #ifdef COMMENT                          /* This isn't used. */
8965 char *
8966 arrayval(a,i) int a, i; {               /* Return value of \&a[i] */
8967     int x; char **p;                    /* (possibly NULL) */
8968     if (a == 64) a = 96;                /* Convert atsign to grave accent */
8969     x = a - ARRAYBASE;                  /* Values must be in range 95-122 */
8970     if (x < 0 || x > 27) return(NULL);  /* Not in range */
8971     if ((x > 0) && (p = a_ptr[x]) == NULL) /* Array not declared */
8972       return(NULL);
8973     if (i > a_dim[x])                   /* Subscript out of range. */
8974       return(NULL);
8975     return(p[i]);                       /* All ok, return pointer to value. */
8976 }
8977 #endif /* COMMENT */
8978
8979 /*
8980   pusharray() is called when an array name is included in a LOCAL statement.
8981   It moves the pointers from the global definition to the stack, and removes
8982   the global definition.  Later, if the same array is declared in the local
8983   context, it occupies the global definition in the normal way.  But when
8984   popclvl() is called, it replaces the global definition with the one saved
8985   here.  The "secret code" is used to indicate to popclv() that it should
8986   remove the global array when popping through this level -- otherwise if a
8987   local array were declared that had no counterpart at any higher level, it
8988   would never be deleted.  This allows Algol-like inheritance to work both
8989   on the way down and on the way back up.
8990 */
8991 int
8992 pusharray(x,z) int x, z; {
8993     int y;
8994     debug(F000,"pusharray x","",x);
8995     debug(F101,"pusharray z","",z);
8996     y = chkarray(x,z);
8997     debug(F101,"pusharray y","",y);
8998     x -= ARRAYBASE;                     /* Convert name letter to index. */
8999     if (x < 0 || x > 27)
9000       return(-1);
9001     if (y < 0) {
9002         aa_ptr[cmdlvl][x] = (char **) NULL;
9003         aa_dim[cmdlvl][x] = -23;        /* Secret code (see popclvl()) */
9004     } else {
9005         aa_ptr[cmdlvl][x] = a_ptr[x];
9006         aa_dim[cmdlvl][x] = y;
9007     }
9008     a_ptr[x] = (char **) NULL;
9009     a_dim[x] = 0;
9010     return(0);
9011 }
9012
9013 /*  P A R S E V A R  --  Parse a variable name or array reference.  */
9014 /*
9015  Call with:
9016    s  = pointer to candidate variable name or array reference.
9017    *c = address of integer in which to return variable ID.
9018    *i = address of integer in which to return array subscript.
9019  Returns:
9020    -2:  syntax error in variable name or array reference.
9021     1:  successful parse of a simple variable, with ID in c.
9022     2:  successful parse of an array reference, w/ID in c and subscript in i.
9023 */
9024 int
9025 parsevar(s,c,i) char *s; int *c, *i; {
9026     char *p;
9027     int x,y,z;
9028
9029     p = s;
9030     if (*s == CMDQ) s++;                /* Point after backslash */
9031
9032     if (*s != '%' && *s != '&') {       /* Make sure it's % or & */
9033         printf("?Not a variable name - %s\n",p);
9034         return(-9);
9035     }
9036     if ((int)strlen(s) < 2) {
9037         printf("?Incomplete variable name - %s\n",p);
9038         return(-9);
9039     }
9040     if (*s == '%' && *(s+2) != '\0') {
9041         printf("?Only one character after '%%' in variable name, please\n");
9042         return(-9);
9043     }
9044     if (*s == '&' && *(s+2) != '[') {
9045         printf("?Array subscript expected - %s\n",p);
9046         return(-9);
9047     }
9048     if (*s == '%') {                    /* Simple variable. */
9049         y = *(s+1);                     /* Get variable ID letter/char */
9050         if (isupper(y)) y -= ('a'-'A'); /* Convert upper to lower case */
9051         *c = y;                         /* Set the return values. */
9052         *i = -1;                        /* No array subscript. */
9053         return(1);                      /* Return 1 = simple variable */
9054     }
9055     if (*s == '&') {                    /* Array reference. */
9056         y = arraynam(s,&x,&z);          /* Go parse it. */
9057         debug(F101,"parsevar arraynam","",y);
9058         if ((y) < 0) {
9059             if (y == -2)
9060               return(pusharray(x,z));
9061             if (y != -9)
9062               printf("?Invalid array reference - %s\n",p);
9063             return(-9);
9064         }
9065         if (chkarray(x,z) < 0) {        /* Check if declared, etc. */
9066             printf("?Array not declared or subscript out of range\n");
9067             return(-9);
9068         }
9069         *c = x;                         /* Return array letter */
9070         *i = z;                         /* and subscript. */
9071         return(2);
9072     }
9073     return(-2);                         /* None of the above. */
9074 }
9075
9076
9077 #define VALN 32
9078
9079 /* Get the numeric value of a variable */
9080 /*
9081   Call with pointer to variable name, pointer to int for return value.
9082   Returns:
9083     0 on success with second arg containing the value.
9084    -1 on failure (bad variable syntax, variable not defined or not numeric).
9085 */
9086 int
9087 varval(s,v) char *s; CK_OFF_T *v; {
9088     char valbuf[VALN+1];                /* s is pointer to variable name */
9089     char name[256];
9090     char *p;
9091     int y;
9092
9093     if (*s != CMDQ) {                   /* Handle macro names too */
9094         ckmakmsg(name,256,"\\m(",s,")",NULL);
9095         s = name;
9096     }
9097     p = valbuf;                         /* Expand variable into valbuf. */
9098     y = VALN;
9099     if (zzstring(s,&p,&y) < 0) return(-1);
9100     p = valbuf;                         /* Make sure value is numeric  */
9101     if (!*p) {                          /* Be nice -- let an undefined */
9102         valbuf[0] = '0';                /* variable be treated as 0.   */
9103         valbuf[1] = NUL;
9104     }
9105     if (chknum(p)) {                    /* Convert numeric string to int */
9106         *v = ckatofs(p);                /* OK */
9107     } else {                            /* Not OK */
9108         p = evala(p);                   /* Maybe it's an expression */
9109         if (!chknum(p))                 /* Did it evaluate? */
9110           return(-1);                   /* No, failure. */
9111         else                            /* Yes, */
9112           *v = ckatofs(p);              /* success */
9113     }
9114     return(0);
9115 }
9116
9117 /* Increment or decrement a variable */
9118 /* Returns -1 on failure, 0 on success */
9119
9120 int
9121 incvar(s,x,z) char *s; CK_OFF_T x; int z; {  /* Increment a numeric variable */
9122     CK_OFF_T n;                         /* s is pointer to variable name */
9123                                         /* x is amount to increment by */
9124                                         /* z != 0 means add */
9125                                         /* z = 0 means subtract */
9126     if (varval(s,&n) < 0)               /* Convert numeric string to int */
9127       return(-1);
9128     if (z)                              /* Increment it by the given amount */
9129       n += x;
9130     else                                /* or decrement as requested. */
9131       n -= x;
9132     addmac(s,ckfstoa(n));               /* Replace old variable */
9133     return(0);
9134 }
9135
9136 /* D O D O  --  Do a macro */
9137
9138 /*
9139   Call with x = macro table index, s = pointer to arguments.
9140   Returns 0 on failure, 1 on success.
9141 */
9142
9143 int
9144 dodo(x,s,flags) int x; char *s; int flags; {
9145     int y;
9146     extern int tra_asg, tra_cmd; int tra_tmp;
9147 #ifndef NOLOCAL
9148 #ifdef OS2
9149     extern int term_io;
9150     int term_io_sav = term_io;
9151 #endif /* OS2 */
9152 #endif /* NOLOCAL */
9153
9154     if (x < 0)                          /* It can happen! */
9155       return(-1);
9156
9157     tra_tmp = tra_asg;
9158
9159     if (++maclvl >= MACLEVEL) {         /* Make sure we have storage */
9160         debug(F101,"dodo maclvl too deep","",maclvl);
9161         --maclvl;
9162         printf("Macros nested too deeply\n");
9163         return(0);
9164     }
9165     macp[maclvl] = mactab[x].mval;      /* Point to the macro body */
9166     macx[maclvl] = mactab[x].mval;      /* Remember where the beginning is */
9167
9168 #ifdef COMMENT
9169     makestr(&(m_line[maclvl]),s);       /* Entire arg string for "\%*" */
9170 #endif /* COMMENT */
9171
9172     cmdlvl++;                           /* Entering a new command level */
9173     if (cmdlvl >= CMDSTKL) {            /* Too many macros + TAKE files? */
9174         debug(F101,"dodo cmdlvl too deep","",cmdlvl);
9175         cmdlvl--;
9176         printf("?TAKE files and DO commands nested too deeply\n");
9177         return(0);
9178     }
9179 #ifdef DEBUG
9180     if (deblog) {
9181         debug(F111,"CMD +M",mactab[x].kwd,cmdlvl);
9182         debug(F010,"CMD ->",s,0);
9183     }
9184 #endif /* DEBUG */
9185
9186 #ifdef VMS
9187     conres();                           /* So Ctrl-C, etc, will work. */
9188 #endif /* VMS */
9189 #ifndef NOLOCAL
9190 #ifdef OS2
9191     term_io = 0;                        /* Disable terminal emulator I/O */
9192 #endif /* OS2 */
9193 #endif /* NOLOCAL */
9194     ifcmd[cmdlvl] = 0;
9195     iftest[cmdlvl] = 0;
9196     count[cmdlvl] = count[cmdlvl-1];    /* Inherit COUNT from previous level */
9197     intime[cmdlvl] = intime[cmdlvl-1];  /* Inherit previous INPUT TIMEOUT */
9198     inpcas[cmdlvl] = inpcas[cmdlvl-1];  /*   and INPUT CASE */
9199     takerr[cmdlvl] = takerr[cmdlvl-1];  /*   and TAKE ERROR */
9200     merror[cmdlvl] = merror[cmdlvl-1];  /*   and MACRO ERROR */
9201     xquiet[cmdlvl] = quiet;
9202     xvarev[cmdlvl] = vareval;
9203     xcmdsrc = CMD_MD;
9204     cmdstk[cmdlvl].src = CMD_MD;        /* Say we're in a macro */
9205     cmdstk[cmdlvl].lvl = maclvl;        /* and remember the macro level */
9206     cmdstk[cmdlvl].ccflgs = flags & ~CF_IMAC; /* Set flags */
9207
9208     /* Initialize return value except in FOR, WHILE, IF, and SWITCH macros */
9209
9210     if (!(flags & CF_IMAC) && mrval[maclvl]) {
9211         free(mrval[maclvl]);
9212         mrval[maclvl] = NULL;
9213     }
9214
9215     /* Clear old %0..%9 arguments */
9216
9217     addmac("%0",mactab[x].kwd);         /* Define %0 = name of macro */
9218     makestr(&(m_xarg[maclvl][0]),mactab[x].kwd);
9219     varnam[0] = '%';
9220     varnam[2] = '\0';
9221     tra_asg = 0;
9222     for (y = 1; y < 10; y++) {          /* Clear args %1..%9 */
9223         if (m_arg[maclvl][y]) {         /* Don't call delmac() unless */
9224             varnam[1] = (char) (y + '0'); /* we have to... */
9225             delmac(varnam,0);
9226         }
9227     }
9228     tra_asg = tra_tmp;
9229
9230 /* Assign the new args one word per arg, allowing braces to group words */
9231
9232     xwords(s,MAXARGLIST,NULL,0);
9233
9234 #ifndef NOLOCAL
9235 #ifdef OS2
9236     term_io = term_io_sav;
9237 #endif /* OS2 */
9238 #endif /* NOLOCAL */
9239     if (tra_cmd)
9240       printf("[%d] +M: \"%s\"\n",cmdlvl,mactab[x].kwd);
9241     return(1);
9242 }
9243
9244 /* Insert "literal" quote around each comma-separated command to prevent */
9245 /* its premature expansion.  Only do this if object command is surrounded */
9246 /* by braces. */
9247
9248 static char* flit = "\\flit(";
9249
9250 int
9251 litcmd(src,dest,n) char **src, **dest; int n; {
9252     int bc = 0, pp = 0;
9253     char c, *s, *lp, *ss;
9254
9255     s = *src;
9256     lp = *dest;
9257
9258     debug(F010,"litcmd",s,0);
9259
9260     while (*s == SP) s++;               /* Strip extra leading spaces */
9261
9262     if (*s == '{') {                    /* Starts with brace */
9263         pp = 0;                         /* Paren counter */
9264         bc = 1;                         /* Count leading brace */
9265         *lp++ = *s++;                   /* Copy it */
9266         if (--n < 1) return(-1);        /* Check space */
9267         while (*s == SP) s++;           /* Strip interior leading spaces */
9268         ss = flit;                      /* Point to "\flit(" */
9269         while ((*lp++ = *ss++))         /* Copy it */
9270           if (--n < 1)                  /* and check space */
9271             return(-1);
9272         lp--;                           /* Back up over null */
9273
9274         while (*s) {                    /* Go thru rest of text */
9275             c = *s;
9276             if (c == '{') bc++;         /* Count brackets */
9277             if (c == '(') pp++;         /* and parens */
9278             if (c == ')') {             /* Right parenthesis. */
9279                 pp--;                   /* Count it. */
9280                 if (pp < 0) {           /* An unbalanced right paren... */
9281 #ifdef COMMENT
9282 /*
9283   The problem here is that "\{" appears to be a quoted brace and therefore
9284   isn't counted; then the "}" matches an earlier opening brace, causing
9285   (e.g.) truncation of macros by getncm().
9286 */
9287                     if (n < 5)          /* Out of space in dest buffer? */
9288                       return(-1);       /* If so, give up. */
9289                     *lp++ = CMDQ;       /* Must be quoted to prevent */
9290                     *lp++ = '}';        /* premature termination of */
9291                     *lp++ = '4';        /* \flit(...) */
9292                     *lp++ = '1';
9293                     *lp++ = '}';
9294                     n -= 5;
9295 #else
9296 /* Here we rely on the fact the \nnn never takes more than 3 digits */
9297                     if (n < 4)          /* Out of space in dest buffer? */
9298                       return(-1);       /* If so, give up. */
9299                     *lp++ = CMDQ;       /* Must be quoted to prevent */
9300                     *lp++ = '0';        /* premature termination of */
9301                     *lp++ = '4';        /* \flit(...) */
9302                     *lp++ = '1';
9303                     n -= 4;
9304 #endif /* COMMENT */
9305                     pp++;               /* Uncount it. */
9306                     s++;
9307                     continue;
9308                 }
9309             }
9310             if (c == '}') {             /* Closing brace. */
9311                 if (--bc == 0) {        /* Final one? */
9312                     *lp++ = ')';        /* Add closing paren for "\flit()" */
9313                     if (--n < 1) return(-1);
9314                     *lp++ = c;
9315                     if (--n < 1) return(-1);
9316                     s++;
9317                     break;
9318                 }
9319             }
9320             *lp++ = c;                  /* General case */
9321             if (--n < 1) return(-1);
9322             s++;
9323         }
9324         *lp = NUL;
9325     } else {                            /* No brackets around, */
9326         while ((*lp++ = *s++))          /* just copy. */
9327           if (--n < 1)
9328             return(-1);
9329         lp--;
9330     }
9331     *src = s;                           /* Return updated source */
9332     *dest = lp;                         /* and destination pointers */
9333     if (bc)                             /* Fail if braces unbalanced */
9334       return(-1);
9335     else                                /* Otherwise succeed. */
9336       return(0);
9337 }
9338 #endif /* NOSPL */
9339
9340 /* Functions moved here from ckuusr.c to even out the module sizes... */
9341
9342 /*
9343   Breaks up string s -- IN PLACE! -- into a list of up to max words.
9344   Pointers to each word go into the array list[].
9345   max is the maximum number of words (pointers).
9346   If list is NULL, then they are added to the macro table.
9347   flag = 0 means the last field is to be one word, like all the other fields,
9348          so anything after it is discarded.
9349   flag = 1 means the last field extends to the end of the string, even if
9350          there are lots of words left, so the last field contains the
9351          remainder of the string.
9352 */
9353 VOID
9354 xwords(s,max,list,flag) char *s; int max; char *list[]; int flag; {
9355     char *p;
9356     int b, i, k, q, y, z;
9357 #ifndef NOSPL
9358     int macro;
9359     macro = (list == NULL);
9360     debug(F010,"xwords",s,0);
9361 #endif /* NOSPL */
9362
9363 #ifdef XWORDSDEBUG
9364     printf("XWORDS string=%s\n",s);
9365     printf("XWORDS max=%d\n",max);
9366 #endif /* XWORDSDEBUG */
9367     p = s;                              /* Pointer to beginning of string */
9368     q = 0;                              /* Flag for doublequote removal */
9369     b = 0;                              /* Flag for outer brace removal */
9370     k = 0;                              /* Flag for in-word */
9371     y = 0;                              /* Brace nesting level */
9372     z = 0;                              /* "Word" counter, 0 thru max */
9373
9374     if (list)
9375       for (i = 0; i <= max; i++)        /* Initialize pointers */
9376         list[i] = NULL;
9377
9378     if (flag) max--;
9379
9380     while (1) {                         /* Go thru word list */
9381         if (!s || (*s == '\0')) {       /* No more characters? */
9382             if (k != 0) {               /* Was I in a word? */
9383                 if (z == max) break;    /* Yes, only go up to max. */
9384                 z++;                    /* Count this word. */
9385 #ifdef XWORDSDEBUG
9386                 printf("1 z++ = %d\n", z);
9387 #endif /* XWORDSDEBUG */
9388 #ifndef NOSPL
9389                 if (macro) {            /* Doing macro args */
9390                     if (z < 10) {
9391                         varnam[1] = (char) (z + '0'); /* Assign last arg */
9392                         addmac(varnam,p);
9393                     }
9394                     if (z <= max) {
9395 #ifdef COMMENT
9396                         if (maclvl < 0)
9397                           addmac(varnam,p);
9398                         else
9399 #endif /* COMMENT */
9400                           makestr(&(m_xarg[maclvl][z]),p);
9401                     }
9402                 } else {                /* Not doing macro args */
9403 #endif /* NOSPL */
9404                     list[z] = p;        /* Assign pointer. */
9405 #ifdef XWORDSDEBUG
9406                     printf("[1]LIST[%d]=\"%s\"\n",z,list[z]);
9407 #endif /* XWORDSDEBUG */
9408 #ifndef NOSPL
9409                 }
9410 #endif /* NOSPL */
9411                 break;                  /* And get out. */
9412             } else break;               /* Was not in a word */
9413         }
9414         if (k == 0 && (*s == SP || *s == HT)) { /* Eat leading blanks */
9415             s++;
9416             continue;
9417         } else if (q == 0 && *s == '{') { /* An opening brace */
9418             if (k == 0 && y == 0) {     /* If leading brace */
9419                 p = s+1;                /* point past it */
9420                 b = 1;                  /* and flag that we did this */
9421             }
9422             k = 1;                      /* Flag that we're in a word */
9423             y++;                        /* Count the brace. */
9424         } else if (q == 0 && *s == '}') { /* A closing brace. */
9425             y--;                        /* Count it. */
9426             if (y <= 0 && b != 0) {     /* If it matches the leading brace */
9427                 char c;
9428                 c = *(s+1);
9429                 if (!c || c == SP || c == HT) { /* at EOL or followed by SP */
9430                     *s = SP;            /* change it to a space */
9431                     b = 0;              /* and we're not in braces any more */
9432                 }
9433             }
9434 #ifdef DOUBLEQUOTING
9435         /* Opening doublequote */
9436         } else if (k == 0 && b == 0 && *s == '"' && dblquo) {
9437             y++;
9438             p = s+1;                    /* point past it */
9439             q = 1;                      /* and flag that we did this */
9440             k = 1;                      /* Flag that we're in a word */
9441         /* Closing double quote */
9442         } else if (q > 0 && k > 0 && b == 0 && *s == '"' && dblquo) {
9443             char c;
9444             c = *(s+1);
9445             if (!c || c == SP || c == HT) { /* at EOL or followed by SP */
9446                 y--;
9447                 *s = SP;                /* change it to a space */
9448                 q = 0;                  /* and we're not in quotes any more */
9449             }
9450 #endif /* DOUBLEQUOTING */
9451
9452         } else if (*s != SP && *s != HT) { /* Nonspace means we're in a word */
9453             if (k == 0) {               /* If we weren't in a word before, */
9454                 p = s;                  /* Mark the beginning */
9455                 if (flag && z == max) { /* Want last word to be remainder? */
9456                     z++;
9457 #ifdef XWORDSDEBUG
9458                     printf("1 z++ = %d\n", z);
9459 #endif /* XWORDSDEBUG */
9460                     list[z] = p;        /* Yes, point to it */
9461 #ifdef XWORDSDEBUG
9462                     printf("[4]LIST[%d]=\"%s\"\n",z,list[z]);
9463 #endif /* XWORDSDEBUG */
9464                     break;              /* and quit */
9465                 }
9466                 k = 1;                  /* Set in-word flag */
9467             }
9468         }
9469         /* If we're not inside a braced quantity, and we are in a word, and */
9470         /* we have hit whitespace, then we have a word. */
9471         if ((y < 1) && (k != 0) && (*s == SP || *s == HT) && !b) {
9472             if (!flag || z < max)       /* if we don't want to keep rest */
9473               *s = '\0';                /* terminate the arg with null */
9474             k = 0;                      /* say we're not in a word any more */
9475             y = 0;                      /* start braces off clean again */
9476             if (z == max) break;        /* Only go up to max. */
9477             z++;                        /* count this arg */
9478 #ifdef XWORDSDEBUG
9479             printf("1 z++ = %d\n", z);
9480 #endif /* XWORDSDEBUG */
9481
9482 #ifndef NOSPL
9483             if (macro) {
9484                 if (z < 10) {
9485                     varnam[1] = (char) (z + '0'); /* compute its name */
9486                     addmac(varnam,p);   /* add it to the macro table */
9487                 }
9488                 if (z <= max) {
9489 #ifdef COMMENT
9490                     if (maclvl < 0)
9491                       addmac(varnam,p);
9492                     else
9493 #endif /* COMMENT */
9494                       makestr(&(m_xarg[maclvl][z]),p);
9495                 }
9496             } else {
9497 #endif /* NOSPL */
9498                 list[z] = p;
9499 #ifdef XWORDSDEBUG
9500                 printf("[2]LIST[%d]=\"%s\"\n",z,list[z]);
9501 #endif /* XWORDSDEBUG */
9502 #ifndef NOSPL
9503             }
9504 #endif /* NOSPL */
9505             p = s+1;
9506         }
9507         s++;                            /* Point past this character */
9508     }
9509     if ((z == 0) && (y > 1)) {          /* Extra closing brace(s) at end */
9510         z++;
9511 #ifndef NOSPL
9512         if (macro) {
9513             if (z < 10) {
9514                 varnam[1] = z + '0';    /* compute its name */
9515                 addmac(varnam,p);       /* Add rest of line to last arg */
9516             }
9517             if (z <= max) {
9518 #ifdef COMMENT
9519                 if (maclvl < 0)
9520                   addmac(varnam,p);
9521                 else
9522 #endif /* COMMENT */
9523                   makestr(&(m_xarg[maclvl][z]),p);
9524             }
9525         } else {
9526 #endif /* NOSPL */
9527             list[z] = p;
9528 #ifdef XWORDSDEBUG
9529             printf("[3]LIST[%d]=\"%s\"\n",z,list[z]);
9530 #endif /* XWORDSDEBUG */
9531 #ifndef NOSPL
9532         }
9533 #endif /* NOSPL */
9534     }
9535 #ifndef NOSPL
9536     if (macro) {                        /* Macro */
9537         if (maclvl < 0) {
9538             a_dim[0] = z;               /* Array dimension is one less */
9539             topargc = z + 1;            /* than \v(argc) */
9540             debug(F111,"a_dim[0]","D",a_dim[0]);
9541         } else {
9542             macargc[maclvl] = z + 1;    /* Set \v(argc) variable */
9543             n_xarg[maclvl] = z + 1;     /* This is the actual number */
9544             a_ptr[0] = m_xarg[maclvl];  /* Point \&_[] at the args */
9545             a_dim[0] = z;               /* And give it this dimension */
9546             debug(F111,"a_dim[0]","E",a_dim[0]);
9547         }
9548     }
9549 #endif /* NOSPL */
9550     return;
9551 }
9552
9553 #ifndef NOSPL
9554
9555 /*  D O S H I F T  --  Do the SHIFT Command; shift macro args left by n */
9556
9557 /*  Note: at some point let's consolidate m_arg[][] and m_xarg[][]. */
9558
9559 int
9560 doshift(n) int n; {                     /* n = shift count */
9561     int i, top, level;
9562     char /* *s, *m, */ buf[6];          /* Buffer to build scalar names */
9563     char * sx = tmpbuf;
9564     int nx = TMPBUFSIZ;
9565
9566     debug(F101,"SHIFT count","",n);
9567     debug(F101,"SHIFT topargc","",topargc);
9568
9569     if (n < 1)                          /* Stay in range */
9570       return(n == 0 ? 1 : 0);
9571
9572     level = maclvl;
9573     top = (level < 0) ? topargc : macargc[level];
9574
9575     if (n >= top)
9576       n = top - 1;
9577
9578 #ifdef DEBUG
9579     if (deblog) {
9580         debug(F101,"SHIFT count 2","",n);
9581         debug(F101,"SHIFT level","",level);
9582         if (level > -1)
9583           debug(F101,"SHIFT macargc[level]","",macargc[level]);
9584     }
9585 #endif /* DEBUG */
9586
9587     buf[0] = '\\';                      /* Initialize name template */
9588     buf[1] = '%';
9589     buf[2] = NUL;
9590     buf[3] = NUL;
9591
9592     for (i = 1; i <= n; i++) {          /* Free shifted-over args */
9593         if (level < 0) {
9594             makestr(&(toparg[i]),NULL);
9595         } else {
9596             makestr(&(m_xarg[level][i]),NULL);
9597         }
9598         if (i < 10) {                   /* Is this necessary? */
9599             buf[2] = (char)(i+'0');
9600             delmac(buf,0);
9601         }
9602     }
9603     for (i = 1; i <= top-n; i++) {      /* Shift remaining args */
9604         if (level < 0) {
9605 #ifdef COMMENT
9606             toparg[i] = toparg[i+n];    /* Full vector */
9607 #else
9608             makestr(&(toparg[i]),toparg[i+n]); /* Full vector */
9609 #endif /* COMMENT */
9610             if (i < 10)                 /* Scalars... */
9611               makestr(&(g_var[i+'0']),toparg[i+n]);
9612         } else {
9613 #ifdef COMMENT
9614             m_xarg[level][i] = m_xarg[level][i+n];
9615 #else
9616             makestr(&(m_xarg[level][i]),m_xarg[level][i+n]);
9617 #endif /* COMMENT */
9618             if (i < 10) {
9619                 buf[2] = (char)(i+'0');
9620                 debug(F010,"SHIFT buf",buf,0);
9621                 addmac(buf,m_xarg[level][i+n]);
9622             }
9623         }
9624     }
9625     for (i = top-n; i <= top; i++) {    /* Clear n args from the end */
9626         if (level < 0) {
9627 #ifdef COMMENT
9628             toparg[i] = NULL;
9629 #else
9630             makestr(&(toparg[i]),NULL);
9631 #endif /* COMMENt */
9632             if (i < 10)
9633               makestr(&(g_var[i+'0']),NULL);
9634         } else {
9635 #ifdef COMMENT
9636             m_xarg[level][i] = NULL;
9637 #else
9638             makestr(&(m_xarg[level][i]),NULL);
9639 #endif /* COMMENt */
9640             if (i < 10) {
9641                 buf[2] = (char)(i+'0');
9642                 delmac(buf,0);
9643             }
9644         }
9645     }
9646     if (level > -1) {                   /* Macro args */
9647         macargc[level] -= n;            /* Adjust count */
9648         n_xarg[maclvl] = macargc[level]; /* Here too */
9649         a_dim[0] = macargc[level] - 1;  /* Adjust array dimension */
9650         debug(F111,"a_dim[0]","F",a_dim[0]);
9651         zzstring("\\fjoin(&_[],{ },1)",&sx,&nx); /* Handle \%* */
9652 #ifdef COMMENT
9653         makestr(&(m_line[level]),tmpbuf);
9654 #endif /* COMMENT */
9655     } else {                            /* Ditto for top level */
9656         topargc -= n;
9657         a_dim[0] = topargc - 1;
9658         debug(F111,"a_dim[0]","G",a_dim[0]);
9659         zzstring("\\fjoin(&_[],{ },1)",&sx,&nx);
9660 #ifdef COMMENT
9661         makestr(&topline,tmpbuf);
9662 #endif /* COMMENT */
9663     }
9664     return(1);
9665 }
9666 #endif /* NOSPL */
9667
9668 int
9669 docd(cx) int cx; {                      /* Do the CD command */
9670     int x;
9671     extern int server, srvcdmsg, cdactive;
9672     extern char * cdmsgfile[], * ckcdpath;
9673     char *s, *p;
9674 #ifdef MAC
9675     char temp[34];
9676 #endif /* MAC */
9677 #ifdef IKSDCONF
9678 extern int iksdcf;
9679 #endif /* IKSDCONF */
9680
9681 #ifndef NOFRILLS
9682     if (cx == XXBACK) {
9683         if ((x = cmcfm()) < 0)
9684         cwdf = 1;
9685         if (prevdir) {
9686             s = zgtdir();
9687             if (!zchdir(prevdir)) {
9688                 cwdf = 0;
9689                 perror(s);
9690             } else {
9691                 makestr(&prevdir,s);
9692             }
9693         }
9694         return(cwdf);
9695     }
9696 #endif /* NOFRILLS */
9697
9698     if (cx == XXCDUP) {
9699 #ifdef VMS
9700         s = "[-]";
9701 #else
9702 #ifdef datageneral
9703         s = "^";
9704 #else
9705         s = "..";
9706 #endif /* datageneral */
9707 #endif /* VMS */
9708         ckstrncpy(line,s,LINBUFSIZ);
9709         goto gocd;
9710     }
9711 #ifndef NOSPL
9712     if (cx == XXKCD) {                  /* Symbolic (Kermit) CD */
9713         char * p;
9714         int n, k;
9715         x = cmkey(kcdtab,nkcdtab,"Symbolic directory name","home",xxstring);
9716         if (x < 0)
9717           return(x);
9718         x = lookup(kcdtab,atmbuf,nkcdtab,&k); /* Get complete keyword */
9719         if (x < 0) {
9720             printf("?Lookup error\n");  /* shouldn't happen */
9721             return(-9);
9722         }
9723         if ((x = cmcfm()) < 0)
9724           return(x);
9725         if (k == VN_HOME) {             /* HOME: allow SET HOME to override */
9726             ckstrncpy(line,homepath(),LINBUFSIZ);
9727         } else {                        /* Other symbolic name */
9728             /* Convert to variable syntax */
9729             ckmakmsg(tmpbuf,TMPBUFSIZ,"\\v(",kcdtab[k].kwd,")",NULL);
9730             p = line;                   /* Expand the variable */
9731             n = LINBUFSIZ;
9732             zzstring(tmpbuf,&p,&n);
9733             if (!line[0]) {             /* Fail if variable not defined */
9734                 printf("?%s - not defined\n",tmpbuf);
9735                 return(success = 0);
9736             }
9737         }
9738         s = line;                       /* All OK, go try to CD... */
9739         goto gocd;
9740     }
9741 #endif /* NOSPL */
9742
9743     cdactive = 1;
9744 #ifdef GEMDOS
9745     if ((x = cmdir("Name of local directory, or carriage return",
9746                    homepath(),
9747                    &s,
9748                    NULL
9749                    )
9750          ) < 0 )
9751       return(x);
9752 #else
9753 #ifdef OS2
9754     if ((x = cmdirp("Name of PC disk and/or directory,\n\
9755        or press the Enter key for the default",
9756                     homepath(),
9757                     &s,
9758                     ckcdpath ? ckcdpath : getenv("CDPATH"),
9759                     xxstring
9760                     )
9761          ) < 0 )
9762       return(x);
9763 #else
9764 #ifdef MAC
9765     x = ckstrncpy(temp,homepath(),32);
9766     if (x > 0) if (temp[x-1] != ':') { temp[x] = ':'; temp[x+1] = NUL; }
9767     if ((x = cmtxt("Name of Macintosh volume and/or folder,\n\
9768  or press the Return key for the desktop on the boot disk",
9769                    temp,&s, xxstring)) < 0 )
9770       return(x);
9771 #else
9772     if ((x = cmdirp("Carriage return for home directory,\n\
9773 or name of directory on this computer",
9774 #ifdef VMS
9775                     "SYS$LOGIN",        /* With no colon */
9776 #else
9777                     homepath(),         /* In VMS this is "SYS$LOGIN:" */
9778 #endif /* VMS */
9779                     &s,
9780                     ckcdpath ? ckcdpath : getenv("CDPATH"),
9781                     xxstring
9782                     )) < 0)
9783       return(x);
9784 #endif /* MAC */
9785 #endif /* OS2 */
9786 #endif /* GEMDOS */
9787     ckstrncpy(line,s,LINBUFSIZ);        /* Make a safe copy */
9788     s = line;
9789 #ifdef VMS
9790     if (ckmatch("*.DIR;1$",s,0,0))
9791       if (cvtdir(s,tmpbuf,TMPBUFSIZ) > 0)
9792         s = tmpbuf;
9793 #endif /* VMS */
9794     debug(F110,"docd",s,0);
9795 #ifndef MAC
9796     if ((x = cmcfm()) < 0)              /* Get confirmation */
9797       return(x);
9798 #endif /* MAC */
9799
9800   gocd:
9801
9802 #ifdef datageneral
9803     x = strlen(line);                   /* homdir ends in colon, */
9804     if (x > 1 && line[x-1] == ':')      /* and "dir" doesn't like that... */
9805       line[x-1] = NUL;
9806 #endif /* datageneral */
9807
9808 #ifdef MAC
9809     cwdf = 1;
9810     if (!zchdir(s)) {
9811         cwdf = 0;
9812         if (*s != ':') {                /* If it failed, */
9813             char *p;                    /* supply leading colon */
9814             int len = (int)strlen(s) + 2;
9815             p = malloc(len);            /* and try again... */
9816             if (p) {
9817                 strcpy(p,":");          /* safe */
9818                 strcat(p,s);            /* safe */
9819                 if (zchdir(p))
9820                   cwdf = 1;
9821                 free(p);
9822                 p = NULL;
9823             }
9824         }
9825     }
9826     if (!cwdf)
9827       perror(s);
9828 #else
9829     p = zgtdir();
9830     if (!zchdir(s)) {
9831         cwdf = 0;
9832 #ifdef CKROOT
9833         if (ckrooterr)
9834           printf("?Off limits: \"%s\"\n",s);
9835         else
9836 #endif /* CKROOT */
9837           perror(s);
9838     } else cwdf = 1;
9839 #endif /* MAC */
9840
9841     x = 0;
9842     if (cwdf) {
9843         makestr(&prevdir,p);
9844         debug(F111,"docd","srvcdmsg",srvcdmsg);
9845         if (srvcdmsg
9846 #ifdef IKSDCONF
9847             && !(inserver && !iksdcf)
9848 #endif /* IKSDCONF */
9849             ) {
9850             int i;
9851             for (i = 0; i < 8; i++) {
9852                 debug(F111,"docd cdmsgfile[i]",cdmsgfile[i],i);
9853                 if (zchki(cdmsgfile[i]) > -1) {
9854                     x = 1;
9855                     dotype(cdmsgfile[i],xaskmore,0,0,NULL,0,NULL,0,0,NULL,0);
9856                     break;
9857                 }
9858             }
9859         }
9860     }
9861 /* xdocd: */
9862     if (!x && srvcdmsg && !server
9863 #ifdef IKSDCONF
9864         && !(inserver && !iksdcf)
9865 #endif /* IKSDCONF */
9866         && !quiet && !xcmdsrc)
9867       printf("%s\n", zgtdir());
9868
9869     return(cwdf);
9870 }
9871
9872 static int on_ctrlc = 0;
9873
9874 VOID
9875 fixcmd() {                      /* Fix command parser after interruption */
9876 #ifndef NOSPL
9877 #ifndef NOONCTRLC
9878     if (nmac) {                         /* Any macros defined? */
9879         int k;                          /* Yes */
9880         char * s = "on_ctrlc";          /* Name of Ctrl-C handling macro */
9881         k = mlook(mactab,s,nmac);       /* Look it up. */
9882         if (k >= 0) {                   /* If found, */
9883             if (on_ctrlc++ == 0) {      /* if not already executing, */
9884                 if (dodo(k,"",0) > -1)  /* set it up, */
9885                   parser(1);            /* execute it, */
9886             }
9887             delmac(s,1);                /* and undefine it. */
9888         }
9889     }
9890     on_ctrlc = 0;
9891 #endif /* NOONCTRLC */
9892 #endif /* NOSPL */
9893     dostop();                   /* Back to top level (also calls conint()). */
9894     bgchk();                    /* Check background status */
9895     if (*psave) {               /* If old prompt saved, */
9896         cmsetp(psave);          /* restore it. */
9897         *psave = NUL;
9898     }
9899     success = 0;                /* Tell parser last command failed */
9900 }
9901
9902 #ifndef NOSHOW                          /* SHOW FEATURES */
9903 /*
9904   Note, presently optlist[] index overflow is not checked.
9905   There is plenty of room (less than 360 entries for 1000 slots).
9906   When space starts to get tight, check for noptlist >= NOPTLIST
9907   every time noptlist is incremented.
9908 */
9909 #define NOPTLIST 1024
9910 static int noptlist = 0;
9911 static char * optlist[NOPTLIST+1];
9912 static int hpos = 0;
9913
9914 int
9915 prtopt(lines,s) int * lines; char *s; { /* Print an option */
9916     int y, i;                           /* Does word wrap. */
9917     if (!s) s = "";
9918     i = *lines;
9919     if (!*s) {                          /* Empty argument */
9920         if (hpos > 0) {                 /* means to end this line. */
9921             printf("\n");               /* Not needed if already at */
9922             if (++i > (cmd_rows - 3)) { /* beginning of new line. */
9923                 if (!askmore())
9924                   return(0);
9925                 else
9926                   i = 0;
9927             }
9928         }
9929         printf("\n");                   /* And then make a blank line */
9930         if (++i > (cmd_rows - 3)) {
9931             if (!askmore())
9932               return(0);
9933             else
9934               i = 0;
9935         }
9936         hpos = 0;
9937         *lines = i;
9938         return(1);
9939     }
9940     y = (int)strlen(s) + 1;
9941     hpos += y;
9942     debug(F101,"prtopt hpos","",hpos);
9943     debug(F101,"prtopt cmd_cols","",cmd_cols);
9944
9945     if (
9946 #ifdef OS2
9947         hpos > ((cmd_cols > 40) ? (cmd_cols - 1) : 79)
9948 #else /* OS2 */
9949         hpos > ((tt_cols > 40) ? (tt_cols - 1) : 79)
9950 #endif /* OS2 */
9951         ) {
9952         printf("\n");
9953         if (++i > (cmd_rows - 3)) {
9954             if (!askmore())
9955               return(0);
9956             else
9957               i = 0;
9958         }
9959         printf(" %s",s);
9960         hpos = y;
9961     } else
9962       printf(" %s",s);
9963     *lines = i;
9964     return(1);
9965 }
9966
9967 static VOID
9968 initoptlist() {
9969     int i;
9970     if (noptlist > 0)
9971       return;
9972     for (i = 0; i < NOPTLIST; i++)
9973       optlist[i] = NULL;
9974
9975 #ifdef MAC
9976 #ifdef MPW
9977     makestr(&(optlist[noptlist++]),"MPW");
9978 #endif /* MPW */
9979 #endif /* MAC */
9980
9981 #ifdef MAC
9982 #ifdef THINK_C
9983     makestr(&(optlist[noptlist++]),"THINK_C");
9984 #endif /* THINK_C */
9985 #endif /* MAC */
9986
9987 #ifdef __386__
9988     makestr(&(optlist[noptlist++]),"__386__");
9989 #endif /* __386__ */
9990
9991 /* Memory models... */
9992
9993 #ifdef __FLAT__
9994     makestr(&(optlist[noptlist++]),"__FLAT__");
9995 #endif /* __FLAT__ */
9996 #ifdef __SMALL__
9997     makestr(&(optlist[noptlist++]),"__SMALL__");
9998 #endif /* __SMALL__ */
9999 #ifdef __MEDIUM__
10000     makestr(&(optlist[noptlist++]),"__MEDIUM__");
10001 #endif /* __MEDIUM__ */
10002 #ifdef __COMPACT__
10003     makestr(&(optlist[noptlist++]),"__COMPACT__");
10004 #endif /* __COMPACT__ */
10005 #ifdef __LARGE__
10006     makestr(&(optlist[noptlist++]),"__LARGE__");
10007 #endif /* __LARGE__ */
10008
10009 #ifdef DEBUG
10010 #ifdef IFDEBUG
10011     makestr(&(optlist[noptlist++]),"IFDEBUG");
10012 #else
10013     makestr(&(optlist[noptlist++]),"DEBUG");
10014 #endif /* IFDEBUG */
10015 #endif /* DEBUG */
10016 #ifdef TLOG
10017     makestr(&(optlist[noptlist++]),"TLOG");
10018 #endif /* TLOG */
10019 #ifdef BIGBUFOK
10020     makestr(&(optlist[noptlist++]),"BIGBUFOK");
10021 #endif /* BIGBUFOK */
10022 #ifdef INPBUFSIZ
10023     sprintf(line,"INPBUFSIZ=%d",INPBUFSIZ); /* SAFE */
10024     makestr(&(optlist[noptlist++]),line);
10025 #endif /* INPBUFSIZE */
10026 #ifdef LINBUFSIZ
10027     sprintf(line,"LINBUFSIZ=%d",LINBUFSIZ); /* SAFE */
10028     makestr(&(optlist[noptlist++]),line);
10029 #endif /* LINBUFSIZE */
10030 #ifdef INBUFSIZE
10031     sprintf(line,"INBUFSIZE=%d",INBUFSIZE); /* SAFE */
10032     makestr(&(optlist[noptlist++]),line);
10033 #endif /* INBUFSIZE */
10034 #ifdef OBUFSIZE
10035     sprintf(line,"OBUFSIZE=%d",OBUFSIZE); /* SAFE */
10036     makestr(&(optlist[noptlist++]),line);
10037 #endif /* OBUFSIZE */
10038 #ifdef FD_SETSIZE
10039     sprintf(line,"FD_SETSIZE=%d",FD_SETSIZE); /* SAFE */
10040     makestr(&(optlist[noptlist++]),line);
10041 #endif /* FD_SETSIZE */
10042 #ifdef XFRCAN
10043     makestr(&(optlist[noptlist++]),"XFRCAN");
10044 #endif /* XFRCAN */
10045 #ifdef XPRINT
10046     makestr(&(optlist[noptlist++]),"XPRINT");
10047 #endif /* XPRINT */
10048 #ifdef PIPESEND
10049     makestr(&(optlist[noptlist++]),"PIPESEND");
10050 #endif /* PIPESEND */
10051 #ifdef CK_SPEED
10052     makestr(&(optlist[noptlist++]),"CK_SPEED");
10053 #endif /* CK_SPEED */
10054 #ifdef CK_FAST
10055     makestr(&(optlist[noptlist++]),"CK_FAST");
10056 #endif /* CK_FAST */
10057 #ifdef CK_APC
10058     makestr(&(optlist[noptlist++]),"CK_APC");
10059 #endif /* CK_APC */
10060 #ifdef CK_AUTODL
10061     makestr(&(optlist[noptlist++]),"CK_AUTODL");
10062 #endif /* CK_AUTODL */
10063 #ifdef CK_MKDIR
10064     makestr(&(optlist[noptlist++]),"CK_MKDIR");
10065 #endif /* CK_MKDIR */
10066 #ifdef NOMKDIR
10067     makestr(&(optlist[noptlist++]),"NOMKDIR");
10068 #endif /* NOMKDIR */
10069 #ifdef CK_LABELED
10070     makestr(&(optlist[noptlist++]),"CK_LABELED");
10071 #endif /* CK_LABELED */
10072 #ifdef NODIAL
10073     makestr(&(optlist[noptlist++]),"NODIAL");
10074 #endif /* NODIAL */
10075 #ifdef MINIDIAL
10076     makestr(&(optlist[noptlist++]),"MINIDIAL");
10077 #endif /* MINIDIAL */
10078 #ifdef WHATAMI
10079     makestr(&(optlist[noptlist++]),"WHATAMI");
10080 #endif /* WHATAMI */
10081 #ifdef DYNAMIC
10082     makestr(&(optlist[noptlist++]),"DYNAMIC");
10083 #endif /* DYNAMIC */
10084 #ifndef NOSPL
10085     sprintf(line,"CMDDEP=%d",CMDDEP);   /* SAFE */
10086     makestr(&(optlist[noptlist++]),line);
10087 #endif /* NOSPL */
10088
10089 #ifdef MAXPATHLEN
10090     sprintf(line,"MAXPATHLEN=%d",MAXPATHLEN); /* SAFE */
10091     makestr(&(optlist[noptlist++]),line);
10092 #endif /* MAXPATHLEN */
10093
10094 #ifdef DEVNAMLEN
10095     sprintf(line,"DEVNAMLEN=%d",DEVNAMLEN); /* SAFE */
10096     makestr(&(optlist[noptlist++]),line);
10097 #endif /* DEVNAMLEN */
10098
10099 #ifdef NO_PARAM_H
10100     makestr(&(optlist[noptlist++]),"NO_PARAM_H");
10101 #endif /* NO_PARAM_H */
10102
10103 #ifdef INCL_PARAM_H
10104     makestr(&(optlist[noptlist++]),"INCL_PARAM_H");
10105 #endif /* INCL_PARAM_H */
10106
10107     sprintf(line,"CKMAXPATH=%d",CKMAXPATH); /* SAFE */
10108     makestr(&(optlist[noptlist++]),line);
10109
10110     sprintf(line,"CKMAXOPEN=%d",CKMAXOPEN); /* SAFE */
10111     makestr(&(optlist[noptlist++]),line);
10112
10113     sprintf(line,"Z_MAXCHAN=%d",Z_MAXCHAN); /* SAFE */
10114     makestr(&(optlist[noptlist++]),line);
10115
10116 #ifdef OPEN_MAX
10117     sprintf(line,"OPEN_MAX=%d",OPEN_MAX); /* SAFE */
10118     makestr(&(optlist[noptlist++]),line);
10119 #endif /* OPEN_MAX */
10120
10121 #ifdef _POSIX_OPEN_MAX
10122     sprintf(line,"_POSIX_OPEN_MAX=%d",_POSIX_OPEN_MAX); /* SAFE */
10123     makestr(&(optlist[noptlist++]),line);
10124 #endif /* _POSIX_OPEN_MAX */
10125
10126 #ifdef CKCHANNELIO
10127     {
10128         extern int z_maxchan;
10129 #ifdef UNIX
10130         extern int ckmaxfiles;
10131         sprintf(line,"ckmaxfiles=%d",ckmaxfiles); /* SAFE */
10132         makestr(&(optlist[noptlist++]),line);
10133 #endif /* UNIX */
10134         sprintf(line,"z_maxchan=%d",z_maxchan); /* SAFE */
10135         makestr(&(optlist[noptlist++]),line);
10136     }
10137 #endif /* CKCHANNELIO */
10138
10139 #ifdef FOPEN_MAX
10140     sprintf(line,"FOPEN_MAX=%d",FOPEN_MAX); /* SAFE */
10141     makestr(&(optlist[noptlist++]),line);
10142 #endif /* FOPEN_MAX */
10143
10144 #ifdef MAXGETPATH
10145     sprintf(line,"MAXGETPATH=%d",MAXGETPATH); /* SAFE */
10146     makestr(&(optlist[noptlist++]),line);
10147 #endif /* MAXGETPATH */
10148
10149 #ifdef CMDBL
10150     sprintf(line,"CMDBL=%d",CMDBL);     /* SAFE */
10151     makestr(&(optlist[noptlist++]),line);
10152 #endif /* CMDBL */
10153
10154 #ifdef VNAML
10155     sprintf(line,"VNAML=%d",VNAML);     /* SAFE */
10156     makestr(&(optlist[noptlist++]),line);
10157 #endif /* VNAML */
10158
10159 #ifdef ARRAYREFLEN
10160     sprintf(line,"ARRAYREFLEN=%d",ARRAYREFLEN); /* SAFE */
10161     makestr(&(optlist[noptlist++]),line);
10162 #endif /* ARRAYREFLEN */
10163
10164 #ifdef UIDBUFLEN
10165     sprintf(line,"UIDBUFLEN=%d",UIDBUFLEN); /* SAFE */
10166     makestr(&(optlist[noptlist++]),line);
10167 #endif /* UIDBUFLEN */
10168
10169 #ifdef FORDEPTH
10170     sprintf(line,"FORDEPTH=%d",FORDEPTH); /* SAFE */
10171     makestr(&(optlist[noptlist++]),line);
10172 #endif /* FORDEPTH */
10173
10174 #ifdef MAXTAKE
10175     sprintf(line,"MAXTAKE=%d",MAXTAKE); /* SAFE */
10176     makestr(&(optlist[noptlist++]),line);
10177 #endif /* MAXTAKE */
10178
10179 #ifdef MACLEVEL
10180     sprintf(line,"MACLEVEL=%d",MACLEVEL); /* SAFE */
10181     makestr(&(optlist[noptlist++]),line);
10182 #endif /* MACLEVEL */
10183
10184 #ifdef MAC_MAX
10185     sprintf(line,"MAC_MAX=%d",MAC_MAX); /* SAFE */
10186     makestr(&(optlist[noptlist++]),line);
10187 #endif /* MAC_MAX */
10188
10189 #ifdef _LARGEFILE_SOURCE
10190     makestr(&(optlist[noptlist++]),"_LARGEFILE_SOURCE");
10191 #endif  /* _LARGEFILE_SOURCE */
10192
10193 #ifdef _FILE_OFFSET_BITS
10194     sprintf(line,"_FILE_OFFSET_BITS=%d",_FILE_OFFSET_BITS); /* SAFE */
10195     makestr(&(optlist[noptlist++]),line);
10196 #endif  /* _FILE_OFFSET_BITS */
10197
10198 #ifdef __USE_FILE_OFFSET64
10199     makestr(&(optlist[noptlist++]),"__USE_FILE_OFFSET64");
10200 #endif  /* __USE_FILE_OFFSET64 */
10201
10202 #ifdef __USE_LARGEFILE64
10203     makestr(&(optlist[noptlist++]),"__USE_LARGEFILE64");
10204 #endif  /* __USE_LARGEFILE64 */
10205
10206 #ifdef COMMENT
10207 #ifdef CHAR_MAX
10208     sprintf(line,"CHAR_MAX=%llx",CHAR_MAX); /* SAFE */
10209     makestr(&(optlist[noptlist++]),line);
10210 #endif /* CHAR_MAX */
10211 #ifdef UCHAR_MAX
10212     sprintf(line,"UCHAR_MAX=%llx",UCHAR_MAX); /* SAFE */
10213     makestr(&(optlist[noptlist++]),line);
10214 #endif /* UCHAR_MAX */
10215 #ifdef SHRT_MAX
10216     sprintf(line,"SHRT_MAX=%llx",SHRT_MAX); /* SAFE */
10217     makestr(&(optlist[noptlist++]),line);
10218 #endif /* SHRT_MAX */
10219 #ifdef USHRT_MAX
10220     sprintf(line,"USHRT_MAX=%llx",USHRT_MAX); /* SAFE */
10221     makestr(&(optlist[noptlist++]),line);
10222 #endif /* USHRT_MAX */
10223 #ifdef INT_MAX
10224     sprintf(line,"INT_MAX=%llx",INT_MAX); /* SAFE */
10225     makestr(&(optlist[noptlist++]),line);
10226 #endif /* INT_MAX */
10227 #ifdef UINT_MAX
10228     sprintf(line,"UINT_MAX=%llx",UINT_MAX); /* SAFE */
10229     makestr(&(optlist[noptlist++]),line);
10230 #endif /* UINT_MAX */
10231 #ifdef MAX_LONG
10232     sprintf(line,"MAX_LONG=%llx",MAX_LONG); /* SAFE */
10233     makestr(&(optlist[noptlist++]),line);
10234 #endif /* MAX_LONG */
10235 #ifdef LONG_MAX
10236     sprintf(line,"LONG_MAX=%llx",LONG_MAX); /* SAFE */
10237     makestr(&(optlist[noptlist++]),line);
10238 #endif /* LONG_MAX */
10239 #ifdef ULONG_MAX
10240     sprintf(line,"ULONG_MAX=%llx",ULONG_MAX); /* SAFE */
10241     makestr(&(optlist[noptlist++]),line);
10242 #endif /* ULONG_MAX */
10243 #ifdef MAXINT
10244     sprintf(line,"MAXINT=%llx",MAXINT); /* SAFE */
10245     makestr(&(optlist[noptlist++]),line);
10246 #endif /* MAXINT */
10247 #ifdef MAXLONG
10248     sprintf(line,"MAXLONG=%llx",MAXLONG); /* SAFE */
10249     makestr(&(optlist[noptlist++]),line);
10250 #endif /* MAXLONG */
10251 #ifdef NT
10252 #ifdef LLONG_MAX
10253     sprintf(line,"LLONG_MAX=%I64x",LLONG_MAX); /* SAFE */
10254     makestr(&(optlist[noptlist++]),line);
10255 #endif /* LLONG_MAX */
10256 #ifdef ULLONG_MAX
10257     sprintf(line,"ULLONG_MAX=%I64x",ULLONG_MAX); /* SAFE */
10258     makestr(&(optlist[noptlist++]),line);
10259 #endif /* ULLONG_MAX */
10260 #ifdef MAXLONGLONG
10261     sprintf(line,"MAXLONGLONG=%I64x",MAXLONGLONG);  /* SAFE */
10262     makestr(&(optlist[noptlist++]),line);
10263 #endif /* MAXLONGLONG */
10264 #else
10265 #ifdef LLONG_MAX
10266     sprintf(line,"LLONG_MAX=%llx",LLONG_MAX); /* SAFE */
10267     makestr(&(optlist[noptlist++]),line);
10268 #endif /* LLONG_MAX */
10269 #ifdef ULLONG_MAX
10270     sprintf(line,"ULLONG_MAX=%llx",ULLONG_MAX); /* SAFE */
10271     makestr(&(optlist[noptlist++]),line);
10272 #endif /* ULLONG_MAX */
10273 #ifdef MAXLONGLONG
10274     sprintf(line,"MAXLONGLONG=%llx",MAXLONGLONG);  /* SAFE */
10275     makestr(&(optlist[noptlist++]),line);
10276 #endif /* MAXLONGLONG */
10277 #endif
10278 #ifdef _INTEGRAL_MAX_BITS
10279     sprintf(line,"_INTEGRAL_MAX_BITS=%d",_INTEGRAL_MAX_BITS);  /* SAFE */
10280     makestr(&(optlist[noptlist++]),line);
10281 #endif /* _INTEGRAL_MAX_BITS */
10282 #endif  /* COMMENT */
10283
10284 #ifdef MINPUTMAX
10285     sprintf(line,"MINPUTMAX=%d",MINPUTMAX); /* SAFE */
10286     makestr(&(optlist[noptlist++]),line);
10287 #endif /* MINPUTMAX */
10288
10289 #ifdef MAXWLD
10290     sprintf(line,"MAXWLD=%d",MAXWLD); /* SAFE */
10291     makestr(&(optlist[noptlist++]),line);
10292 #else
10293 #ifdef OS2
10294     makestr(&(optlist[noptlist++]),"MAXWLD=unlimited");
10295 #endif /* OS2 */
10296 #endif /* MAXWLD */
10297
10298 #ifdef MSENDMAX
10299     sprintf(line,"MSENDMAX=%d",MSENDMAX); /* SAFE */
10300     makestr(&(optlist[noptlist++]),line);
10301 #endif /* MSENDMAX */
10302
10303 #ifdef MAXDDIR
10304     sprintf(line,"MAXDDIR=%d",MAXDDIR); /* SAFE */
10305     makestr(&(optlist[noptlist++]),line);
10306 #endif /* MAXDDIR */
10307
10308 #ifdef MAXDNUMS
10309     sprintf(line,"MAXDNUMS=%d",MAXDNUMS); /* SAFE */
10310     makestr(&(optlist[noptlist++]),line);
10311 #endif /* MAXDNUMS */
10312
10313 #ifdef UNIX
10314     makestr(&(optlist[noptlist++]),"UNIX");
10315 #endif /* UNIX */
10316
10317 #ifdef VMS
10318     makestr(&(optlist[noptlist++]),"VMS");
10319 #ifdef __VMS_VER
10320     sprintf(line,"__VMS_VER=%d",__VMS_VER); /* SAFE */
10321     makestr(&(optlist[noptlist++]),line);
10322 #endif /* __VMS_VER */
10323 #ifdef VMSV70
10324     makestr(&(optlist[noptlist++]),"VMSV70");
10325 #endif /* VMSV70 */
10326 #ifdef OLD_VMS
10327     makestr(&(optlist[noptlist++]),"OLD_VMS");
10328 #endif /* OLD_VMS */
10329 #ifdef vms
10330     makestr(&(optlist[noptlist++]),"vms");
10331 #endif /* vms */
10332 #ifdef VMSV60
10333     makestr(&(optlist[noptlist++]),"VMSV60");
10334 #endif /* VMSV60 */
10335 #ifdef VMSV80
10336     makestr(&(optlist[noptlist++]),"VMSV80");
10337 #endif /* VMSV80 */
10338 #ifdef VMSSHARE
10339     makestr(&(optlist[noptlist++]),"VMSSHARE");
10340 #endif /* VMSSHARE */
10341 #ifdef NOVMSSHARE
10342     makestr(&(optlist[noptlist++]),"NOVMSSHARE");
10343 #endif /* NOVMSSHARE */
10344 #endif /* VMS */
10345
10346 #ifdef datageneral
10347     makestr(&(optlist[noptlist++]),"datageneral");
10348 #endif /* datageneral */
10349 #ifdef apollo
10350     makestr(&(optlist[noptlist++]),"apollo");
10351 #endif /* apollo */
10352 #ifdef aegis
10353     makestr(&(optlist[noptlist++]),"aegis");
10354 #endif /* aegis */
10355 #ifdef A986
10356     makestr(&(optlist[noptlist++]),"A986");
10357 #endif /* A986 */
10358 #ifdef AMIGA
10359     makestr(&(optlist[noptlist++]),"AMIGA");
10360 #endif /* AMIGA */
10361 #ifdef CONVEX9
10362     makestr(&(optlist[noptlist++]),"CONVEX9");
10363 #endif /* CONVEX9 */
10364 #ifdef CONVEX10
10365     makestr(&(optlist[noptlist++]),"CONVEX10");
10366 #endif /* CONVEX9 */
10367 #ifdef MAC
10368     makestr(&(optlist[noptlist++]),"MAC");
10369 #endif /* MAC */
10370 #ifdef AUX
10371     makestr(&(optlist[noptlist++]),"AUX");
10372 #endif /* AUX */
10373
10374 #ifdef OS2
10375     makestr(&(optlist[noptlist++]),"OS2");
10376 #ifdef NT
10377     makestr(&(optlist[noptlist++]),"NT");
10378 #endif /* NT */
10379 #endif /* OS2 */
10380
10381 #ifdef OSK
10382     makestr(&(optlist[noptlist++]),"OS9");
10383 #endif /* OSK */
10384
10385 #ifdef MSDOS
10386     makestr(&(optlist[noptlist++]),"MSDOS");
10387 #endif /* MSDOS */
10388
10389 #ifdef DIRENT
10390     makestr(&(optlist[noptlist++]),"DIRENT");
10391 #endif /* DIRENT */
10392
10393 #ifdef SDIRENT
10394     makestr(&(optlist[noptlist++]),"SDIRENT");
10395 #endif /* SDIRENT */
10396
10397 #ifdef NDIR
10398     makestr(&(optlist[noptlist++]),"NDIR");
10399 #endif /* NDIR */
10400
10401 #ifdef XNDIR
10402     makestr(&(optlist[noptlist++]),"XNDIR");
10403 #endif /* XNDIR */
10404
10405 #ifdef SAVEDUID
10406     makestr(&(optlist[noptlist++]),"SAVEDUID");
10407 #endif /* SAVEDUID */
10408
10409 #ifdef RENAME
10410     makestr(&(optlist[noptlist++]),"RENAME");
10411 #endif /* RENAME */
10412
10413 #ifdef CK_TMPDIR
10414     makestr(&(optlist[noptlist++]),"CK_TMPDIR");
10415 #endif /* CK_TMPDIR */
10416
10417 #ifdef NOCCTRAP
10418     makestr(&(optlist[noptlist++]),"NOCCTRAP");
10419 #endif /* NOCCTRAP */
10420
10421 #ifdef NOCOTFMC
10422     makestr(&(optlist[noptlist++]),"NOCOTFMC");
10423 #endif /* NOCOTFMC */
10424
10425 #ifdef NOFRILLS
10426     makestr(&(optlist[noptlist++]),"NOFRILLS");
10427 #endif /* NOFRILLS */
10428
10429 #ifdef PARSENSE
10430     makestr(&(optlist[noptlist++]),"PARSENSE");
10431 #endif /* PARSENSE */
10432
10433 #ifdef TIMEH
10434     makestr(&(optlist[noptlist++]),"TIMEH");
10435 #endif /* TIMEH */
10436
10437 #ifdef NOTIMEH
10438     makestr(&(optlist[noptlist++]),"TIMEH");
10439 #endif /* NOTIMEH */
10440
10441 #ifdef SYSTIMEH
10442     makestr(&(optlist[noptlist++]),"SYSTIMEH");
10443 #endif /* SYSTIMEH */
10444
10445 #ifdef NOSYSTIMEH
10446     makestr(&(optlist[noptlist++]),"SYSTIMEH");
10447 #endif /* NOSYSTIMEH */
10448
10449 #ifdef SYSTIMEBH
10450     makestr(&(optlist[noptlist++]),"SYSTIMEBH");
10451 #endif /* SYSTIMEBH */
10452
10453 #ifdef NOSYSTIMEBH
10454     makestr(&(optlist[noptlist++]),"SYSTIMEBH");
10455 #endif /* NOSYSTIMEBH */
10456
10457 #ifdef UTIMEH
10458     makestr(&(optlist[noptlist++]),"UTIMEH");
10459 #endif /* UTIMEH */
10460
10461 #ifdef SYSUTIMEH
10462     makestr(&(optlist[noptlist++]),"SYSUTIMEH");
10463 #endif /* SYSUTIMEH */
10464
10465 #ifdef CK_NEED_SIG
10466     makestr(&(optlist[noptlist++]),"CK_NEED_SIG");
10467 #endif /* CK_NEED_SIG */
10468
10469 #ifdef CK_TTYFD
10470     makestr(&(optlist[noptlist++]),"CK_TTYFD");
10471 #endif /* CK_TTYFD */
10472
10473 #ifdef NETCONN
10474     makestr(&(optlist[noptlist++]),"NETCONN");
10475 #endif /* NETCONN */
10476
10477 #ifdef TCPSOCKET
10478     makestr(&(optlist[noptlist++]),"TCPSOCKET");
10479 #ifdef NOTCPOPTS
10480     makestr(&(optlist[noptlist++]),"NOTCPOPTS");
10481 #endif /* NOTCPOPTS */
10482 #ifdef CK_DNS_SRV
10483     makestr(&(optlist[noptlist++]),"CK_DNS_SRV");
10484 #endif /* CK_DNS_SRV */
10485 #ifdef NO_DNS_SRV
10486     makestr(&(optlist[noptlist++]),"NO_DNS_SRV");
10487 #endif /* NO_DNS_SRV */
10488 #ifdef CKGHNLHOST
10489     makestr(&(optlist[noptlist++]),"CKGHNLHOST");
10490 #endif /* CKGHNLHOST */
10491 #ifdef NOLISTEN
10492     makestr(&(optlist[noptlist++]),"NOLISTEN");
10493 #endif /* NOLISTEN */
10494 #ifdef SOL_SOCKET
10495     makestr(&(optlist[noptlist++]),"SOL_SOCKET");
10496 #endif /* SOL_SOCKET */
10497 #ifdef SO_OOBINLINE
10498     makestr(&(optlist[noptlist++]),"SO_OOBINLINE");
10499 #endif /* SO_OOBINLNE */
10500 #ifdef SO_DONTROUTE
10501     makestr(&(optlist[noptlist++]),"SO_DONTROUTE");
10502 #endif /* SO_DONTROUTE */
10503 #ifdef SO_KEEPALIVE
10504     makestr(&(optlist[noptlist++]),"SO_KEEPALIVE");
10505 #endif /* SO_KEEPALIVE */
10506 #ifdef SO_LINGER
10507     makestr(&(optlist[noptlist++]),"SO_LINGER");
10508 #endif /* SO_LINGER */
10509 #ifdef TCP_NODELAY
10510     makestr(&(optlist[noptlist++]),"TCP_NODELAY");
10511 #endif /* TCP_NODELAY */
10512 #ifdef SO_SNDBUF
10513     makestr(&(optlist[noptlist++]),"SO_SNDBUF");
10514 #endif /* SO_SNDBUF */
10515 #ifdef SO_RCVBUF
10516     makestr(&(optlist[noptlist++]),"SO_RCVBUF");
10517 #endif /* SO_RCVBUF */
10518 #ifdef h_addr
10519     makestr(&(optlist[noptlist++]),"h_addr");
10520 #endif /* h_addr */
10521 #ifdef HADDRLIST
10522     makestr(&(optlist[noptlist++]),"HADDRLIST");
10523 #endif /* HADDRLIST */
10524 #ifdef CK_SOCKS
10525     makestr(&(optlist[noptlist++]),"CK_SOCKS");
10526 #ifdef CK_SOCKS5
10527     makestr(&(optlist[noptlist++]),"CK_SOCKS5");
10528 #endif /* CK_SOCKS5 */
10529 #ifdef CK_SOCKS_NS
10530     makestr(&(optlist[noptlist++]),"CK_SOCKS_NS");
10531 #endif /* CK_SOCKS_NS */
10532 #endif /* CK_SOCKS */
10533 #ifdef RLOGCODE
10534     makestr(&(optlist[noptlist++]),"RLOGCODE");
10535 #endif /* RLOGCODE */
10536 #ifdef NETCMD
10537     makestr(&(optlist[noptlist++]),"NETCMD");
10538 #endif /* NETCMD */
10539 #ifdef NONETCMD
10540     makestr(&(optlist[noptlist++]),"NONETCMD");
10541 #endif /* NONETCMD */
10542 #ifdef NETPTY
10543     makestr(&(optlist[noptlist++]),"NETPTY");
10544 #endif /* NETPTY */
10545 #ifdef CK_ENVIRONMENT
10546     makestr(&(optlist[noptlist++]),"CK_ENVIRONMENT");
10547 #endif /* CK_ENVIRONMENT */
10548 #endif /* TCPSOCKET */
10549 #ifdef TNCODE
10550     makestr(&(optlist[noptlist++]),"TNCODE");
10551 #endif /* TNCODE */
10552 #ifdef CK_FORWARD_X
10553     makestr(&(optlist[noptlist++]),"CK_FORWARD_X");
10554 #endif /* CK_FORWARD_X */
10555 #ifdef TN_COMPORT
10556     makestr(&(optlist[noptlist++]),"TN_COMPORT");
10557 #endif /* TN_COMPORT */
10558 #ifdef MULTINET
10559     makestr(&(optlist[noptlist++]),"MULTINET");
10560 #endif /* MULTINET */
10561 #ifdef DEC_TCPIP
10562     makestr(&(optlist[noptlist++]),"DEC_TCPIP");
10563 #endif /* DEC_TCPIP */
10564 #ifdef TCPWARE
10565     makestr(&(optlist[noptlist++]),"TCPWARE");
10566 #endif /* TCPWARE */
10567 #ifdef UCX50
10568     makestr(&(optlist[noptlist++]),"UCX50");
10569 #endif /* UCX50 */
10570 #ifdef CMU_TCPIP
10571     makestr(&(optlist[noptlist++]),"CMU_TCPIP");
10572 #endif /* CMU_TCPIP */
10573 #ifdef TTLEBUF
10574     makestr(&(optlist[noptlist++]),"TTLEBUF");
10575 #endif /* TTLEBUF */
10576 #ifdef NETLEBUF
10577     makestr(&(optlist[noptlist++]),"NETLEBUF");
10578 #endif /* NETLEBUF */
10579 #ifdef IKS_OPTION
10580     makestr(&(optlist[noptlist++]),"IKS_OPTION");
10581 #endif /* IKS_OPTION */
10582 #ifdef IKSDB
10583     makestr(&(optlist[noptlist++]),"IKSDB");
10584 #endif /* IKSDB */
10585 #ifdef IKSDCONF
10586     makestr(&(optlist[noptlist++]),"IKSDCONF");
10587 #endif /* IKSDCONF */
10588 #ifdef CK_LOGIN
10589     makestr(&(optlist[noptlist++]),"CK_LOGIN");
10590 #endif /* CK_LOGIN */
10591 #ifdef CK_PAM
10592     makestr(&(optlist[noptlist++]),"CK_PAM");
10593 #endif /* CK_PAM */
10594 #ifdef CK_SHADOW
10595     makestr(&(optlist[noptlist++]),"CK_SHADOW");
10596 #endif /* CK_SHADOW */
10597 #ifdef CONGSPD
10598     makestr(&(optlist[noptlist++]),"CONGSPD");
10599 #endif /* CONGSPD */
10600 #ifdef SUNX25
10601     makestr(&(optlist[noptlist++]),"SUNX25");
10602 #endif /* SUNX25 */
10603 #ifdef IBMX25
10604     makestr(&(optlist[noptlist++]),"IBMX25");
10605 #endif /* IBMX25 */
10606 #ifdef HPX25
10607     makestr(&(optlist[noptlist++]),"HPX25");
10608 #endif /* HPX25 */
10609 #ifdef DECNET
10610     makestr(&(optlist[noptlist++]),"DECNET");
10611 #endif /* DECNET */
10612 #ifdef SUPERLAT
10613     makestr(&(optlist[noptlist++]),"SUPERLAT");
10614 #endif /* SUPERLAT */
10615 #ifdef NPIPE
10616     makestr(&(optlist[noptlist++]),"NPIPE");
10617 #endif /* NPIPE */
10618 #ifdef CK_NETBIOS
10619     makestr(&(optlist[noptlist++]),"CK_NETBIOS");
10620 #endif /* CK_NETBIOS */
10621 #ifdef ATT7300
10622     makestr(&(optlist[noptlist++]),"ATT7300");
10623 #endif /* ATT7300 */
10624 #ifdef ATT6300
10625     makestr(&(optlist[noptlist++]),"ATT6300");
10626 #endif /* ATT6300 */
10627 #ifdef HDBUUCP
10628     makestr(&(optlist[noptlist++]),"HDBUUCP");
10629 #endif /* HDBUUCP */
10630 #ifdef USETTYLOCK
10631     makestr(&(optlist[noptlist++]),"USETTYLOCK");
10632 #endif /* USETTYLOCK */
10633 #ifdef USE_UU_LOCK
10634     makestr(&(optlist[noptlist++]),"USE_UU_LOCK");
10635 #endif /* USE_UU_LOCK */
10636 #ifdef HAVE_LOCKDEV
10637     makestr(&(optlist[noptlist++]),"HAVE_LOCKDEV");
10638 #endif /* HAVE_LOCKDEV */
10639 #ifdef HAVE_BAUDBOY
10640     makestr(&(optlist[noptlist++]),"HAVE_BAUDBOY");
10641 #endif /* HAVE_BAUDBOY */
10642 #ifdef HAVE_OPENPTY
10643     makestr(&(optlist[noptlist++]),"HAVE_OPENPTY");
10644 #endif /* HAVE_OPENPTY */
10645 #ifdef TTPTYCMD
10646     makestr(&(optlist[noptlist++]),"TTPTYCMD");
10647 #endif /* TTPTYCMD */
10648 #ifdef NOUUCP
10649     makestr(&(optlist[noptlist++]),"NOUUCP");
10650 #endif /* NOUUCP */
10651 #ifdef LONGFN
10652     makestr(&(optlist[noptlist++]),"LONGFN");
10653 #endif /* LONGFN */
10654 #ifdef RDCHK
10655     makestr(&(optlist[noptlist++]),"RDCHK");
10656 #endif /* RDCHK */
10657 #ifdef SELECT
10658     makestr(&(optlist[noptlist++]),"SELECT");
10659 #endif /* SELECT */
10660 #ifdef USLEEP
10661     makestr(&(optlist[noptlist++]),"USLEEP");
10662 #endif /* USLEEP */
10663 #ifdef NAP
10664     makestr(&(optlist[noptlist++]),"NAP");
10665 #endif /* NAP */
10666 #ifdef NAPHACK
10667     makestr(&(optlist[noptlist++]),"NAPHACK");
10668 #endif /* NAPHACK */
10669 #ifdef CK_POLL
10670     makestr(&(optlist[noptlist++]),"CK_POLL");
10671 #endif /* CK_POLL */
10672 #ifdef NOIEXTEN
10673     makestr(&(optlist[noptlist++]),"NOIEXTEN");
10674 #endif /* NOIEXTEN */
10675 #ifdef EXCELAN
10676     makestr(&(optlist[noptlist++]),"EXCELAN");
10677 #endif /* EXCELAN */
10678 #ifdef INTERLAN
10679     makestr(&(optlist[noptlist++]),"INTERLAN");
10680 #endif /* INTERLAN */
10681 #ifdef NOFILEH
10682     makestr(&(optlist[noptlist++]),"NOFILEH");
10683 #endif /* NOFILEH */
10684 #ifdef NOSYSIOCTLH
10685     makestr(&(optlist[noptlist++]),"NOSYSIOCTLH");
10686 #endif /* NOSYSIOCTLH */
10687 #ifdef DCLPOPEN
10688     makestr(&(optlist[noptlist++]),"DCLPOPEN");
10689 #endif /* DCLPOPEN */
10690 #ifdef NOSETBUF
10691     makestr(&(optlist[noptlist++]),"NOSETBUF");
10692 #endif /* NOSETBUF */
10693 #ifdef NOXFER
10694     makestr(&(optlist[noptlist++]),"NOXFER");
10695 #endif /* NOXFER */
10696 #ifdef NOCURSES
10697     makestr(&(optlist[noptlist++]),"NOCURSES");
10698 #endif /* NOCURSES */
10699 #ifdef NOSERVER
10700     makestr(&(optlist[noptlist++]),"NOSERVER");
10701 #endif /* NOSERVER */
10702 #ifdef NOPATTERNS
10703     makestr(&(optlist[noptlist++]),"NOPATTERNS");
10704 #else
10705 #ifdef PATTERNS
10706     makestr(&(optlist[noptlist++]),"PATTERNS");
10707 #endif /* PATTERNS */
10708 #endif /* NOPATTERNS */
10709 #ifdef NOCKEXEC
10710     makestr(&(optlist[noptlist++]),"NOCKEXEC");
10711 #else
10712 #ifdef CKEXEC
10713     makestr(&(optlist[noptlist++]),"CKEXEC");
10714 #endif /* CKEXEC */
10715 #endif /* NOCKEXEC */
10716 #ifdef NOAUTODL
10717     makestr(&(optlist[noptlist++]),"NOAUTODL");
10718 #endif /* NOAUTODL */
10719 #ifdef NOMSEND
10720     makestr(&(optlist[noptlist++]),"NOMSEND");
10721 #endif /* NOMSEND */
10722 #ifdef NOFDZERO
10723     makestr(&(optlist[noptlist++]),"NOFDZERO");
10724 #endif /* NOFDZERO */
10725 #ifdef NOPOPEN
10726     makestr(&(optlist[noptlist++]),"NOPOPEN");
10727 #endif /* NOPOPEN */
10728 #ifdef NOPARTIAL
10729     makestr(&(optlist[noptlist++]),"NOPARTIAL");
10730 #endif /* NOPARTIAL */
10731 #ifdef NOKVERBS
10732     makestr(&(optlist[noptlist++]),"NOKVERBS");
10733 #endif /* NOKVERBS */
10734 #ifdef NOSETREU
10735     makestr(&(optlist[noptlist++]),"NOSETREU");
10736 #endif /* NOSETREU */
10737 #ifdef LCKDIR
10738     makestr(&(optlist[noptlist++]),"LCKDIR");
10739 #endif /* LCKDIR */
10740 #ifdef ACUCNTRL
10741     makestr(&(optlist[noptlist++]),"ACUCNTRL");
10742 #endif /* ACUCNTRL */
10743 #ifdef BSD4
10744     makestr(&(optlist[noptlist++]),"BSD4");
10745 #endif /* BSD4 */
10746 #ifdef BSD44
10747     makestr(&(optlist[noptlist++]),"BSD44");
10748 #endif /* BSD44 */
10749 #ifdef BSD41
10750     makestr(&(optlist[noptlist++]),"BSD41");
10751 #endif /* BSD41 */
10752 #ifdef BSD43
10753     makestr(&(optlist[noptlist++]),"BSD43");
10754 #endif /* BSD43 */
10755 #ifdef BSD29
10756     makestr(&(optlist[noptlist++]),"BSD29");
10757 #endif /* BSD29 */
10758 #ifdef BSDI
10759     makestr(&(optlist[noptlist++]),"BSDI");
10760 #endif /* BSDI */
10761 #ifdef __bsdi__
10762     makestr(&(optlist[noptlist++]),"__bsdi__");
10763 #endif /* __bsdi__ */
10764 #ifdef __NetBSD__
10765     makestr(&(optlist[noptlist++]),"__NetBSD__");
10766 #endif /* __NetBSD__ */
10767 #ifdef __OpenBSD__
10768     makestr(&(optlist[noptlist++]),"__OpenBSD__");
10769 #endif /* __OpenBSD__ */
10770 #ifdef __FreeBSD__
10771     makestr(&(optlist[noptlist++]),"__FreeBSD__");
10772 #endif /* __FreeBSD__ */
10773 #ifdef FREEBSD4
10774     makestr(&(optlist[noptlist++]),"FREEBSD4");
10775 #endif /* FREEBSD4 */
10776 #ifdef FREEBSD8
10777     makestr(&(optlist[noptlist++]),"FREEBSD8");
10778 #endif /* FREEBSD8 */
10779 #ifdef FREEBSD9
10780     makestr(&(optlist[noptlist++]),"FREEBSD9");
10781 #endif /* FREEBSD9 */
10782 #ifdef __linux__
10783     makestr(&(optlist[noptlist++]),"__linux__");
10784 #endif /* __linux__ */
10785 #ifdef LINUX_HI_SPD
10786     makestr(&(optlist[noptlist++]),"LINUX_HI_SPD");
10787 #endif /* LINUX_HI_SPD */
10788 #ifdef LYNXOS
10789     makestr(&(optlist[noptlist++]),"LYNXOS");
10790 #endif /* LYNXOS */
10791 #ifdef V7
10792     makestr(&(optlist[noptlist++]),"V7");
10793 #endif /* V7 */
10794 #ifdef AIX370
10795     makestr(&(optlist[noptlist++]),"AIX370");
10796 #endif /* AIX370 */
10797 #ifdef RTAIX
10798     makestr(&(optlist[noptlist++]),"RTAIX");
10799 #endif /* RTAIX */
10800 #ifdef HPUX
10801     makestr(&(optlist[noptlist++]),"HPUX");
10802 #endif /* HPUX */
10803 #ifdef HPUX9
10804     makestr(&(optlist[noptlist++]),"HPUX9");
10805 #endif /* HPUX9 */
10806 #ifdef HPUX10
10807     makestr(&(optlist[noptlist++]),"HPUX10");
10808 #endif /* HPUX10 */
10809 #ifdef HPUX1000
10810     makestr(&(optlist[noptlist++]),"HPUX1000");
10811 #endif /* HPUX1000 */
10812 #ifdef HPUX1100
10813     makestr(&(optlist[noptlist++]),"HPUX1100");
10814 #endif /* HPUX1100 */
10815 #ifdef HPUXPRE65
10816     makestr(&(optlist[noptlist++]),"HPUXPRE65");
10817 #endif /* HPUXPRE65 */
10818 #ifdef DGUX
10819     makestr(&(optlist[noptlist++]),"DGUX");
10820 #endif /* DGUX */
10821 #ifdef DGUX430
10822     makestr(&(optlist[noptlist++]),"DGUX430");
10823 #endif /* DGUX430 */
10824 #ifdef DGUX540
10825     makestr(&(optlist[noptlist++]),"DGUX540");
10826 #endif /* DGUX540 */
10827 #ifdef DGUX543
10828     makestr(&(optlist[noptlist++]),"DGUX543");
10829 #endif /* DGUX543 */
10830 #ifdef DGUX54410
10831     makestr(&(optlist[noptlist++]),"DGUX54410");
10832 #endif /* DGUX54410 */
10833 #ifdef DGUX54411
10834     makestr(&(optlist[noptlist++]),"DGUX54411");
10835 #endif /* DGUX54411 */
10836 #ifdef sony_news
10837     makestr(&(optlist[noptlist++]),"sony_news");
10838 #endif /* sony_news */
10839 #ifdef CIE
10840     makestr(&(optlist[noptlist++]),"CIE");
10841 #endif /* CIE */
10842 #ifdef XENIX
10843     makestr(&(optlist[noptlist++]),"XENIX");
10844 #endif /* XENIX */
10845 #ifdef SCO_XENIX
10846     makestr(&(optlist[noptlist++]),"SCO_XENIX");
10847 #endif /* SCO_XENIX */
10848 #ifdef ISIII
10849     makestr(&(optlist[noptlist++]),"ISIII");
10850 #endif /* ISIII */
10851 #ifdef I386IX
10852     makestr(&(optlist[noptlist++]),"I386IX");
10853 #endif /* I386IX */
10854 #ifdef RTU
10855     makestr(&(optlist[noptlist++]),"RTU");
10856 #endif /* RTU */
10857 #ifdef PROVX1
10858     makestr(&(optlist[noptlist++]),"PROVX1");
10859 #endif /* PROVX1 */
10860 #ifdef PYRAMID
10861     makestr(&(optlist[noptlist++]),"PYRAMID");
10862 #endif /* PYRAMID */
10863 #ifdef TOWER1
10864     makestr(&(optlist[noptlist++]),"TOWER1");
10865 #endif /* TOWER1 */
10866 #ifdef UTEK
10867     makestr(&(optlist[noptlist++]),"UTEK");
10868 #endif /* UTEK */
10869 #ifdef ZILOG
10870     makestr(&(optlist[noptlist++]),"ZILOG");
10871 #endif /* ZILOG */
10872 #ifdef TRS16
10873     makestr(&(optlist[noptlist++]),"TRS16");
10874 #endif /* TRS16 */
10875 #ifdef MINIX
10876     makestr(&(optlist[noptlist++]),"MINIX");
10877 #endif /* MINIX */
10878 #ifdef MINIX2
10879     makestr(&(optlist[noptlist++]),"MINIX2");
10880 #endif /* MINIX2 */
10881 #ifdef MINIX3
10882     makestr(&(optlist[noptlist++]),"MINIX3");
10883 #endif /* MINIX3 */
10884 #ifdef MINIX315
10885     makestr(&(optlist[noptlist++]),"MINIX315");
10886 #endif /* MINIX315 */
10887 #ifdef C70
10888     makestr(&(optlist[noptlist++]),"C70");
10889 #endif /* C70 */
10890 #ifdef AIXPS2
10891     makestr(&(optlist[noptlist++]),"AIXPS2");
10892 #endif /* AIXPS2 */
10893 #ifdef AIXRS
10894     makestr(&(optlist[noptlist++]),"AIXRS");
10895 #endif /* AIXRS */
10896 #ifdef UTSV
10897     makestr(&(optlist[noptlist++]),"UTSV");
10898 #endif /* UTSV */
10899 #ifdef ATTSV
10900     makestr(&(optlist[noptlist++]),"ATTSV");
10901 #endif /* ATTSV */
10902 #ifdef SVR3
10903     makestr(&(optlist[noptlist++]),"SVR3");
10904 #endif /* SVR3 */
10905 #ifdef SVR4
10906     makestr(&(optlist[noptlist++]),"SVR4");
10907 #endif /* SVR4 */
10908 #ifdef DELL_SVR4
10909     makestr(&(optlist[noptlist++]),"DELL_SVR4");
10910 #endif /* DELL_SVR4 */
10911 #ifdef ICL_SVR4
10912     makestr(&(optlist[noptlist++]),"ICL_SVR4");
10913 #endif /* ICL_SVR4 */
10914 #ifdef OSF
10915     makestr(&(optlist[noptlist++]),"OSF");
10916 #endif /* OSF */
10917 #ifdef OSF1
10918     makestr(&(optlist[noptlist++]),"OSF1");
10919 #endif /* OSF1 */
10920 #ifdef __OSF
10921     makestr(&(optlist[noptlist++]),"__OSF");
10922 #endif /* __OSF */
10923 #ifdef __OSF__
10924     makestr(&(optlist[noptlist++]),"__OSF__");
10925 #endif /* __OSF__ */
10926 #ifdef __osf__
10927     makestr(&(optlist[noptlist++]),"__osf__");
10928 #endif /* __osf__ */
10929 #ifdef __OSF1
10930     makestr(&(optlist[noptlist++]),"__OSF1");
10931 #endif /* __OSF1 */
10932 #ifdef __OSF1__
10933     makestr(&(optlist[noptlist++]),"__OSF1__");
10934 #endif /* __OSF1__ */
10935 #ifdef PTX
10936     makestr(&(optlist[noptlist++]),"PTX");
10937 #endif /* PTX */
10938 #ifdef POSIX
10939     makestr(&(optlist[noptlist++]),"POSIX");
10940 #endif /* POSIX */
10941 #ifdef BSD44ORPOSIX
10942     makestr(&(optlist[noptlist++]),"BSD44ORPOSIX");
10943 #endif /* BSD44ORPOSIX */
10944 #ifdef SVORPOSIX
10945     makestr(&(optlist[noptlist++]),"SVORPOSIX");
10946 #endif /* SVORPOSIX */
10947 #ifdef SVR4ORPOSIX
10948     makestr(&(optlist[noptlist++]),"SVR4ORPOSIX");
10949 #endif /* SVR4ORPOSIX */
10950 #ifdef OS2ORVMS
10951     makestr(&(optlist[noptlist++]),"OS2ORVMS");
10952 #endif /* OS2ORVMS */
10953 #ifdef OS2ORUNIX
10954     makestr(&(optlist[noptlist++]),"OS2ORUNIX");
10955 #endif /* OS2ORUNIX */
10956 #ifdef VMSORUNIX
10957     makestr(&(optlist[noptlist++]),"VMSORUNIX");
10958 #endif /* VMSORUNIX */
10959 #ifdef VMS64BIT
10960     makestr(&(optlist[noptlist++]),"VMS64BIT"); /* VMS on Alpha or IA64 */
10961 #endif /* VMS64BIT */
10962 #ifdef VMSI64
10963     makestr(&(optlist[noptlist++]),"VMSI64"); /* VMS on IA64 */
10964 #endif /* VMSI64 */
10965 #ifdef _POSIX_SOURCE
10966     makestr(&(optlist[noptlist++]),"_POSIX_SOURCE");
10967 #endif /* _POSIX_SOURCE */
10968 #ifdef _XOPEN_SOURCE
10969     makestr(&(optlist[noptlist++]),"_XOPEN_SOURCE");
10970 #endif
10971 #ifdef _ALL_SOURCE
10972     makestr(&(optlist[noptlist++]),"_ALL_SOURCE");
10973 #endif
10974 #ifdef _SVID3
10975     makestr(&(optlist[noptlist++]),"_SVID3");
10976 #endif /* _SVID3 */
10977 #ifdef Plan9
10978     makestr(&(optlist[noptlist++]),"Plan9");
10979 #endif /* Plan9 */
10980 #ifdef SOLARIS
10981     makestr(&(optlist[noptlist++]),"SOLARIS");
10982 #ifdef SOLARIS24
10983     makestr(&(optlist[noptlist++]),"SOLARIS24");
10984 #endif /* SOLARIS24 */
10985 #ifdef SOLARIS25
10986     makestr(&(optlist[noptlist++]),"SOLARIS25");
10987 #endif /* SOLARIS25 */
10988 #ifdef SOLARIS26
10989     makestr(&(optlist[noptlist++]),"SOLARIS26");
10990 #endif /* SOLARIS26 */
10991 #ifdef SOLARIS7
10992     makestr(&(optlist[noptlist++]),"SOLARIS7");
10993 #endif /* SOLARIS7 */
10994 #ifdef SOLARIS8
10995     makestr(&(optlist[noptlist++]),"SOLARIS8");
10996 #endif /* SOLARIS8 */
10997 #ifdef SOLARIS9
10998     makestr(&(optlist[noptlist++]),"SOLARIS9");
10999 #endif /* SOLARIS9 */
11000 #ifdef SOLARIS10
11001     makestr(&(optlist[noptlist++]),"SOLARIS10");
11002 #endif /* SOLARIS10 */
11003 #endif /* SOLARIS */
11004
11005 #ifdef SUNOS4
11006     makestr(&(optlist[noptlist++]),"SUNOS4");
11007 #endif /* SUNOS4 */
11008 #ifdef SUN4S5
11009     makestr(&(optlist[noptlist++]),"SUN4S5");
11010 #endif /* SUN4S5 */
11011 #ifdef IRIX
11012     makestr(&(optlist[noptlist++]),"IRIX");
11013 #endif /* IRIX */
11014 #ifdef ENCORE
11015     makestr(&(optlist[noptlist++]),"ENCORE");
11016 #endif /* ENCORE */
11017 #ifdef ultrix
11018     makestr(&(optlist[noptlist++]),"ultrix");
11019 #endif
11020 #ifdef sxaE50
11021     makestr(&(optlist[noptlist++]),"sxaE50");
11022 #endif
11023 #ifdef mips
11024     makestr(&(optlist[noptlist++]),"mips");
11025 #endif
11026 #ifdef MIPS
11027     makestr(&(optlist[noptlist++]),"MIPS");
11028 #endif
11029 #ifdef vax
11030     makestr(&(optlist[noptlist++]),"vax");
11031 #endif
11032 #ifdef VAX
11033     makestr(&(optlist[noptlist++]),"VAX");
11034 #endif
11035 #ifdef alpha
11036     makestr(&(optlist[noptlist++]),"alpha");
11037 #endif
11038 #ifdef ALPHA
11039     makestr(&(optlist[noptlist++]),"ALPHA");
11040 #endif
11041 #ifdef __ALPHA
11042     makestr(&(optlist[noptlist++]),"__ALPHA");
11043 #endif
11044 #ifdef __alpha
11045     makestr(&(optlist[noptlist++]),"__alpha");
11046 #endif
11047 #ifdef __AXP
11048     makestr(&(optlist[noptlist++]),"__AXP");
11049 #endif
11050 #ifdef AXP
11051     makestr(&(optlist[noptlist++]),"AXP");
11052 #endif
11053 #ifdef axp
11054     makestr(&(optlist[noptlist++]),"axp");
11055 #endif
11056 #ifdef __ALPHA__
11057     makestr(&(optlist[noptlist++]),"__ALPHA__");
11058 #endif
11059 #ifdef __alpha__
11060     makestr(&(optlist[noptlist++]),"__alpha__");
11061 #endif
11062 #ifdef sun
11063     makestr(&(optlist[noptlist++]),"sun");
11064 #endif
11065 #ifdef sun3
11066     makestr(&(optlist[noptlist++]),"sun3");
11067 #endif
11068 #ifdef sun386
11069     makestr(&(optlist[noptlist++]),"sun386");
11070 #endif
11071 #ifdef _SUN
11072     makestr(&(optlist[noptlist++]),"_SUN");
11073 #endif
11074 #ifdef sun4
11075     makestr(&(optlist[noptlist++]),"sun4");
11076 #endif
11077 #ifdef sparc
11078     makestr(&(optlist[noptlist++]),"sparc");
11079 #endif
11080 #ifdef _CRAY
11081     makestr(&(optlist[noptlist++]),"_CRAY");
11082 #endif /* _CRAY */
11083 #ifdef NEXT33
11084     makestr(&(optlist[noptlist++]),"NEXT33");
11085 #endif
11086 #ifdef NEXT
11087     makestr(&(optlist[noptlist++]),"NEXT");
11088 #endif
11089 #ifdef NeXT
11090     makestr(&(optlist[noptlist++]),"NeXT");
11091 #endif
11092 #ifdef MACH
11093     makestr(&(optlist[noptlist++]),"MACH");
11094 #endif
11095
11096 #ifdef MACOSX
11097     makestr(&(optlist[noptlist++]),"MACOSX");
11098 #endif
11099 #ifdef MACOSX10
11100     makestr(&(optlist[noptlist++]),"MACOSX10");
11101 #endif
11102 #ifdef MACOSX103
11103     makestr(&(optlist[noptlist++]),"MACOSX10e");
11104 #endif
11105 #ifdef COMMENT
11106 /* not used */
11107 #ifdef MACOSX103
11108     makestr(&(optlist[noptlist++]),"MACOSX103");
11109 #endif
11110 #endif  /* COMMENT */
11111
11112 #ifdef sgi
11113     makestr(&(optlist[noptlist++]),"sgi");
11114 #endif
11115 #ifdef M_SYS5
11116     makestr(&(optlist[noptlist++]),"M_SYS5");
11117 #endif
11118 #ifdef __SYSTEM_FIVE
11119     makestr(&(optlist[noptlist++]),"__SYSTEM_FIVE");
11120 #endif
11121 #ifdef sysV
11122     makestr(&(optlist[noptlist++]),"sysV");
11123 #endif
11124 #ifdef M_XENIX                          /* SCO Xenix V and UNIX/386 */
11125     makestr(&(optlist[noptlist++]),"M_XENIX");
11126 #endif
11127 #ifdef M_UNIX                           /* SCO UNIX */
11128     makestr(&(optlist[noptlist++]),"M_UNIX");
11129 #endif
11130 #ifdef _M_UNIX                          /* SCO UNIX 3.2v4 = ODT 2.0 */
11131     makestr(&(optlist[noptlist++]),"_M_UNIX");
11132 #endif
11133 #ifdef CK_SCOV5
11134     makestr(&(optlist[noptlist++]),"CK_SCOV5");
11135 #endif
11136 #ifdef SCO_OSR504
11137     makestr(&(optlist[noptlist++]),"SCO_OSR504");
11138 #endif
11139 #ifdef M_IA64
11140     makestr(&(optlist[noptlist++]),"M_IA64");
11141 #endif
11142 #ifdef _M_IA64
11143     makestr(&(optlist[noptlist++]),"_M_IA64");
11144 #endif
11145 #ifdef ia64
11146     makestr(&(optlist[noptlist++]),"ia64");
11147 #endif
11148 #ifdef _ia64
11149     makestr(&(optlist[noptlist++]),"_ia64");
11150 #endif
11151 #ifdef _ia64_
11152     makestr(&(optlist[noptlist++]),"_ia64_");
11153 #endif
11154 #ifdef __ia64
11155     makestr(&(optlist[noptlist++]),"__ia64");
11156 #endif
11157 #ifdef M_I686
11158     makestr(&(optlist[noptlist++]),"M_I686");
11159 #endif
11160 #ifdef _M_I686
11161     makestr(&(optlist[noptlist++]),"_M_I686");
11162 #endif
11163 #ifdef i686
11164     makestr(&(optlist[noptlist++]),"i686");
11165 #endif
11166 #ifdef M_I586
11167     makestr(&(optlist[noptlist++]),"M_I586");
11168 #endif
11169 #ifdef _M_I586
11170     makestr(&(optlist[noptlist++]),"_M_I586");
11171 #endif
11172 #ifdef i586
11173     makestr(&(optlist[noptlist++]),"i586");
11174 #endif
11175 #ifdef M_I486
11176     makestr(&(optlist[noptlist++]),"M_I486");
11177 #endif
11178 #ifdef _M_I486
11179     makestr(&(optlist[noptlist++]),"_M_I486");
11180 #endif
11181 #ifdef i486
11182     makestr(&(optlist[noptlist++]),"i486");
11183 #endif
11184 #ifdef M_I386
11185     makestr(&(optlist[noptlist++]),"M_I386");
11186 #endif
11187 #ifdef _M_I386
11188     makestr(&(optlist[noptlist++]),"_M_I386");
11189 #endif
11190 #ifdef i386
11191     makestr(&(optlist[noptlist++]),"i386");
11192 #endif
11193 #ifdef __i386
11194     makestr(&(optlist[noptlist++]),"__i386");
11195 #endif
11196 #ifdef __x86
11197     makestr(&(optlist[noptlist++]),"__x86");
11198 #endif
11199 #ifdef __amd64
11200     makestr(&(optlist[noptlist++]),"__amd64");
11201 #endif
11202 #ifdef _ILP32
11203     makestr(&(optlist[noptlist++]),"_ILP32");
11204 #endif
11205 #ifdef _ILP64
11206     makestr(&(optlist[noptlist++]),"_ILP64");
11207 #endif
11208 #ifdef _LP32
11209     makestr(&(optlist[noptlist++]),"_LP32");
11210 #endif
11211 #ifdef _LP64
11212     makestr(&(optlist[noptlist++]),"_LP64");
11213 #endif
11214 #ifdef __LP32__
11215     makestr(&(optlist[noptlist++]),"__LP32__");
11216 #endif
11217 #ifdef __LP64__
11218     makestr(&(optlist[noptlist++]),"__LP64__");
11219 #endif
11220 #ifdef _XGP4_2
11221     makestr(&(optlist[noptlist++]),"_XGP4_2");
11222 #endif
11223 #ifdef __ppc__
11224     makestr(&(optlist[noptlist++]),"__ppc__");
11225 #endif
11226 #ifdef __ppc32__
11227     makestr(&(optlist[noptlist++]),"__ppc32__");
11228 #endif
11229 #ifdef __ppc64__
11230     makestr(&(optlist[noptlist++]),"__ppc64__");
11231 #endif
11232 #ifdef CK_64BIT
11233     makestr(&(optlist[noptlist++]),"CK_64BIT");
11234 #endif
11235 #ifdef i286
11236     makestr(&(optlist[noptlist++]),"i286");
11237 #endif
11238 #ifdef M_I286
11239     makestr(&(optlist[noptlist++]),"M_I286");
11240 #endif
11241 #ifdef __sparc
11242     makestr(&(optlist[noptlist++]),"__sparc");
11243 #endif
11244 #ifdef __sparcv8
11245     makestr(&(optlist[noptlist++]),"__sparcv8");
11246 #endif
11247 #ifdef __sparcv9
11248     makestr(&(optlist[noptlist++]),"__sparcv9");
11249 #endif
11250 #ifdef mc68000
11251     makestr(&(optlist[noptlist++]),"mc68000");
11252 #endif
11253 #ifdef mc68010
11254     makestr(&(optlist[noptlist++]),"mc68010");
11255 #endif
11256 #ifdef mc68020
11257     makestr(&(optlist[noptlist++]),"mc68020");
11258 #endif
11259 #ifdef mc68030
11260     makestr(&(optlist[noptlist++]),"mc68030");
11261 #endif
11262 #ifdef mc68040
11263     makestr(&(optlist[noptlist++]),"mc68040");
11264 #endif
11265 #ifdef M_68000
11266     makestr(&(optlist[noptlist++]),"M_68000");
11267 #endif
11268 #ifdef M_68010
11269     makestr(&(optlist[noptlist++]),"M_68010");
11270 #endif
11271 #ifdef M_68020
11272     makestr(&(optlist[noptlist++]),"M_68020");
11273 #endif
11274 #ifdef M_68030
11275     makestr(&(optlist[noptlist++]),"M_68030");
11276 #endif
11277 #ifdef M_68040
11278     makestr(&(optlist[noptlist++]),"M_68040");
11279 #endif
11280 #ifdef m68k
11281     makestr(&(optlist[noptlist++]),"m68k");
11282 #endif
11283 #ifdef m88k
11284     makestr(&(optlist[noptlist++]),"m88k");
11285 #endif
11286 #ifdef pdp11
11287     makestr(&(optlist[noptlist++]),"pdp11");
11288 #endif
11289 #ifdef iAPX
11290     makestr(&(optlist[noptlist++]),"iAPX");
11291 #endif
11292 #ifdef hpux
11293     makestr(&(optlist[noptlist++]),"hpux");
11294 #endif
11295 #ifdef __hpux
11296     makestr(&(optlist[noptlist++]),"__hpux");
11297 #endif
11298 #ifdef __hp9000s800
11299     makestr(&(optlist[noptlist++]),"__hp9000s800");
11300 #endif
11301 #ifdef __hp9000s700
11302     makestr(&(optlist[noptlist++]),"__hp9000s700");
11303 #endif
11304 #ifdef __hp9000s500
11305     makestr(&(optlist[noptlist++]),"__hp9000s500");
11306 #endif
11307 #ifdef __hp9000s300
11308     makestr(&(optlist[noptlist++]),"__hp9000s300");
11309 #endif
11310 #ifdef __hp9000s200
11311     makestr(&(optlist[noptlist++]),"__hp9000s200");
11312 #endif
11313 #ifdef AIX
11314     makestr(&(optlist[noptlist++]),"AIX");
11315 #endif
11316 #ifdef _AIXFS
11317     makestr(&(optlist[noptlist++]),"_AIXFS");
11318 #endif
11319 #ifdef u370
11320     makestr(&(optlist[noptlist++]),"u370");
11321 #endif
11322 #ifdef u3b
11323     makestr(&(optlist[noptlist++]),"u3b");
11324 #endif
11325 #ifdef u3b2
11326     makestr(&(optlist[noptlist++]),"u3b2");
11327 #endif
11328 #ifdef multimax
11329     makestr(&(optlist[noptlist++]),"multimax");
11330 #endif
11331 #ifdef balance
11332     makestr(&(optlist[noptlist++]),"balance");
11333 #endif
11334 #ifdef ibmrt
11335     makestr(&(optlist[noptlist++]),"ibmrt");
11336 #endif
11337 #ifdef _IBMRT
11338     makestr(&(optlist[noptlist++]),"_IBMRT");
11339 #endif
11340 #ifdef ibmrs6000
11341     makestr(&(optlist[noptlist++]),"ibmrs6000");
11342 #endif
11343 #ifdef _AIX
11344     makestr(&(optlist[noptlist++]),"_AIX");
11345 #endif /* _AIX */
11346 #ifdef _IBMR2
11347     makestr(&(optlist[noptlist++]),"_IBMR2");
11348 #endif
11349 #ifdef UNIXWARE
11350     makestr(&(optlist[noptlist++]),"UNIXWARE");
11351 #endif
11352 #ifdef QNX
11353     makestr(&(optlist[noptlist++]),"QNX");
11354 #ifdef __QNX__
11355     makestr(&(optlist[noptlist++]),"__QNX__");
11356 #ifdef __16BIT__
11357     makestr(&(optlist[noptlist++]),"__16BIT__");
11358 #endif
11359 #ifdef CK_QNX16
11360     makestr(&(optlist[noptlist++]),"CK_QNX16");
11361 #endif
11362 #ifdef __32BIT__
11363     makestr(&(optlist[noptlist++]),"__32BIT__");
11364 #endif
11365 #ifdef CK_QNX32
11366     makestr(&(optlist[noptlist++]),"CK_QNX32");
11367 #endif
11368 #endif /* __QNX__ */
11369 #endif /* QNX */
11370
11371 #ifdef QNX6
11372     makestr(&(optlist[noptlist++]),"QNX6");
11373 #endif /* QNX6 */
11374
11375 #ifdef NEUTRINO
11376     makestr(&(optlist[noptlist++]),"NEUTRINO");
11377 #endif /* NEUTRINO */
11378
11379 #ifdef __STRICT_BSD__
11380     makestr(&(optlist[noptlist++]),"__STRICT_BSD__");
11381 #endif
11382 #ifdef __STRICT_ANSI__
11383     makestr(&(optlist[noptlist++]),"__STRICT_ANSI__");
11384 #endif
11385 #ifdef _ANSI_C_SOURCE
11386     makestr(&(optlist[noptlist++]),"_ANSI_C_SOURCE");
11387 #endif
11388 #ifdef __STDC__
11389     makestr(&(optlist[noptlist++]),"__STDC__");
11390 #endif
11391 #ifdef cplusplus
11392     makestr(&(optlist[noptlist++]),"cplusplus");
11393 #endif
11394 #ifdef __DECC
11395     makestr(&(optlist[noptlist++]),"__DECC");
11396 #ifdef __DECC_VER
11397     sprintf(line,"__DECC_VER=%d",__DECC_VER); /* SAFE */
11398     makestr(&(optlist[noptlist++]),line);
11399 #endif /* __DECC_VER */
11400 #endif /* __DECC */
11401 #ifdef __CRTL_VER
11402     sprintf(line,"__CRTL_VER=%d",__CRTL_VER); /* SAFE */
11403     makestr(&(optlist[noptlist++]),line);
11404 #endif /* __CRTL_VER */
11405 #ifdef __GNUC__                         /* gcc in ansi mode */
11406     makestr(&(optlist[noptlist++]),"__GNUC__");
11407 #endif
11408 #ifdef GNUC                             /* gcc in traditional mode */
11409     makestr(&(optlist[noptlist++]),"GNUC");
11410 #endif
11411 #ifdef __EGCS__                         /* egcs in ansi mode */
11412     makestr(&(optlist[noptlist++]),"__EGCS__");
11413 #endif
11414 #ifdef __egcs__                         /* egcs in ansi mode */
11415     makestr(&(optlist[noptlist++]),"__egcs__");
11416 #endif
11417 #ifdef __WATCOMC__
11418     makestr(&(optlist[noptlist++]),"__WATCOMC__");
11419 #endif
11420 #ifdef CK_ANSIC
11421     makestr(&(optlist[noptlist++]),"CK_ANSIC");
11422 #endif
11423 #ifdef CK_ANSILIBS
11424     makestr(&(optlist[noptlist++]),"CK_ANSILIBS");
11425 #endif
11426 #ifdef CKCONINTB4CB
11427     makestr(&(optlist[noptlist++]),"CKCONINTB4CB");
11428 #endif /* CKCONINTB4CB */
11429 #ifdef NOTERMCAP
11430     makestr(&(optlist[noptlist++]),"NOTERMCAP");
11431 #endif /* NOTERMCAP */
11432 #ifdef __GLIBC__
11433     makestr(&(optlist[noptlist++]),"__GLIBC__");
11434 #endif
11435 #ifdef _SC_JOB_CONTROL
11436     makestr(&(optlist[noptlist++]),"_SC_JOB_CONTROL");
11437 #endif
11438 #ifdef _POSIX_JOB_CONTROL
11439     makestr(&(optlist[noptlist++]),"_POSIX_JOB_CONTROL");
11440 #endif
11441 #ifdef SIG_I
11442     makestr(&(optlist[noptlist++]),"SIG_I");
11443 #endif /* SIG_I */
11444 #ifdef SIG_V
11445     makestr(&(optlist[noptlist++]),"SIG_V");
11446 #endif /* SIG_V */
11447 #ifdef CK_POSIX_SIG
11448     makestr(&(optlist[noptlist++]),"CK_POSIX_SIG");
11449 #endif
11450 #ifdef SVR3JC
11451     makestr(&(optlist[noptlist++]),"SVR3JC");
11452 #endif
11453 #ifdef _386BSD
11454     makestr(&(optlist[noptlist++]),"_386BSD");
11455 #endif
11456 #ifdef _BSD
11457     makestr(&(optlist[noptlist++]),"_BSD");
11458 #endif
11459 #ifdef USE_MEMCPY
11460     makestr(&(optlist[noptlist++]),"USE_MEMCPY");
11461 #endif /* USE_MEMCPY */
11462 #ifdef USE_LSTAT
11463     makestr(&(optlist[noptlist++]),"USE_LSTAT");
11464 #endif /* USE_LSTAT */
11465 #ifdef TERMIOX
11466     makestr(&(optlist[noptlist++]),"TERMIOX");
11467 #endif /* TERMIOX */
11468 #ifdef STERMIOX
11469     makestr(&(optlist[noptlist++]),"STERMIOX");
11470 #endif /* STERMIOX */
11471 #ifdef CK_CURSES
11472     makestr(&(optlist[noptlist++]),"CK_CURSES");
11473 #endif /* CK_CURSES */
11474 #ifdef CK_NEWTERM
11475     makestr(&(optlist[noptlist++]),"CK_NEWTERM");
11476 #endif /* CK_NEWTERM */
11477 #ifdef CK_WREFRESH
11478     makestr(&(optlist[noptlist++]),"CK_WREFRESH");
11479 #endif /* CK_WREFRESH */
11480 #ifdef CK_PCT_BAR
11481     makestr(&(optlist[noptlist++]),"CK_PCT_BAR");
11482 #endif /* CK_PCT_BAR */
11483 #ifdef CK_DTRCD
11484     makestr(&(optlist[noptlist++]),"CK_DTRCD");
11485 #endif /* CK_DTRCD */
11486 #ifdef CK_DTRCTS
11487     makestr(&(optlist[noptlist++]),"CK_DTRCTS");
11488 #endif /* CK_DTRCTS */
11489 #ifdef CK_RTSCTS
11490     makestr(&(optlist[noptlist++]),"CK_RTSCTS");
11491 #endif /* CK_RTSCTS */
11492 #ifdef POSIX_CRTSCTS
11493     makestr(&(optlist[noptlist++]),"POSIX_CRTSCTS");
11494 #endif /* POSIX_CRTSCTS */
11495 #ifdef FIXCRTSCTS
11496     makestr(&(optlist[noptlist++]),"FIXCRTSCTS");
11497 #endif /* FIXCRTSCTS */
11498 #ifdef HWPARITY
11499     makestr(&(optlist[noptlist++]),"HWPARITY");
11500 #endif /* HWPARITY */
11501 #ifdef CK_SYSINI
11502 #ifdef CK_INI_A
11503     makestr(&(optlist[noptlist++]),"CK_INI_A");
11504     ckmakmsg(line,LINBUFSIZ,"CK_SYSINI=\"",CK_SYSINI,"\"",NULL);
11505     makestr(&(optlist[noptlist++]),line);
11506 #else
11507 #ifdef CK_INI_B
11508     makestr(&(optlist[noptlist++]),"CK_INI_B");
11509     ckmakmsg(line,LINBUFSIZ,"CK_SYSINI=\"",CK_SYSINI,"\"",NULL);
11510     makestr(&(optlist[noptlist++]),line);
11511 #else
11512     makestr(&(optlist[noptlist++]),"CK_SYSINI");
11513 #endif /* CK_INI_B */
11514 #endif /* CK_INI_A */
11515 #endif /* CK_DSYSINI */
11516 #ifdef CK_DSYSINI
11517     makestr(&(optlist[noptlist++]),"CK_DSYSINI");
11518 #endif /* CK_DSYSINI */
11519 #ifdef CK_TTGWSIZ
11520     makestr(&(optlist[noptlist++]),"CK_TTGWSIZ");
11521 #endif /* CK_TTGWSIZ */
11522 #ifdef CK_NAWS
11523     makestr(&(optlist[noptlist++]),"CK_NAWS");
11524 #endif /* CK_NAWS */
11525 #ifdef MDMHUP
11526     makestr(&(optlist[noptlist++]),"MDMHUP");
11527 #endif /* MDMHUP */
11528 #ifdef HUP_CLOSE_POSIX
11529     makestr(&(optlist[noptlist++]),"HUP_CLOSE_POSIX");
11530 #endif /* HUP_CLOSE_POSIX */
11531 #ifdef NO_HUP_CLOSE_POSIX
11532     makestr(&(optlist[noptlist++]),"NO_HUP_CLOSE_POSIX");
11533 #endif /* NO_HUP_CLOSE_POSIX */
11534 #ifdef DCMDBUF
11535     makestr(&(optlist[noptlist++]),"DCMDBUF");
11536 #endif /* DCMDBUF */
11537 #ifdef CK_RECALL
11538     makestr(&(optlist[noptlist++]),"CK_RECALL");
11539 #endif /* CK_RECALL */
11540 #ifdef BROWSER
11541     makestr(&(optlist[noptlist++]),"BROWSER");
11542 #endif /* BROWSER */
11543 #ifdef CLSOPN
11544     makestr(&(optlist[noptlist++]),"CLSOPN");
11545 #endif /* CLSOPN */
11546 #ifdef STRATUS
11547     makestr(&(optlist[noptlist++]),"STRATUS");
11548 #endif /* STRATUS */
11549 #ifdef __VOS__
11550     makestr(&(optlist[noptlist++]),"__VOS__");
11551 #endif /* __VOS__ */
11552 #ifdef STRATUSX25
11553     makestr(&(optlist[noptlist++]),"STRATUSX25");
11554 #endif /* STRATUSX25 */
11555 #ifdef OS2MOUSE
11556     makestr(&(optlist[noptlist++]),"OS2MOUSE");
11557 #endif /* OS2MOUSE */
11558 #ifdef CK_REXX
11559     makestr(&(optlist[noptlist++]),"CK_REXX");
11560 #endif /* CK_REXX */
11561 #ifdef CK_TIMERS
11562     makestr(&(optlist[noptlist++]),"CK_TIMERS");
11563 #endif /* CK_TIMERS */
11564 #ifdef TTSPDLIST
11565     makestr(&(optlist[noptlist++]),"TTSPDLIST");
11566 #endif /* TTSPDLIST */
11567 #ifdef CK_PERMS
11568     makestr(&(optlist[noptlist++]),"CK_PERMS");
11569 #endif /* CK_PERMS */
11570 #ifdef CKTUNING
11571     makestr(&(optlist[noptlist++]),"CKTUNING");
11572 #endif /* CKTUNING */
11573 #ifdef NEWFTP
11574     makestr(&(optlist[noptlist++]),"NEWFTP");
11575 #endif /* NEWFTP */
11576 #ifdef SYSFTP
11577     makestr(&(optlist[noptlist++]),"SYSFTP");
11578 #endif /* SYSFTP */
11579 #ifdef NOFTP
11580     makestr(&(optlist[noptlist++]),"NOFTP");
11581 #endif /* NOFTP */
11582 #ifdef CKHTTP
11583     makestr(&(optlist[noptlist++]),"CKHTTP");
11584 #endif /* CKHTTP */
11585 #ifdef NOHTTP
11586     makestr(&(optlist[noptlist++]),"NOHTTP");
11587 #endif /* NOHTTP */
11588 #ifdef CKROOT
11589     makestr(&(optlist[noptlist++]),"CKROOT");
11590 #endif /* CKROOT */
11591 #ifdef CKREALPATH
11592     makestr(&(optlist[noptlist++]),"CKREALPATH");
11593 #endif /* CKREALPATH */
11594 #ifdef STREAMING
11595     makestr(&(optlist[noptlist++]),"STREAMING");
11596 #endif /* STREAMING */
11597 #ifdef UNPREFIXZERO
11598     makestr(&(optlist[noptlist++]),"UNPREFIXZERO");
11599 #endif /* UNPREFIXZERO */
11600 #ifdef CKREGEX
11601     makestr(&(optlist[noptlist++]),"CKREGEX");
11602 #endif /* CKREGEX */
11603 #ifdef ZXREWIND
11604     makestr(&(optlist[noptlist++]),"ZXREWIND");
11605 #endif /* ZXREWIND */
11606 #ifdef CKSYSLOG
11607     makestr(&(optlist[noptlist++]),"CKSYSLOG");
11608 #endif /* CKSYSLOG */
11609 #ifdef SYSLOGLEVEL
11610     sprintf(line,"SYSLOGLEVEL=%d",SYSLOGLEVEL); /* SAFE */
11611     makestr(&(optlist[noptlist++]),line);
11612 #endif /* SYSLOGLEVEL */
11613 #ifdef NOSEXP
11614     makestr(&(optlist[noptlist++]),"NOSEXP");
11615 #endif /* NOSEXP */
11616 #ifdef CKLEARN
11617     makestr(&(optlist[noptlist++]),"CKLEARN");
11618 #else
11619 #ifdef NOLOEARN
11620     makestr(&(optlist[noptlist++]),"NOLOEARN");
11621 #endif /* NOLOEARN */
11622 #endif /* CKLEARN */
11623
11624 #ifdef NOFLOAT
11625     makestr(&(optlist[noptlist++]),"NOFLOAT");
11626 #else
11627 #ifdef FNFLOAT
11628     makestr(&(optlist[noptlist++]),"FNFLOAT");
11629 #endif /* FNFLOAT */
11630 #ifdef CKFLOAT
11631 #ifdef GFTIMER
11632     makestr(&(optlist[noptlist++]),"GFTIMER");
11633 #endif /* GFTIMER */
11634 #ifdef CKFLOAT_S
11635     ckmakmsg(line,LINBUFSIZ,"CKFLOAT=",CKFLOAT_S,NULL,NULL);
11636     makestr(&(optlist[noptlist++]),line);
11637 #else
11638     makestr(&(optlist[noptlist++]),"CKFLOAT");
11639 #endif /* CKFLOAT_S */
11640 #endif /* CKFLOAT */
11641 #endif /* NOFLOAT */
11642
11643 #ifdef SSH
11644     makestr(&(optlist[noptlist++]),"SSH");
11645 #endif /* SSH */
11646 #ifdef NETDLL
11647     makestr(&(optlist[noptlist++]),"NETDLL");
11648 #endif /* NETDLL */
11649 #ifdef NETFILE
11650     makestr(&(optlist[noptlist++]),"NETFILE");
11651 #endif /* NETFILE */
11652 #ifdef CK_TAPI
11653     makestr(&(optlist[noptlist++]),"CK_TAPI");
11654 #endif /* CK_TAPI */
11655 #ifdef CK_SSL
11656     makestr(&(optlist[noptlist++]),"CK_SSL");
11657 #ifdef OPENSSL_VERSION_TEXT
11658     ckmakmsg(line,LINBUFSIZ,
11659              "OPENSSL_VERSION_TEXT=","\"",OPENSSL_VERSION_TEXT,"\"");
11660     makestr(&(optlist[noptlist++]),line);
11661 #endif  /* OPENSSL_VERSION_TEXT */
11662 #endif /* CK_SSL */
11663     debug(F101,"initoptlist noptlist","",noptlist);
11664     sh_sort(optlist,NULL,noptlist,0,0,0);
11665 }
11666
11667 int
11668 shofea() {
11669     int i;
11670     int flag = 0;
11671     int lines = 1;
11672 #ifdef FNFLOAT
11673     extern int fp_digits, fp_rounding;
11674 #endif /* FNFLOAT */
11675     extern int byteorder;
11676     printf("%s\n",versio);
11677     if (inserver)
11678       return(1);
11679
11680     debug(F101,"shofea NOPTLIST","",NOPTLIST);
11681     initoptlist();
11682     debug(F101,"shofea noptlist","",noptlist);
11683 #ifdef OS2
11684 #ifdef NT
11685 #ifdef _M_ALPHA
11686     printf("Microsoft Windows Operating Systems for Alpha CPUs.\n");
11687 #else /* _M_ALPHA */
11688 #ifdef _M_PPC
11689     printf("Microsoft Windows Operating Systems for PowerPC CPUs.\n");
11690 #else /* _M_PPC */
11691 #ifdef _M_MRX000
11692     printf("Microsoft Windows Operating Systems for MIPS CPUs.\n");
11693 #else /* _M_MRX000 */
11694 #ifdef _M_IX86
11695     printf("Microsoft Windows Operating Systems for 32-bit Intel CPUs.\n");
11696 #else /* _M_IX86 */
11697     UNKNOWN WINDOWS PLATFORM
11698 #endif /* _M_IX86 */
11699 #endif /* _M_MRX000 */
11700 #endif /* _M_PPC */
11701 #endif /* _M_ALPHA */
11702 #else /* NT */
11703 #ifdef M_I286
11704     printf("IBM OS/2 16-bit.\n");
11705 #else
11706     printf("IBM OS/2 32-bit.\n");
11707 #endif /* M_I286 */
11708 #endif /* NT */
11709     lines++;
11710 #endif /* OS2 */
11711     printf("\n");
11712     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11713     printf("Major optional features included:\n");
11714     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11715
11716     if (sizeof(CK_OFF_T) == 8) {
11717         printf(" Large files and large integers (64 bits)\n");
11718         if (++lines > cmd_rows - 3) {
11719             if (!askmore()) return(1); else lines = 0;
11720         }
11721     }
11722 #ifdef NETCONN
11723     printf(" Network support (type SHOW NET for further info)\n");
11724     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11725 #ifdef IKS_OPTION
11726     printf(" Telnet Kermit Option\n");
11727     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11728 #endif /* IKS_OPTION */
11729 #ifdef CK_AUTHENTICATION
11730     printf(" Telnet Authentication Option\n");
11731     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11732 #ifdef CK_KERBEROS
11733 #ifdef KRB4
11734 #ifdef KRB5
11735     printf(" Kerberos(TM) IV and Kerberos V authentication\n");
11736     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11737 #else /* KRB5 */
11738     printf(" Kerberos(TM) IV authentication\n");
11739     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11740 #endif /* KRB5 */
11741 #else /* KRB4 */
11742 #ifdef KRB5
11743     printf(" Kerberos(TM) V authentication\n");
11744     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11745 #endif /* KRB5 */
11746 #endif /* KRB4 */
11747 #endif /* CK_KERBEROS */
11748 #ifdef CK_SRP
11749     printf(" SRP(TM) (Secure Remote Password) authentication\n");
11750     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11751 #endif /* CK_SRP */
11752 #ifdef CK_SSL
11753     printf(" Secure Sockets Layer (SSL)\n");
11754     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11755     printf(" Transport Layer Security (TLS)\n");
11756     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11757 #endif /* CK_SSL */
11758 #ifdef SSHBUILTIN
11759     printf(" Secure Shell (SSH) [internal]\n");
11760     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11761 #endif /* SSHBUILTIN */
11762 #ifdef SSHCMD
11763     printf(" Secure Shell (SSH) [external]\n");
11764     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11765 #endif /* SSHCMD */
11766 #ifdef CK_ENCRYPTION
11767     printf(" Telnet Encryption Option\n");
11768     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11769 #ifdef CK_DES
11770     printf(" Telnet DES Encryption\n");
11771     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11772 #endif /* CK_DES */
11773 #ifdef CK_CAST
11774     printf(" Telnet CAST Encryption\n");
11775     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11776 #endif /* CK_CAST */
11777
11778 #ifdef CK_KERBEROS
11779 #ifdef KRB5
11780 #ifdef ALLOW_KRB_3DES_ENCRYPT
11781     printf(" Kerberos 3DES/AES Telnet Encryption\n");
11782     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11783 #endif /* ALLOW_KRB_3DES_ENCRYPT */
11784 #endif /* KRB5 */
11785 #endif /* CK_KERBEROS */
11786
11787 #endif /* CK_ENCRYPTION */
11788 #endif /* CK_AUTHENTICATION */
11789 #ifdef CK_FORWARD_X
11790     printf(" X Windows forwarding\n");
11791     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11792 #endif /* CK_FORWARD_X */
11793 #ifdef TN_COMPORT
11794     printf(" Telnet Remote Com Port Control Option\n");
11795     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11796 #endif /* TN_COMPORT */
11797 #ifdef CK_SOCKS
11798 #ifdef CK_SOCKS5
11799     printf(" SOCKS 5\n");
11800     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11801 #else /* CK_SOCKS5 */
11802     printf(" SOCKS 4\n");
11803     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11804 #endif /* CK_SOCKS5 */
11805 #endif /* CK_SOCKS */
11806 #ifdef NEWFTP
11807     printf(" Built-in FTP client\n");
11808     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11809 #endif /* NEWFTP */
11810 #ifdef CKHTTP
11811     printf(" Built-in HTTP client\n");
11812     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11813 #endif /* CKHTTP */
11814 #endif /* NETCONN */
11815
11816 #ifdef CK_RTSCTS
11817     printf(" Hardware flow control\n");
11818     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11819 #endif /* CK_RTSCTS */
11820
11821 #ifdef CK_XYZ
11822 #ifdef XYZ_INTERNAL
11823     printf(" Built-in XYZMODEM protocols\n");
11824 #else
11825     printf(" External XYZMODEM protocol support\n");
11826 #endif /* XYZ_INTERNAL */
11827     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11828 #endif /* CK_XYZ */
11829
11830 #ifndef NOCSETS
11831     printf(" Latin-1 (West European) character-set translation\n");
11832     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11833 #ifdef LATIN2
11834     printf(" Latin-2 (East European) character-set translation\n");
11835     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11836 #endif /* LATIN2 */
11837 #ifdef CYRILLIC
11838     printf(" Cyrillic (Russian, Ukrainian, etc) character-set translation\n");
11839     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11840 #endif /* CYRILLIC */
11841 #ifdef GREEK
11842     printf(" Greek character-set translation\n");
11843     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11844 #endif /* GREEK */
11845 #ifdef HEBREW
11846     printf(" Hebrew character-set translation\n");
11847     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11848 #endif /* HEBREW */
11849 #ifdef KANJI
11850     printf(" Japanese character-set translation\n");
11851     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11852 #endif /* KANJI */
11853 #ifdef UNICODE
11854     printf(" Unicode character-set translation\n");
11855     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11856 #endif /* UNICODE */
11857 #ifdef CKOUNI
11858     if (isunicode())
11859       printf(" Unicode support for ISO-2022 Terminal Emulation\n");
11860     else
11861       printf(" Unicode translation for Terminal Character-Sets\n");
11862     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11863 #endif /* CKOUNI */
11864 #endif /* NOCSETS */
11865
11866 #ifdef NETPTY
11867     printf(" Pseudoterminal control\n");
11868     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11869 #endif /* NETPTY */
11870
11871 #ifdef CK_REDIR
11872     printf(" REDIRECT command\n");
11873     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11874 #endif /* CK_REDIR */
11875
11876 #ifdef CK_RESEND
11877     printf(" RESEND command\n");
11878     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11879 #endif /* CK_RESEND */
11880
11881 #ifndef NOXFER
11882 #ifdef CK_CURSES
11883     printf(" Fullscreen file transfer display\n");
11884     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11885 #endif /* CK_CURSES */
11886 #endif /* NOXFER */
11887
11888 #ifdef CK_SPEED
11889     printf(" Control-character unprefixing\n");
11890     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11891 #endif /* CK_SPEED */
11892
11893 #ifdef STREAMING
11894     printf(" Streaming\n");
11895     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11896 #endif /* STREAMING */
11897
11898 #ifdef CK_AUTODL
11899     printf(" Autodownload\n");
11900     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11901 #endif /* CK_AUTODL */
11902
11903 #ifdef OS2MOUSE
11904     printf(" Mouse support\n");
11905     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11906 #endif /* OS2MOUSE */
11907
11908 #ifdef CK_REXX
11909     printf(" REXX script language interface\n");
11910     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11911 #endif /* CK_REXX */
11912
11913 #ifdef IKSD
11914 #ifdef CK_LOGIN
11915     printf(" Internet Kermit Service with user login support\n");
11916 #else /* CK_LOGIN */
11917     printf(" Internet Kermit Service without user login support\n");
11918 #endif /* CK_LOGIN */
11919     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11920 #endif /* IKSD */
11921
11922     printf("\n");
11923     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11924     printf("Major optional features not included:\n");
11925     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11926
11927     if (sizeof(CK_OFF_T) <= 4) {
11928         printf(" No large files or large integers\n");
11929         if (++lines > cmd_rows - 3) {
11930             if (!askmore()) return(1); else lines = 0;
11931         }
11932     }
11933
11934 #ifdef NOXFER
11935     printf(" No file-transfer protocols\n");
11936     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11937     flag = 1;
11938 #else
11939 #ifndef CK_CURSES
11940 #ifndef MAC
11941     printf(" No fullscreen file transfer display\n");
11942     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11943     flag = 1;
11944 #endif /* MAC */
11945 #endif /* CK_CURSES */
11946
11947 #ifdef NOSERVER
11948     printf(" No server mode\n");
11949     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11950     flag = 1;
11951 #endif /* NOSERVER */
11952
11953 #ifndef CK_SPEED
11954     printf(" No control-character unprefixing\n");
11955     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11956     flag = 1;
11957 #endif /* CK_SPEED */
11958
11959 #ifndef STREAMING
11960     printf(" No streaming\n");
11961     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11962     flag = 1;
11963 #endif /* STREAMING */
11964
11965 #ifndef CK_AUTODL
11966     printf(" No autodownload\n");
11967     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11968     flag = 1;
11969 #endif /* CK_AUTODL */
11970
11971 #ifndef CK_XYZ
11972     printf(" No built-in XYZMODEM protocols\n");
11973     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11974     flag = 1;
11975 #endif /* CK_XYZ */
11976
11977 #ifdef NOFLOAT
11978     printf(" No floating-point arithmetic\n");
11979     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11980     flag = 1;
11981     printf(" No S-Expressions (LISP interpreter)\n");
11982     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11983     flag = 1;
11984 #else
11985 #ifdef NOSEXP
11986     printf(" No S-Expressions (LISP interpreter)\n");
11987     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11988     flag = 1;
11989 #endif  /* NOSEXP */
11990 #endif  /* NOFLOAT */
11991
11992 #ifdef NOTLOG
11993     printf(" No transaction log\n");
11994     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11995     flag = 1;
11996 #endif /* NOTLOG */
11997 #endif /* NOXFER */
11998
11999 #ifdef NODEBUG
12000     printf(" No debugging\n");
12001     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12002     flag = 1;
12003 #endif /* NODEBUG */
12004
12005 #ifdef NOHELP
12006     printf(" No built-in help\n");
12007     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12008     flag = 1;
12009 #endif /* NOHELP */
12010
12011 #ifdef NOLOCAL
12012     printf(" No making connections\n");
12013     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12014     flag = 1;
12015 #else
12016 #ifndef NETCONN
12017     printf(" No network support\n");
12018     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12019     flag = 1;
12020 #else /* NETCONN */
12021 #ifndef IKS_OPTION
12022     printf(" No Telnet Kermit Option\n");
12023     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12024     flag = 1;
12025 #endif /* IKS_OPTION */
12026 #endif /* NETCONN */
12027
12028 #ifdef NOSSH
12029     printf(" No Secure Shell (SSH)\n");
12030     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12031 #endif /* NOSSH */
12032 #ifndef CK_AUTHENTICATION
12033     printf(" No Kerberos(TM) authentication\n");
12034     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12035     printf(" No SRP(TM) (Secure Remote Password) protocol\n");
12036     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12037     printf(" No Secure Sockets Layer (SSL) protocol\n");
12038     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12039     printf(" No Transport Layer Security (TLS) protocol\n");
12040     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12041     printf(" No encryption\n");
12042     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12043     flag = 1;
12044 #else /* CK_AUTHENTICATION */
12045 #ifndef CK_KERBEROS
12046     printf(" No Kerberos(TM) authentication\n");
12047     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12048     flag = 1;
12049 #else /* CK_KERBEROS */
12050 #ifndef KRB4
12051     printf(" No Kerberos(TM) IV authentication\n");
12052     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12053     flag = 1;
12054 #endif /* KRB4 */
12055 #ifndef KRB5
12056     printf(" No Kerberos(TM) V authentication\n");
12057     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12058     flag = 1;
12059 #endif /* KRB5 */
12060 #endif /* CK_KERBEROS */
12061 #ifndef CK_SRP
12062     printf(" No SRP(TM) (Secure Remote Password) authentication\n");
12063     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12064     flag = 1;
12065 #endif /* CK_SRP */
12066 #ifndef CK_SSL
12067     printf(" No Secure Sockets Layer (SSL) protocol\n");
12068     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12069     printf(" No Transport Layer Security (TLS) protocol\n");
12070     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12071     flag = 1;
12072 #endif /* CK_SSL */
12073 #ifndef CK_ENCRYPTION
12074     printf(" No Telnet Encryption Option\n");
12075     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12076     flag = 1;
12077 #else /* CK_ENCRYPTION */
12078 #ifndef OS2
12079 #ifndef CK_DES
12080     printf(" No Telnet DES encryption\n");
12081     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12082     flag = 1;
12083 #endif /* CK_DES */
12084 #ifndef CK_CAST
12085     printf(" No Telnet CAST encryption\n");
12086     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12087     flag = 1;
12088 #endif /* CK_CAST */
12089
12090 #ifdef COMMENT
12091 #ifdef CK_KERBEROS
12092 #ifdef KRB5
12093 #ifndef ALLOW_KRB_3DES_ENCRYPT
12094     printf(" No Kerberos 3DES/AES Telnet Encryption\n");
12095     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12096 #endif /* ALLOW_KRB_3DES_ENCRYPT */
12097 #endif /* KRB5 */
12098 #endif /* CK_KERBEROS */
12099 #endif /* COMMENT */
12100
12101 #endif /* OS2 */
12102 #endif /* CK_ENCRYPTION */
12103 #endif /* CK_AUTHENTICATION */
12104 #ifndef CK_FORWARD_X
12105     printf(" No X Windows forwarding\n");
12106     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12107 #endif /* CK_FORWARD_X */
12108 #ifndef TN_COMPORT
12109     printf(" No Telnet Remote Com Port Control Option\n");
12110     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12111 #endif /* TN_COMPORT */
12112 #ifndef CK_SOCKS
12113     printf(" No SOCKS\n");
12114     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12115 #endif /* CK_SOCKS */
12116 #ifndef NEWFTP
12117     printf(" No built-in FTP client\n");
12118     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12119 #endif /* NEWFTP */
12120 #ifdef NOHTTP
12121     printf(" No built-in HTTP client\n");
12122     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12123 #endif /* NOHTTP */
12124
12125 #ifdef NODIAL
12126     printf(" No DIAL command\n");
12127     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12128     flag = 1;
12129 #else
12130 #ifdef MINIDIAL
12131     printf(" Support for most modem types excluded\n");
12132     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12133     flag = 1;
12134 #endif /* MINIDIAL */
12135 #endif /* NODIAL */
12136 #endif /* NOLOCAL */
12137
12138 #ifndef CK_RTSCTS
12139 #ifndef MAC
12140     printf(" No hardware flow control\n");
12141     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12142     flag = 1;
12143 #endif /* MAC */
12144 #endif /* CK_RTSCTS */
12145
12146 #ifdef NOXMIT
12147     printf(" No TRANSMIT command\n");
12148     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12149     flag = 1;
12150 #endif /* NOXMIT */
12151
12152 #ifdef NOSCRIPT
12153     printf(" No SCRIPT command\n");
12154     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12155     flag = 1;
12156 #endif /* NOSCRIPT */
12157
12158 #ifdef NOSPL
12159     printf(" No script programming features\n");
12160     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12161     flag = 1;
12162 #endif /* NOSPL */
12163
12164 #ifdef NOCSETS
12165     printf(" No character-set translation\n");
12166     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12167     flag = 1;
12168 #else
12169
12170 #ifndef LATIN2
12171     printf(" No Latin-2 character-set translation\n");
12172     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12173     flag = 1;
12174 #endif /* LATIN2 */
12175
12176 #ifdef NOGREEK
12177     printf(" No Greek character-set translation\n");
12178     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12179     flag = 1;
12180 #endif /* NOGREEK */
12181
12182 #ifdef NOHEBREW
12183     printf(" No Hebrew character-set translation\n");
12184     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12185     flag = 1;
12186 #endif /* NOHEBREW */
12187
12188 #ifdef NOUNICODE
12189     printf(" No Unicode character-set translation\n");
12190     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12191     flag = 1;
12192 #endif /* NOUNICODE */
12193
12194 #ifdef NOCYRIL
12195     printf(" No Cyrillic character-set translation\n");
12196     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12197     flag = 1;
12198 #endif /* NOCYRIL */
12199
12200 #ifndef KANJI
12201     printf(" No Kanji character-set translation\n");
12202     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12203     flag = 1;
12204 #endif /* KANJI */
12205 #endif /* NOCSETS */
12206
12207 #ifdef NOCMDL
12208     printf(" No command-line arguments\n");
12209     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12210     flag = 1;
12211 #endif /* NOCMDL */
12212
12213 #ifdef NOPUSH
12214     printf(" No escape to system\n");
12215     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12216     flag = 1;
12217 #endif /* NOPUSH */
12218
12219 #ifdef NOJC
12220 #ifdef UNIX
12221     printf(" No UNIX job control\n");
12222     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12223     flag = 1;
12224 #endif /* UNIX */
12225 #endif /* NOJC */
12226
12227 #ifdef NOSETKEY
12228     printf(" No SET KEY command\n");
12229     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12230     flag = 1;
12231 #endif /* NOSETKEY */
12232
12233 #ifndef CK_REDIR
12234     printf(" No REDIRECT or PIPE command\n");
12235     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12236     flag = 1;
12237 #endif /* CK_REDIR */
12238
12239 #ifdef UNIX
12240 #ifndef NETPTY
12241     printf(" No pseudoterminal control\n");
12242     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12243     flag = 1;
12244 #endif /* NETPTY */
12245 #endif /* UNIX */
12246
12247 #ifndef CK_RESEND
12248     printf(" No RESEND command\n");
12249     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12250     flag = 1;
12251 #endif /* CK_RESEND */
12252
12253 #ifdef OS2
12254 #ifdef __32BIT__
12255 #ifndef OS2MOUSE
12256     printf(" No Mouse support\n");
12257     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12258     flag = 1;
12259 #endif /* __32BIT__ */
12260 #endif /* OS2 */
12261 #endif /* OS2MOUSE */
12262
12263 #ifdef OS2
12264 #ifndef NT
12265 #ifndef CK_REXX
12266     printf(" No REXX script language interface\n");
12267     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12268     flag = 1;
12269 #endif /* CK_REXX */
12270 #endif /* NT */
12271 #endif /* OS2 */
12272
12273 #ifndef IKSD
12274     printf(" No Internet Kermit Service\n");
12275     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12276     flag = 1;
12277 #endif /* IKSD */
12278
12279     if (flag == 0) {
12280         printf(" None\n");
12281         if (++lines > cmd_rows - 3)
12282           { if (!askmore()) return(1); else lines = 0; }
12283     }
12284     printf("\n");
12285     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12286
12287 #ifdef CK_UTSNAME
12288     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12289     printf("Host info:\n");
12290     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12291     printf(" Machine:    %s\n",unm_mch[0] ? unm_mch : "(unknown)");
12292     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12293     printf(" Model:      %s\n",unm_mod[0] ? unm_mod : "(unknown)");
12294     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12295     printf(" OS:         %s\n",unm_nam[0] ? unm_nam : "(unknown)");
12296     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12297     printf(" OS Release: %s\n",unm_rel[0] ? unm_rel : "(unknown)");
12298     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12299     printf(" OS Version: %s\n",unm_ver[0] ? unm_ver : "(unknown)");
12300     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12301     printf("\n");
12302     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12303 #endif /* CK_UTSNAME */
12304
12305 /*
12306   Print compile-time (-D) options, as well as C preprocessor
12307   predefined symbols that might affect us...
12308 */
12309 #ifdef KTARGET
12310     {
12311         char * s;                       /* Makefile target */
12312         s = KTARGET;
12313         if (!s) s = "";
12314         if (!*s) s = "(unknown)";
12315         printf("\n");
12316         if (++lines > cmd_rows - 3) {
12317             if (!askmore()) return(1); else lines = 0;
12318         }
12319         printf("Target: %s\n", s);
12320         if (++lines > cmd_rows - 3) {
12321             if (!askmore()) return(1); else lines = 0;
12322         }
12323     }
12324 #endif /* KTARGET */
12325
12326 #ifdef __VERSION__
12327 #ifdef __GNUC__
12328     printf("GCC version: %s\n", __VERSION__);
12329 #else
12330     printf("Compiler version: %s\n", __VERSION__);
12331 #endif /* __GNUC__ */
12332     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12333 #endif /* __VERSION__ */
12334
12335 #ifdef __DATE__                         /* GNU and other ANSI */
12336 #ifdef __TIME__
12337     printf("Compiled %s %s, options:\n", __DATE__, __TIME__);
12338 #else
12339     printf("Compiled %s, options:\n", __DATE__);
12340 #endif /* __TIME__ */
12341 #else /* !__DATE__ */
12342     printf("Compiler options:\n");
12343 #endif /* __DATE__ */
12344     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12345
12346     for (i = 0; i < noptlist; i++)      /* Print sorted option list */
12347       if (!prtopt(&lines,optlist[i]))
12348         return(0);
12349
12350     if (!prtopt(&lines,"")) return(0);  /* Start a new section */
12351
12352 /* Sizes of data types */
12353
12354     ckmakmsg(line,
12355              LINBUFSIZ,
12356              "byte order: ",
12357              byteorder ? "little" : "big",
12358              " endian",
12359              NULL
12360              );
12361     {
12362 /* Whether to use %d or %ld with sizeof is a portability issue, so... */
12363         int size = 0;
12364
12365         if (!prtopt(&lines,line)) return(0);
12366         if (!prtopt(&lines,"")) return(0);  /* Start a new section */
12367
12368         size = (int)sizeof(int);
12369         sprintf(line,"sizeofs: int=%d",size); /* SAFE */
12370         if (!prtopt(&lines,line)) return(0);
12371
12372         size = (int)sizeof(long);
12373         sprintf(line,"long=%d",size); /* SAFE */
12374         if (!prtopt(&lines,line)) return(0);
12375
12376 #ifndef OS2
12377         /* Windows doesn't have off_t */
12378         size = (int)sizeof(off_t);
12379         sprintf(line,"off_t=%d",size); /* SAFE */
12380         if (!prtopt(&lines,line)) return(0);
12381 #endif /* OS2 */
12382
12383         size = (int)sizeof(CK_OFF_T);
12384         sprintf(line,"CK_OFF_T=%d",size); /* SAFE */
12385         if (!prtopt(&lines,line)) return(0);
12386
12387 #ifdef BIGBUFOK
12388         size = (int)sizeof(size_t);
12389         sprintf(line,"size_t=%d",size); /* SAFE */
12390         if (!prtopt(&lines,line)) return(0);
12391 #endif /* BIGBUFOK */
12392
12393         size = (int)sizeof(short);
12394         sprintf(line,"short=%d",size); /* SAFE */
12395         if (!prtopt(&lines,line)) return(0);
12396
12397         size = (int)sizeof(char);
12398         sprintf(line,"char=%d",size); /* SAFE */
12399         if (!prtopt(&lines,line)) return(0);
12400
12401         size = (int)sizeof(char *);
12402         sprintf(line,"char*=%d",size); /* SAFE */
12403         if (!prtopt(&lines,line)) return(0);
12404
12405         size = (int)sizeof(float);
12406         sprintf(line,"float=%d",size); /* SAFE */
12407         if (!prtopt(&lines,line)) return(0);
12408
12409         size = (int)sizeof(double);
12410         sprintf(line,"double=%d",size); /* SAFE */
12411         if (!prtopt(&lines,line)) return(0);
12412     }
12413
12414 #ifdef FNFLOAT
12415     if (!prtopt(&lines,"")) return(0);  /* Start a new section */
12416     if (!prtopt(&lines,"floating-point:")) return(0);
12417     sprintf(line,"precision=%d",fp_digits); /* SAFE */
12418     if (!prtopt(&lines,line)) return(0);
12419     sprintf(line,"rounding=%d",fp_rounding); /* SAFE */
12420     if (!prtopt(&lines,line)) return(0);
12421 #endif /* FNFLOAT */
12422
12423     prtopt(&lines,"");
12424     return(0);
12425 }
12426 #endif /* NOSHOW */
12427 #endif /* NOICP */