makefile patch
[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++;
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) {           /* Check for separator */
8732             s2 = ckstrchr(sep,*p);
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;
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 = "-1";
8758     if (!r) r = "-1";
8759
8760     e[0] = q;
8761     e[1] = r;
8762
8763     debug(F000,"boundspair c","",c);
8764     debug(F110,"boundspair q",q,0);
8765     debug(F110,"boundspair r",r,0);
8766
8767     for (i = 0; i < 2 && e[i]; i++) {
8768         y = 255;                        /* Expand variables, etc. */
8769         s = buf;
8770         zzstring(e[i],&s,&y);
8771         s = evalx(buf);                 /* Evaluate it arithmetically */
8772         if (s) if (*s)
8773           ckstrncpy(buf,s,256);
8774         if (!chknum(buf)) {             /* Did we get a number? */
8775             debug(F110,"boundspair element not numeric",buf,0);
8776             makestr(&tmp,NULL);         /* No, fail. */
8777             return(-1);
8778         }
8779         range[i] = atoi(buf);
8780     }
8781     makestr(&tmp,NULL);                 /* Free temporary poked string */
8782     *lo = range[0];                     /* Return what we got */
8783     *hi = range[1];
8784     *zz = c;
8785     debug(F101,"boundspair lo","",*lo);
8786     debug(F101,"boundspair hi","",*hi);
8787     return(0);
8788 }
8789
8790 /*  A R R A Y B O U N D S  --  Parse array segment notation \&a[n:m]  */
8791
8792 /*
8793   Call with s = array reference, plus two pointers to ints.
8794   Returns -1 on error, or array index, with the two ints set as follows:
8795    \&a[]     -1, -1
8796    \&a[3]     3, -1
8797    \&a[3:17]  3, 17
8798   The array need not be declared -- this routine is just for parsing.
8799 */
8800 int
8801 arraybounds(s,lo,hi) char * s; int * lo, * hi; {
8802     int i, x, y, range[2];
8803     char zz, buf[256], * p, * q;
8804     char * tmp = NULL;
8805
8806     *lo = -1;                           /* Default bounds */
8807     *hi = -1;
8808
8809     if (!s) s = "";                     /* Defense de null args */
8810     if (!*s)
8811       return(-1);
8812
8813     x = xarray(s);                      /* Check basic structure */
8814     debug(F111,"arraybounds xarray",s,x);
8815     if (x < 0)                          /* Not OK, fail. */
8816       return(-1);
8817     y = boundspair(s,":",lo,hi,&zz);
8818     debug(F111,"arraybounds boundspair",s,y);
8819     debug(F101,"arraybounds lo","",*lo);
8820     debug(F101,"arraybounds hi","",*hi);
8821     if (y < 0)                          /* Get bounds */
8822       return(-1);
8823     return(x);
8824 }
8825
8826 /*  A R R A Y N A M  --  Parse an array name  */
8827
8828 /*
8829   Call with pointer to string that starts with the array reference.
8830   String may begin with either \& or just &.
8831   On success,
8832     Returns letter ID (always lowercase) in argument c,
8833       which can also be accent grave (` = 96; '@' is converted to grave);
8834     Dimension or subscript in argument n;
8835     IMPORTANT: These arguments must be provided by the caller as addresses
8836     of ints (not chars), for example:
8837       char *s; int x, y;
8838       arraynam(s,&x,&y);
8839   On failure, returns a negative number, with args n and c set to zero.
8840 */
8841 int
8842 arraynam(ss,c,n) char *ss; int *c; int *n; {
8843     int i, y, pp, len;
8844     char x;
8845     char *s, *p, *sx, *vnp;
8846     /* On stack to allow for recursive calls... */
8847     char vnbuf[ARRAYREFLEN+1];          /* Entire array reference */
8848     char ssbuf[ARRAYREFLEN+1];          /* Subscript in "plain text" */
8849     char sxbuf[16];                     /* Evaluated subscript */
8850
8851     *c = *n = 0;                        /* Initialize return values */
8852     len = strlen(ss);
8853     for (pp = 0,i = 0; i < len; i++) {          /* Check length */
8854         if (ss[i] == '[') {
8855             pp++;
8856         } else if (ss[i] == ']') {
8857             if (--pp == 0)
8858               break;
8859         }
8860     }
8861     if (i > ARRAYREFLEN) {
8862         printf("?Array reference too long - %s\n",ss);
8863         return(-9);
8864     }
8865     ckstrncpy(vnbuf,ss,ARRAYREFLEN);
8866     vnp = vnbuf;
8867     if (vnbuf[0] == CMDQ && vnbuf[1] == '&') vnp++;
8868     if (*vnp != '&') {
8869         printf("?Not an array - %s\n",vnbuf);
8870         return(-9);
8871     }
8872     x = *(vnp + 1);                     /* Fold case of array name */
8873
8874     /* We don't use isupper & tolower here on purpose because these */
8875     /* would produce undesired effects with accented letters. */
8876     if (x > 63 && x < 91) x  = *(vnp + 1) = (char) (x + 32);
8877     if ((x < ARRAYBASE) || (x > 122) || (*(vnp+2) != '[')) {
8878         if (msgflg) {
8879             printf("?Invalid format for array name - %s\n",vnbuf);
8880             return(-9);
8881         } else
8882           return(-2);
8883     }
8884     *c = x;                             /* Return the array name */
8885     s = vnp+3;                          /* Get dimension */
8886     p = ssbuf;
8887     pp = 1;                             /* Bracket counter */
8888     for (i = 0; i < ARRAYREFLEN && *s != NUL; i++) { /* Copy up to ] */
8889         if (*s == '[') pp++;
8890         if (*s == ']' && --pp == 0) break;
8891         *p++ = *s++;
8892     }
8893     if (*s != ']') {
8894         printf("?No closing bracket on array dimension - %s\n",vnbuf);
8895         return(-9);
8896     }
8897     p--;                                /* Trim whitespace from end */
8898     while (*p == SP || *p == HT)
8899       p--;
8900     p++;
8901     *p = NUL;                           /* Terminate subscript with null */
8902     p = ssbuf;                          /* Point to beginning of subscript */
8903     while (*p == SP || *p == HT)        /* Trim whitespace from beginning */
8904       p++;
8905     sx = sxbuf;                         /* Where to put expanded subscript */
8906     y = 16;
8907     {
8908         /* Even if VARIABLE-EVALUATION SIMPLE use RECURSIVE for subscripts */
8909         /* NOTE: This is vulnerable to SIGINT and whatnot... */
8910         int tmp = vareval;              /* Save VARIABLE-EVALUATION setting */
8911         vareval = 1;                    /* Force it to RECURSIVE */
8912         zzstring(p,&sx,&y);             /* Convert variables, etc. */
8913         vareval = tmp;                  /* Restore VARIABLE-EVALUATION */
8914     }
8915     sx = sxbuf;
8916     while (*sx == SP) sx++;
8917     /* debug(F110,"arraynam sx","",sx); */
8918     if (!*sx) {                         /* Empty brackets... */
8919         *n = -17;                       /* (Secret code :-) */
8920         return(-2);
8921     }
8922     p = evala(sx);                      /* Run it thru \fneval()... */
8923     if (p) if (*p) ckstrncpy(sxbuf,p,16); /* We know it has to be a number. */
8924
8925     if (!chknum(sxbuf)) {               /* Make sure it's all digits */
8926         if (msgflg) {
8927             printf("?Array dimension or subscript missing or not numeric\n");
8928             return(-9);
8929         } else
8930           return(-2);
8931     }
8932     if ((y = atoi(sxbuf)) < 0) {
8933         if (cmflgs == 0) printf("\n");
8934         if (msgflg) {
8935             printf("?Array dimension or subscript not positive or zero\n");
8936             return(-9);
8937         } else
8938           return(-2);
8939     }
8940     *n = y;                             /* Return the subscript or dimension */
8941     return(0);
8942 }
8943
8944 /* chkarray returns 0 or greater if array exists, negative otherwise */
8945
8946 int
8947 chkarray(a,i) int a, i; {               /* Check if array is declared */
8948     int x;                              /* and if subscript is in range */
8949     if (a == 64) a = 96;                /* Convert atsign to grave accent */
8950     x = a - ARRAYBASE;                  /* Values must be in range 95-122 */
8951 #ifdef COMMENT
8952     if (x == 0 && maclvl < 0)           /* Macro arg vector but no macro */
8953       return(0);
8954 #endif /* COMMENT */
8955     if (x < 0 || x > 'z' - ARRAYBASE)   /* Not in range */
8956       return(-2);
8957     if (a_ptr[x] == NULL) return(-1);   /* Not declared */
8958     if (i > a_dim[x]) return(-2);       /* Declared but out of range. */
8959     return(a_dim[x]);                   /* All ok, return dimension */
8960 }
8961
8962 #ifdef COMMENT                          /* This isn't used. */
8963 char *
8964 arrayval(a,i) int a, i; {               /* Return value of \&a[i] */
8965     int x; char **p;                    /* (possibly NULL) */
8966     if (a == 64) a = 96;                /* Convert atsign to grave accent */
8967     x = a - ARRAYBASE;                  /* Values must be in range 95-122 */
8968     if (x < 0 || x > 27) return(NULL);  /* Not in range */
8969     if ((x > 0) && (p = a_ptr[x]) == NULL) /* Array not declared */
8970       return(NULL);
8971     if (i > a_dim[x])                   /* Subscript out of range. */
8972       return(NULL);
8973     return(p[i]);                       /* All ok, return pointer to value. */
8974 }
8975 #endif /* COMMENT */
8976
8977 /*
8978   pusharray() is called when an array name is included in a LOCAL statement.
8979   It moves the pointers from the global definition to the stack, and removes
8980   the global definition.  Later, if the same array is declared in the local
8981   context, it occupies the global definition in the normal way.  But when
8982   popclvl() is called, it replaces the global definition with the one saved
8983   here.  The "secret code" is used to indicate to popclv() that it should
8984   remove the global array when popping through this level -- otherwise if a
8985   local array were declared that had no counterpart at any higher level, it
8986   would never be deleted.  This allows Algol-like inheritance to work both
8987   on the way down and on the way back up.
8988 */
8989 int
8990 pusharray(x,z) int x, z; {
8991     int y;
8992     debug(F000,"pusharray x","",x);
8993     debug(F101,"pusharray z","",z);
8994     y = chkarray(x,z);
8995     debug(F101,"pusharray y","",y);
8996     x -= ARRAYBASE;                     /* Convert name letter to index. */
8997     if (x < 0 || x > 27)
8998       return(-1);
8999     if (y < 0) {
9000         aa_ptr[cmdlvl][x] = (char **) NULL;
9001         aa_dim[cmdlvl][x] = -23;        /* Secret code (see popclvl()) */
9002     } else {
9003         aa_ptr[cmdlvl][x] = a_ptr[x];
9004         aa_dim[cmdlvl][x] = y;
9005     }
9006     a_ptr[x] = (char **) NULL;
9007     a_dim[x] = 0;
9008     return(0);
9009 }
9010
9011 /*  P A R S E V A R  --  Parse a variable name or array reference.  */
9012 /*
9013  Call with:
9014    s  = pointer to candidate variable name or array reference.
9015    *c = address of integer in which to return variable ID.
9016    *i = address of integer in which to return array subscript.
9017  Returns:
9018    -2:  syntax error in variable name or array reference.
9019     1:  successful parse of a simple variable, with ID in c.
9020     2:  successful parse of an array reference, w/ID in c and subscript in i.
9021 */
9022 int
9023 parsevar(s,c,i) char *s; int *c, *i; {
9024     char *p;
9025     int x,y,z;
9026
9027     p = s;
9028     if (*s == CMDQ) s++;                /* Point after backslash */
9029
9030     if (*s != '%' && *s != '&') {       /* Make sure it's % or & */
9031         printf("?Not a variable name - %s\n",p);
9032         return(-9);
9033     }
9034     if ((int)strlen(s) < 2) {
9035         printf("?Incomplete variable name - %s\n",p);
9036         return(-9);
9037     }
9038     if (*s == '%' && *(s+2) != '\0') {
9039         printf("?Only one character after '%%' in variable name, please\n");
9040         return(-9);
9041     }
9042     if (*s == '&' && *(s+2) != '[') {
9043         printf("?Array subscript expected - %s\n",p);
9044         return(-9);
9045     }
9046     if (*s == '%') {                    /* Simple variable. */
9047         y = *(s+1);                     /* Get variable ID letter/char */
9048         if (isupper(y)) y -= ('a'-'A'); /* Convert upper to lower case */
9049         *c = y;                         /* Set the return values. */
9050         *i = -1;                        /* No array subscript. */
9051         return(1);                      /* Return 1 = simple variable */
9052     }
9053     if (*s == '&') {                    /* Array reference. */
9054         y = arraynam(s,&x,&z);          /* Go parse it. */
9055         debug(F101,"parsevar arraynam","",y);
9056         if ((y) < 0) {
9057             if (y == -2)
9058               return(pusharray(x,z));
9059             if (y != -9)
9060               printf("?Invalid array reference - %s\n",p);
9061             return(-9);
9062         }
9063         if (chkarray(x,z) < 0) {        /* Check if declared, etc. */
9064             printf("?Array not declared or subscript out of range\n");
9065             return(-9);
9066         }
9067         *c = x;                         /* Return array letter */
9068         *i = z;                         /* and subscript. */
9069         return(2);
9070     }
9071     return(-2);                         /* None of the above. */
9072 }
9073
9074
9075 #define VALN 32
9076
9077 /* Get the numeric value of a variable */
9078 /*
9079   Call with pointer to variable name, pointer to int for return value.
9080   Returns:
9081     0 on success with second arg containing the value.
9082    -1 on failure (bad variable syntax, variable not defined or not numeric).
9083 */
9084 int
9085 varval(s,v) char *s; CK_OFF_T *v; {
9086     char valbuf[VALN+1];                /* s is pointer to variable name */
9087     char name[256];
9088     char *p;
9089     int y;
9090
9091     if (*s != CMDQ) {                   /* Handle macro names too */
9092         ckmakmsg(name,256,"\\m(",s,")",NULL);
9093         s = name;
9094     }
9095     p = valbuf;                         /* Expand variable into valbuf. */
9096     y = VALN;
9097     if (zzstring(s,&p,&y) < 0) return(-1);
9098     p = valbuf;                         /* Make sure value is numeric  */
9099     if (!*p) {                          /* Be nice -- let an undefined */
9100         valbuf[0] = '0';                /* variable be treated as 0.   */
9101         valbuf[1] = NUL;
9102     }
9103     if (chknum(p)) {                    /* Convert numeric string to int */
9104         *v = ckatofs(p);                /* OK */
9105     } else {                            /* Not OK */
9106         p = evala(p);                   /* Maybe it's an expression */
9107         if (!chknum(p))                 /* Did it evaluate? */
9108           return(-1);                   /* No, failure. */
9109         else                            /* Yes, */
9110           *v = ckatofs(p);              /* success */
9111     }
9112     return(0);
9113 }
9114
9115 /* Increment or decrement a variable */
9116 /* Returns -1 on failure, 0 on success */
9117
9118 int
9119 incvar(s,x,z) char *s; CK_OFF_T x; int z; {  /* Increment a numeric variable */
9120     CK_OFF_T n;                         /* s is pointer to variable name */
9121                                         /* x is amount to increment by */
9122                                         /* z != 0 means add */
9123                                         /* z = 0 means subtract */
9124     if (varval(s,&n) < 0)               /* Convert numeric string to int */
9125       return(-1);
9126     if (z)                              /* Increment it by the given amount */
9127       n += x;
9128     else                                /* or decrement as requested. */
9129       n -= x;
9130     addmac(s,ckfstoa(n));               /* Replace old variable */
9131     return(0);
9132 }
9133
9134 /* D O D O  --  Do a macro */
9135
9136 /*
9137   Call with x = macro table index, s = pointer to arguments.
9138   Returns 0 on failure, 1 on success.
9139 */
9140
9141 int
9142 dodo(x,s,flags) int x; char *s; int flags; {
9143     int y;
9144     extern int tra_asg, tra_cmd; int tra_tmp;
9145 #ifndef NOLOCAL
9146 #ifdef OS2
9147     extern int term_io;
9148     int term_io_sav = term_io;
9149 #endif /* OS2 */
9150 #endif /* NOLOCAL */
9151
9152     if (x < 0)                          /* It can happen! */
9153       return(-1);
9154
9155     tra_tmp = tra_asg;
9156
9157     if (++maclvl >= MACLEVEL) {         /* Make sure we have storage */
9158         debug(F101,"dodo maclvl too deep","",maclvl);
9159         --maclvl;
9160         printf("Macros nested too deeply\n");
9161         return(0);
9162     }
9163     macp[maclvl] = mactab[x].mval;      /* Point to the macro body */
9164     macx[maclvl] = mactab[x].mval;      /* Remember where the beginning is */
9165
9166 #ifdef COMMENT
9167     makestr(&(m_line[maclvl]),s);       /* Entire arg string for "\%*" */
9168 #endif /* COMMENT */
9169
9170     cmdlvl++;                           /* Entering a new command level */
9171     if (cmdlvl >= CMDSTKL) {            /* Too many macros + TAKE files? */
9172         debug(F101,"dodo cmdlvl too deep","",cmdlvl);
9173         cmdlvl--;
9174         printf("?TAKE files and DO commands nested too deeply\n");
9175         return(0);
9176     }
9177 #ifdef DEBUG
9178     if (deblog) {
9179         debug(F111,"CMD +M",mactab[x].kwd,cmdlvl);
9180         debug(F010,"CMD ->",s,0);
9181     }
9182 #endif /* DEBUG */
9183
9184 #ifdef VMS
9185     conres();                           /* So Ctrl-C, etc, will work. */
9186 #endif /* VMS */
9187 #ifndef NOLOCAL
9188 #ifdef OS2
9189     term_io = 0;                        /* Disable terminal emulator I/O */
9190 #endif /* OS2 */
9191 #endif /* NOLOCAL */
9192     ifcmd[cmdlvl] = 0;
9193     iftest[cmdlvl] = 0;
9194     count[cmdlvl] = count[cmdlvl-1];    /* Inherit COUNT from previous level */
9195     intime[cmdlvl] = intime[cmdlvl-1];  /* Inherit previous INPUT TIMEOUT */
9196     inpcas[cmdlvl] = inpcas[cmdlvl-1];  /*   and INPUT CASE */
9197     takerr[cmdlvl] = takerr[cmdlvl-1];  /*   and TAKE ERROR */
9198     merror[cmdlvl] = merror[cmdlvl-1];  /*   and MACRO ERROR */
9199     xquiet[cmdlvl] = quiet;
9200     xvarev[cmdlvl] = vareval;
9201     xcmdsrc = CMD_MD;
9202     cmdstk[cmdlvl].src = CMD_MD;        /* Say we're in a macro */
9203     cmdstk[cmdlvl].lvl = maclvl;        /* and remember the macro level */
9204     cmdstk[cmdlvl].ccflgs = flags & ~CF_IMAC; /* Set flags */
9205
9206     /* Initialize return value except in FOR, WHILE, IF, and SWITCH macros */
9207
9208     if (!(flags & CF_IMAC) && mrval[maclvl]) {
9209         free(mrval[maclvl]);
9210         mrval[maclvl] = NULL;
9211     }
9212
9213     /* Clear old %0..%9 arguments */
9214
9215     addmac("%0",mactab[x].kwd);         /* Define %0 = name of macro */
9216     makestr(&(m_xarg[maclvl][0]),mactab[x].kwd);
9217     varnam[0] = '%';
9218     varnam[2] = '\0';
9219     tra_asg = 0;
9220     for (y = 1; y < 10; y++) {          /* Clear args %1..%9 */
9221         if (m_arg[maclvl][y]) {         /* Don't call delmac() unless */
9222             varnam[1] = (char) (y + '0'); /* we have to... */
9223             delmac(varnam,0);
9224         }
9225     }
9226     tra_asg = tra_tmp;
9227
9228 /* Assign the new args one word per arg, allowing braces to group words */
9229
9230     xwords(s,MAXARGLIST,NULL,0);
9231
9232 #ifndef NOLOCAL
9233 #ifdef OS2
9234     term_io = term_io_sav;
9235 #endif /* OS2 */
9236 #endif /* NOLOCAL */
9237     if (tra_cmd)
9238       printf("[%d] +M: \"%s\"\n",cmdlvl,mactab[x].kwd);
9239     return(1);
9240 }
9241
9242 /* Insert "literal" quote around each comma-separated command to prevent */
9243 /* its premature expansion.  Only do this if object command is surrounded */
9244 /* by braces. */
9245
9246 static char* flit = "\\flit(";
9247
9248 int
9249 litcmd(src,dest,n) char **src, **dest; int n; {
9250     int bc = 0, pp = 0;
9251     char c, *s, *lp, *ss;
9252
9253     s = *src;
9254     lp = *dest;
9255
9256     debug(F010,"litcmd",s,0);
9257
9258     while (*s == SP) s++;               /* Strip extra leading spaces */
9259
9260     if (*s == '{') {                    /* Starts with brace */
9261         pp = 0;                         /* Paren counter */
9262         bc = 1;                         /* Count leading brace */
9263         *lp++ = *s++;                   /* Copy it */
9264         if (--n < 1) return(-1);        /* Check space */
9265         while (*s == SP) s++;           /* Strip interior leading spaces */
9266         ss = flit;                      /* Point to "\flit(" */
9267         while ((*lp++ = *ss++))         /* Copy it */
9268           if (--n < 1)                  /* and check space */
9269             return(-1);
9270         lp--;                           /* Back up over null */
9271
9272         while (*s) {                    /* Go thru rest of text */
9273             c = *s;
9274             if (c == '{') bc++;         /* Count brackets */
9275             if (c == '(') pp++;         /* and parens */
9276             if (c == ')') {             /* Right parenthesis. */
9277                 pp--;                   /* Count it. */
9278                 if (pp < 0) {           /* An unbalanced right paren... */
9279 #ifdef COMMENT
9280 /*
9281   The problem here is that "\{" appears to be a quoted brace and therefore
9282   isn't counted; then the "}" matches an earlier opening brace, causing
9283   (e.g.) truncation of macros by getncm().
9284 */
9285                     if (n < 5)          /* Out of space in dest buffer? */
9286                       return(-1);       /* If so, give up. */
9287                     *lp++ = CMDQ;       /* Must be quoted to prevent */
9288                     *lp++ = '}';        /* premature termination of */
9289                     *lp++ = '4';        /* \flit(...) */
9290                     *lp++ = '1';
9291                     *lp++ = '}';
9292                     n -= 5;
9293 #else
9294 /* Here we rely on the fact the \nnn never takes more than 3 digits */
9295                     if (n < 4)          /* Out of space in dest buffer? */
9296                       return(-1);       /* If so, give up. */
9297                     *lp++ = CMDQ;       /* Must be quoted to prevent */
9298                     *lp++ = '0';        /* premature termination of */
9299                     *lp++ = '4';        /* \flit(...) */
9300                     *lp++ = '1';
9301                     n -= 4;
9302 #endif /* COMMENT */
9303                     pp++;               /* Uncount it. */
9304                     s++;
9305                     continue;
9306                 }
9307             }
9308             if (c == '}') {             /* Closing brace. */
9309                 if (--bc == 0) {        /* Final one? */
9310                     *lp++ = ')';        /* Add closing paren for "\flit()" */
9311                     if (--n < 1) return(-1);
9312                     *lp++ = c;
9313                     if (--n < 1) return(-1);
9314                     s++;
9315                     break;
9316                 }
9317             }
9318             *lp++ = c;                  /* General case */
9319             if (--n < 1) return(-1);
9320             s++;
9321         }
9322         *lp = NUL;
9323     } else {                            /* No brackets around, */
9324         while ((*lp++ = *s++))          /* just copy. */
9325           if (--n < 1)
9326             return(-1);
9327         lp--;
9328     }
9329     *src = s;                           /* Return updated source */
9330     *dest = lp;                         /* and destination pointers */
9331     if (bc)                             /* Fail if braces unbalanced */
9332       return(-1);
9333     else                                /* Otherwise succeed. */
9334       return(0);
9335 }
9336 #endif /* NOSPL */
9337
9338 /* Functions moved here from ckuusr.c to even out the module sizes... */
9339
9340 /*
9341   Breaks up string s -- IN PLACE! -- into a list of up to max words.
9342   Pointers to each word go into the array list[].
9343   max is the maximum number of words (pointers).
9344   If list is NULL, then they are added to the macro table.
9345   flag = 0 means the last field is to be one word, like all the other fields,
9346          so anything after it is discarded.
9347   flag = 1 means the last field extends to the end of the string, even if
9348          there are lots of words left, so the last field contains the
9349          remainder of the string.
9350 */
9351 VOID
9352 xwords(s,max,list,flag) char *s; int max; char *list[]; int flag; {
9353     char *p;
9354     int b, i, k, q, y, z;
9355 #ifndef NOSPL
9356     int macro;
9357     macro = (list == NULL);
9358     debug(F010,"xwords",s,0);
9359 #endif /* NOSPL */
9360
9361 #ifdef XWORDSDEBUG
9362     printf("XWORDS string=%s\n",s);
9363     printf("XWORDS max=%d\n",max);
9364 #endif /* XWORDSDEBUG */
9365     p = s;                              /* Pointer to beginning of string */
9366     q = 0;                              /* Flag for doublequote removal */
9367     b = 0;                              /* Flag for outer brace removal */
9368     k = 0;                              /* Flag for in-word */
9369     y = 0;                              /* Brace nesting level */
9370     z = 0;                              /* "Word" counter, 0 thru max */
9371
9372     if (list)
9373       for (i = 0; i <= max; i++)        /* Initialize pointers */
9374         list[i] = NULL;
9375
9376     if (flag) max--;
9377
9378     while (1) {                         /* Go thru word list */
9379         if (!s || (*s == '\0')) {       /* No more characters? */
9380             if (k != 0) {               /* Was I in a word? */
9381                 if (z == max) break;    /* Yes, only go up to max. */
9382                 z++;                    /* Count this word. */
9383 #ifdef XWORDSDEBUG
9384                 printf("1 z++ = %d\n", z);
9385 #endif /* XWORDSDEBUG */
9386 #ifndef NOSPL
9387                 if (macro) {            /* Doing macro args */
9388                     if (z < 10) {
9389                         varnam[1] = (char) (z + '0'); /* Assign last arg */
9390                         addmac(varnam,p);
9391                     }
9392                     if (z <= max) {
9393 #ifdef COMMENT
9394                         if (maclvl < 0)
9395                           addmac(varnam,p);
9396                         else
9397 #endif /* COMMENT */
9398                           makestr(&(m_xarg[maclvl][z]),p);
9399                     }
9400                 } else {                /* Not doing macro args */
9401 #endif /* NOSPL */
9402                     list[z] = p;        /* Assign pointer. */
9403 #ifdef XWORDSDEBUG
9404                     printf("[1]LIST[%d]=\"%s\"\n",z,list[z]);
9405 #endif /* XWORDSDEBUG */
9406 #ifndef NOSPL
9407                 }
9408 #endif /* NOSPL */
9409                 break;                  /* And get out. */
9410             } else break;               /* Was not in a word */
9411         }
9412         if (k == 0 && (*s == SP || *s == HT)) { /* Eat leading blanks */
9413             s++;
9414             continue;
9415         } else if (q == 0 && *s == '{') { /* An opening brace */
9416             if (k == 0 && y == 0) {     /* If leading brace */
9417                 p = s+1;                /* point past it */
9418                 b = 1;                  /* and flag that we did this */
9419             }
9420             k = 1;                      /* Flag that we're in a word */
9421             y++;                        /* Count the brace. */
9422         } else if (q == 0 && *s == '}') { /* A closing brace. */
9423             y--;                        /* Count it. */
9424             if (y <= 0 && b != 0) {     /* If it matches the leading brace */
9425                 char c;
9426                 c = *(s+1);
9427                 if (!c || c == SP || c == HT) { /* at EOL or followed by SP */
9428                     *s = SP;            /* change it to a space */
9429                     b = 0;              /* and we're not in braces any more */
9430                 }
9431             }
9432 #ifdef DOUBLEQUOTING
9433         /* Opening doublequote */
9434         } else if (k == 0 && b == 0 && *s == '"' && dblquo) {
9435             y++;
9436             p = s+1;                    /* point past it */
9437             q = 1;                      /* and flag that we did this */
9438             k = 1;                      /* Flag that we're in a word */
9439         /* Closing double quote */
9440         } else if (q > 0 && k > 0 && b == 0 && *s == '"' && dblquo) {
9441             char c;
9442             c = *(s+1);
9443             if (!c || c == SP || c == HT) { /* at EOL or followed by SP */
9444                 y--;
9445                 *s = SP;                /* change it to a space */
9446                 q = 0;                  /* and we're not in quotes any more */
9447             }
9448 #endif /* DOUBLEQUOTING */
9449
9450         } else if (*s != SP && *s != HT) { /* Nonspace means we're in a word */
9451             if (k == 0) {               /* If we weren't in a word before, */
9452                 p = s;                  /* Mark the beginning */
9453                 if (flag && z == max) { /* Want last word to be remainder? */
9454                     z++;
9455 #ifdef XWORDSDEBUG
9456                     printf("1 z++ = %d\n", z);
9457 #endif /* XWORDSDEBUG */
9458                     list[z] = p;        /* Yes, point to it */
9459 #ifdef XWORDSDEBUG
9460                     printf("[4]LIST[%d]=\"%s\"\n",z,list[z]);
9461 #endif /* XWORDSDEBUG */
9462                     break;              /* and quit */
9463                 }
9464                 k = 1;                  /* Set in-word flag */
9465             }
9466         }
9467         /* If we're not inside a braced quantity, and we are in a word, and */
9468         /* we have hit whitespace, then we have a word. */
9469         if ((y < 1) && (k != 0) && (*s == SP || *s == HT) && !b) {
9470             if (!flag || z < max)       /* if we don't want to keep rest */
9471               *s = '\0';                /* terminate the arg with null */
9472             k = 0;                      /* say we're not in a word any more */
9473             y = 0;                      /* start braces off clean again */
9474             if (z == max) break;        /* Only go up to max. */
9475             z++;                        /* count this arg */
9476 #ifdef XWORDSDEBUG
9477             printf("1 z++ = %d\n", z);
9478 #endif /* XWORDSDEBUG */
9479
9480 #ifndef NOSPL
9481             if (macro) {
9482                 if (z < 10) {
9483                     varnam[1] = (char) (z + '0'); /* compute its name */
9484                     addmac(varnam,p);   /* add it to the macro table */
9485                 }
9486                 if (z <= max) {
9487 #ifdef COMMENT
9488                     if (maclvl < 0)
9489                       addmac(varnam,p);
9490                     else
9491 #endif /* COMMENT */
9492                       makestr(&(m_xarg[maclvl][z]),p);
9493                 }
9494             } else {
9495 #endif /* NOSPL */
9496                 list[z] = p;
9497 #ifdef XWORDSDEBUG
9498                 printf("[2]LIST[%d]=\"%s\"\n",z,list[z]);
9499 #endif /* XWORDSDEBUG */
9500 #ifndef NOSPL
9501             }
9502 #endif /* NOSPL */
9503             p = s+1;
9504         }
9505         s++;                            /* Point past this character */
9506     }
9507     if ((z == 0) && (y > 1)) {          /* Extra closing brace(s) at end */
9508         z++;
9509 #ifndef NOSPL
9510         if (macro) {
9511             if (z < 10) {
9512                 varnam[1] = z + '0';    /* compute its name */
9513                 addmac(varnam,p);       /* Add rest of line to last arg */
9514             }
9515             if (z <= max) {
9516 #ifdef COMMENT
9517                 if (maclvl < 0)
9518                   addmac(varnam,p);
9519                 else
9520 #endif /* COMMENT */
9521                   makestr(&(m_xarg[maclvl][z]),p);
9522             }
9523         } else {
9524 #endif /* NOSPL */
9525             list[z] = p;
9526 #ifdef XWORDSDEBUG
9527             printf("[3]LIST[%d]=\"%s\"\n",z,list[z]);
9528 #endif /* XWORDSDEBUG */
9529 #ifndef NOSPL
9530         }
9531 #endif /* NOSPL */
9532     }
9533 #ifndef NOSPL
9534     if (macro) {                        /* Macro */
9535         if (maclvl < 0) {
9536             a_dim[0] = z;               /* Array dimension is one less */
9537             topargc = z + 1;            /* than \v(argc) */
9538             debug(F111,"a_dim[0]","D",a_dim[0]);
9539         } else {
9540             macargc[maclvl] = z + 1;    /* Set \v(argc) variable */
9541             n_xarg[maclvl] = z + 1;     /* This is the actual number */
9542             a_ptr[0] = m_xarg[maclvl];  /* Point \&_[] at the args */
9543             a_dim[0] = z;               /* And give it this dimension */
9544             debug(F111,"a_dim[0]","E",a_dim[0]);
9545         }
9546     }
9547 #endif /* NOSPL */
9548     return;
9549 }
9550
9551 #ifndef NOSPL
9552
9553 /*  D O S H I F T  --  Do the SHIFT Command; shift macro args left by n */
9554
9555 /*  Note: at some point let's consolidate m_arg[][] and m_xarg[][]. */
9556
9557 int
9558 doshift(n) int n; {                     /* n = shift count */
9559     int i, top, level;
9560     char /* *s, *m, */ buf[6];          /* Buffer to build scalar names */
9561     char * sx = tmpbuf;
9562     int nx = TMPBUFSIZ;
9563
9564     debug(F101,"SHIFT count","",n);
9565     debug(F101,"SHIFT topargc","",topargc);
9566
9567     if (n < 1)                          /* Stay in range */
9568       return(n == 0 ? 1 : 0);
9569
9570     level = maclvl;
9571     top = (level < 0) ? topargc : macargc[level];
9572
9573     if (n >= top)
9574       n = top - 1;
9575
9576 #ifdef DEBUG
9577     if (deblog) {
9578         debug(F101,"SHIFT count 2","",n);
9579         debug(F101,"SHIFT level","",level);
9580         if (level > -1)
9581           debug(F101,"SHIFT macargc[level]","",macargc[level]);
9582     }
9583 #endif /* DEBUG */
9584
9585     buf[0] = '\\';                      /* Initialize name template */
9586     buf[1] = '%';
9587     buf[2] = NUL;
9588     buf[3] = NUL;
9589
9590     for (i = 1; i <= n; i++) {          /* Free shifted-over args */
9591         if (level < 0) {
9592             makestr(&(toparg[i]),NULL);
9593         } else {
9594             makestr(&(m_xarg[level][i]),NULL);
9595         }
9596         if (i < 10) {                   /* Is this necessary? */
9597             buf[2] = (char)(i+'0');
9598             delmac(buf,0);
9599         }
9600     }
9601     for (i = 1; i <= top-n; i++) {      /* Shift remaining args */
9602         if (level < 0) {
9603 #ifdef COMMENT
9604             toparg[i] = toparg[i+n];    /* Full vector */
9605 #else
9606             makestr(&(toparg[i]),toparg[i+n]); /* Full vector */
9607 #endif /* COMMENT */
9608             if (i < 10)                 /* Scalars... */
9609               makestr(&(g_var[i+'0']),toparg[i+n]);
9610         } else {
9611 #ifdef COMMENT
9612             m_xarg[level][i] = m_xarg[level][i+n];
9613 #else
9614             makestr(&(m_xarg[level][i]),m_xarg[level][i+n]);
9615 #endif /* COMMENT */
9616             if (i < 10) {
9617                 buf[2] = (char)(i+'0');
9618                 debug(F010,"SHIFT buf",buf,0);
9619                 addmac(buf,m_xarg[level][i+n]);
9620             }
9621         }
9622     }
9623     for (i = top-n; i <= top; i++) {    /* Clear n args from the end */
9624         if (level < 0) {
9625 #ifdef COMMENT
9626             toparg[i] = NULL;
9627 #else
9628             makestr(&(toparg[i]),NULL);
9629 #endif /* COMMENt */
9630             if (i < 10)
9631               makestr(&(g_var[i+'0']),NULL);
9632         } else {
9633 #ifdef COMMENT
9634             m_xarg[level][i] = NULL;
9635 #else
9636             makestr(&(m_xarg[level][i]),NULL);
9637 #endif /* COMMENt */
9638             if (i < 10) {
9639                 buf[2] = (char)(i+'0');
9640                 delmac(buf,0);
9641             }
9642         }
9643     }
9644     if (level > -1) {                   /* Macro args */
9645         macargc[level] -= n;            /* Adjust count */
9646         n_xarg[maclvl] = macargc[level]; /* Here too */
9647         a_dim[0] = macargc[level] - 1;  /* Adjust array dimension */
9648         debug(F111,"a_dim[0]","F",a_dim[0]);
9649         zzstring("\\fjoin(&_[],{ },1)",&sx,&nx); /* Handle \%* */
9650 #ifdef COMMENT
9651         makestr(&(m_line[level]),tmpbuf);
9652 #endif /* COMMENT */
9653     } else {                            /* Ditto for top level */
9654         topargc -= n;
9655         a_dim[0] = topargc - 1;
9656         debug(F111,"a_dim[0]","G",a_dim[0]);
9657         zzstring("\\fjoin(&_[],{ },1)",&sx,&nx);
9658 #ifdef COMMENT
9659         makestr(&topline,tmpbuf);
9660 #endif /* COMMENT */
9661     }
9662     return(1);
9663 }
9664 #endif /* NOSPL */
9665
9666 int
9667 docd(cx) int cx; {                      /* Do the CD command */
9668     int x;
9669     extern int server, srvcdmsg, cdactive;
9670     extern char * cdmsgfile[], * ckcdpath;
9671     char *s, *p;
9672 #ifdef MAC
9673     char temp[34];
9674 #endif /* MAC */
9675 #ifdef IKSDCONF
9676 extern int iksdcf;
9677 #endif /* IKSDCONF */
9678
9679 #ifndef NOFRILLS
9680     if (cx == XXBACK) {
9681         if ((x = cmcfm()) < 0)
9682         cwdf = 1;
9683         if (prevdir) {
9684             s = zgtdir();
9685             if (!zchdir(prevdir)) {
9686                 cwdf = 0;
9687                 perror(s);
9688             } else {
9689                 makestr(&prevdir,s);
9690             }
9691         }
9692         return(cwdf);
9693     }
9694 #endif /* NOFRILLS */
9695
9696     if (cx == XXCDUP) {
9697 #ifdef VMS
9698         s = "[-]";
9699 #else
9700 #ifdef datageneral
9701         s = "^";
9702 #else
9703         s = "..";
9704 #endif /* datageneral */
9705 #endif /* VMS */
9706         ckstrncpy(line,s,LINBUFSIZ);
9707         goto gocd;
9708     }
9709 #ifndef NOSPL
9710     if (cx == XXKCD) {                  /* Symbolic (Kermit) CD */
9711         char * p;
9712         int n, k;
9713         x = cmkey(kcdtab,nkcdtab,"Symbolic directory name","home",xxstring);
9714         if (x < 0)
9715           return(x);
9716         x = lookup(kcdtab,atmbuf,nkcdtab,&k); /* Get complete keyword */
9717         if (x < 0) {
9718             printf("?Lookup error\n");  /* shouldn't happen */
9719             return(-9);
9720         }
9721         if ((x = cmcfm()) < 0)
9722           return(x);
9723         if (k == VN_HOME) {             /* HOME: allow SET HOME to override */
9724             ckstrncpy(line,homepath(),LINBUFSIZ);
9725         } else {                        /* Other symbolic name */
9726             /* Convert to variable syntax */
9727             ckmakmsg(tmpbuf,TMPBUFSIZ,"\\v(",kcdtab[k].kwd,")",NULL);
9728             p = line;                   /* Expand the variable */
9729             n = LINBUFSIZ;
9730             zzstring(tmpbuf,&p,&n);
9731             if (!line[0]) {             /* Fail if variable not defined */
9732                 printf("?%s - not defined\n",tmpbuf);
9733                 return(success = 0);
9734             }
9735         }
9736         s = line;                       /* All OK, go try to CD... */
9737         goto gocd;
9738     }
9739 #endif /* NOSPL */
9740
9741     cdactive = 1;
9742 #ifdef GEMDOS
9743     if ((x = cmdir("Name of local directory, or carriage return",
9744                    homepath(),
9745                    &s,
9746                    NULL
9747                    )
9748          ) < 0 )
9749       return(x);
9750 #else
9751 #ifdef OS2
9752     if ((x = cmdirp("Name of PC disk and/or directory,\n\
9753        or press the Enter key for the default",
9754                     homepath(),
9755                     &s,
9756                     ckcdpath ? ckcdpath : getenv("CDPATH"),
9757                     xxstring
9758                     )
9759          ) < 0 )
9760       return(x);
9761 #else
9762 #ifdef MAC
9763     x = ckstrncpy(temp,homepath(),32);
9764     if (x > 0) if (temp[x-1] != ':') { temp[x] = ':'; temp[x+1] = NUL; }
9765     if ((x = cmtxt("Name of Macintosh volume and/or folder,\n\
9766  or press the Return key for the desktop on the boot disk",
9767                    temp,&s, xxstring)) < 0 )
9768       return(x);
9769 #else
9770     if ((x = cmdirp("Carriage return for home directory,\n\
9771 or name of directory on this computer",
9772 #ifdef VMS
9773                     "SYS$LOGIN",        /* With no colon */
9774 #else
9775                     homepath(),         /* In VMS this is "SYS$LOGIN:" */
9776 #endif /* VMS */
9777                     &s,
9778                     ckcdpath ? ckcdpath : getenv("CDPATH"),
9779                     xxstring
9780                     )) < 0)
9781       return(x);
9782 #endif /* MAC */
9783 #endif /* OS2 */
9784 #endif /* GEMDOS */
9785     ckstrncpy(line,s,LINBUFSIZ);        /* Make a safe copy */
9786     s = line;
9787 #ifdef VMS
9788     if (ckmatch("*.DIR;1$",s,0,0))
9789       if (cvtdir(s,tmpbuf,TMPBUFSIZ) > 0)
9790         s = tmpbuf;
9791 #endif /* VMS */
9792     debug(F110,"docd",s,0);
9793 #ifndef MAC
9794     if ((x = cmcfm()) < 0)              /* Get confirmation */
9795       return(x);
9796 #endif /* MAC */
9797
9798   gocd:
9799
9800 #ifdef datageneral
9801     x = strlen(line);                   /* homdir ends in colon, */
9802     if (x > 1 && line[x-1] == ':')      /* and "dir" doesn't like that... */
9803       line[x-1] = NUL;
9804 #endif /* datageneral */
9805
9806 #ifdef MAC
9807     cwdf = 1;
9808     if (!zchdir(s)) {
9809         cwdf = 0;
9810         if (*s != ':') {                /* If it failed, */
9811             char *p;                    /* supply leading colon */
9812             int len = (int)strlen(s) + 2;
9813             p = malloc(len);            /* and try again... */
9814             if (p) {
9815                 strcpy(p,":");          /* safe */
9816                 strcat(p,s);            /* safe */
9817                 if (zchdir(p))
9818                   cwdf = 1;
9819                 free(p);
9820                 p = NULL;
9821             }
9822         }
9823     }
9824     if (!cwdf)
9825       perror(s);
9826 #else
9827     p = zgtdir();
9828     if (!zchdir(s)) {
9829         cwdf = 0;
9830 #ifdef CKROOT
9831         if (ckrooterr)
9832           printf("?Off limits: \"%s\"\n",s);
9833         else
9834 #endif /* CKROOT */
9835           perror(s);
9836     } else cwdf = 1;
9837 #endif /* MAC */
9838
9839     x = 0;
9840     if (cwdf) {
9841         makestr(&prevdir,p);
9842         debug(F111,"docd","srvcdmsg",srvcdmsg);
9843         if (srvcdmsg
9844 #ifdef IKSDCONF
9845             && !(inserver && !iksdcf)
9846 #endif /* IKSDCONF */
9847             ) {
9848             int i;
9849             for (i = 0; i < 8; i++) {
9850                 debug(F111,"docd cdmsgfile[i]",cdmsgfile[i],i);
9851                 if (zchki(cdmsgfile[i]) > -1) {
9852                     x = 1;
9853                     dotype(cdmsgfile[i],xaskmore,0,0,NULL,0,NULL,0,0,NULL,0);
9854                     break;
9855                 }
9856             }
9857         }
9858     }
9859 /* xdocd: */
9860     if (!x && srvcdmsg && !server
9861 #ifdef IKSDCONF
9862         && !(inserver && !iksdcf)
9863 #endif /* IKSDCONF */
9864         && !quiet && !xcmdsrc)
9865       printf("%s\n", zgtdir());
9866
9867     return(cwdf);
9868 }
9869
9870 static int on_ctrlc = 0;
9871
9872 VOID
9873 fixcmd() {                      /* Fix command parser after interruption */
9874 #ifndef NOSPL
9875 #ifndef NOONCTRLC
9876     if (nmac) {                         /* Any macros defined? */
9877         int k;                          /* Yes */
9878         char * s = "on_ctrlc";          /* Name of Ctrl-C handling macro */
9879         k = mlook(mactab,s,nmac);       /* Look it up. */
9880         if (k >= 0) {                   /* If found, */
9881             if (on_ctrlc++ == 0) {      /* if not already executing, */
9882                 if (dodo(k,"",0) > -1)  /* set it up, */
9883                   parser(1);            /* execute it, */
9884             }
9885             delmac(s,1);                /* and undefine it. */
9886         }
9887     }
9888     on_ctrlc = 0;
9889 #endif /* NOONCTRLC */
9890 #endif /* NOSPL */
9891     dostop();                   /* Back to top level (also calls conint()). */
9892     bgchk();                    /* Check background status */
9893     if (*psave) {               /* If old prompt saved, */
9894         cmsetp(psave);          /* restore it. */
9895         *psave = NUL;
9896     }
9897     success = 0;                /* Tell parser last command failed */
9898 }
9899
9900 #ifndef NOSHOW                          /* SHOW FEATURES */
9901 /*
9902   Note, presently optlist[] index overflow is not checked.
9903   There is plenty of room (less than 360 entries for 1000 slots).
9904   When space starts to get tight, check for noptlist >= NOPTLIST
9905   every time noptlist is incremented.
9906 */
9907 #define NOPTLIST 1024
9908 static int noptlist = 0;
9909 static char * optlist[NOPTLIST+1];
9910 static int hpos = 0;
9911
9912 int
9913 prtopt(lines,s) int * lines; char *s; { /* Print an option */
9914     int y, i;                           /* Does word wrap. */
9915     if (!s) s = "";
9916     i = *lines;
9917     if (!*s) {                          /* Empty argument */
9918         if (hpos > 0) {                 /* means to end this line. */
9919             printf("\n");               /* Not needed if already at */
9920             if (++i > (cmd_rows - 3)) { /* beginning of new line. */
9921                 if (!askmore())
9922                   return(0);
9923                 else
9924                   i = 0;
9925             }
9926         }
9927         printf("\n");                   /* And then make a blank line */
9928         if (++i > (cmd_rows - 3)) {
9929             if (!askmore())
9930               return(0);
9931             else
9932               i = 0;
9933         }
9934         hpos = 0;
9935         *lines = i;
9936         return(1);
9937     }
9938     y = (int)strlen(s) + 1;
9939     hpos += y;
9940     debug(F101,"prtopt hpos","",hpos);
9941     debug(F101,"prtopt cmd_cols","",cmd_cols);
9942
9943     if (
9944 #ifdef OS2
9945         hpos > ((cmd_cols > 40) ? (cmd_cols - 1) : 79)
9946 #else /* OS2 */
9947         hpos > ((tt_cols > 40) ? (tt_cols - 1) : 79)
9948 #endif /* OS2 */
9949         ) {
9950         printf("\n");
9951         if (++i > (cmd_rows - 3)) {
9952             if (!askmore())
9953               return(0);
9954             else
9955               i = 0;
9956         }
9957         printf(" %s",s);
9958         hpos = y;
9959     } else
9960       printf(" %s",s);
9961     *lines = i;
9962     return(1);
9963 }
9964
9965 static VOID
9966 initoptlist() {
9967     int i;
9968     if (noptlist > 0)
9969       return;
9970     for (i = 0; i < NOPTLIST; i++)
9971       optlist[i] = NULL;
9972
9973 #ifdef MAC
9974 #ifdef MPW
9975     makestr(&(optlist[noptlist++]),"MPW");
9976 #endif /* MPW */
9977 #endif /* MAC */
9978
9979 #ifdef MAC
9980 #ifdef THINK_C
9981     makestr(&(optlist[noptlist++]),"THINK_C");
9982 #endif /* THINK_C */
9983 #endif /* MAC */
9984
9985 #ifdef __386__
9986     makestr(&(optlist[noptlist++]),"__386__");
9987 #endif /* __386__ */
9988
9989 /* Memory models... */
9990
9991 #ifdef __FLAT__
9992     makestr(&(optlist[noptlist++]),"__FLAT__");
9993 #endif /* __FLAT__ */
9994 #ifdef __SMALL__
9995     makestr(&(optlist[noptlist++]),"__SMALL__");
9996 #endif /* __SMALL__ */
9997 #ifdef __MEDIUM__
9998     makestr(&(optlist[noptlist++]),"__MEDIUM__");
9999 #endif /* __MEDIUM__ */
10000 #ifdef __COMPACT__
10001     makestr(&(optlist[noptlist++]),"__COMPACT__");
10002 #endif /* __COMPACT__ */
10003 #ifdef __LARGE__
10004     makestr(&(optlist[noptlist++]),"__LARGE__");
10005 #endif /* __LARGE__ */
10006
10007 #ifdef DEBUG
10008 #ifdef IFDEBUG
10009     makestr(&(optlist[noptlist++]),"IFDEBUG");
10010 #else
10011     makestr(&(optlist[noptlist++]),"DEBUG");
10012 #endif /* IFDEBUG */
10013 #endif /* DEBUG */
10014 #ifdef TLOG
10015     makestr(&(optlist[noptlist++]),"TLOG");
10016 #endif /* TLOG */
10017 #ifdef BIGBUFOK
10018     makestr(&(optlist[noptlist++]),"BIGBUFOK");
10019 #endif /* BIGBUFOK */
10020 #ifdef INPBUFSIZ
10021     sprintf(line,"INPBUFSIZ=%d",INPBUFSIZ); /* SAFE */
10022     makestr(&(optlist[noptlist++]),line);
10023 #endif /* INPBUFSIZE */
10024 #ifdef LINBUFSIZ
10025     sprintf(line,"LINBUFSIZ=%d",LINBUFSIZ); /* SAFE */
10026     makestr(&(optlist[noptlist++]),line);
10027 #endif /* LINBUFSIZE */
10028 #ifdef INBUFSIZE
10029     sprintf(line,"INBUFSIZE=%d",INBUFSIZE); /* SAFE */
10030     makestr(&(optlist[noptlist++]),line);
10031 #endif /* INBUFSIZE */
10032 #ifdef OBUFSIZE
10033     sprintf(line,"OBUFSIZE=%d",OBUFSIZE); /* SAFE */
10034     makestr(&(optlist[noptlist++]),line);
10035 #endif /* OBUFSIZE */
10036 #ifdef FD_SETSIZE
10037     sprintf(line,"FD_SETSIZE=%d",FD_SETSIZE); /* SAFE */
10038     makestr(&(optlist[noptlist++]),line);
10039 #endif /* FD_SETSIZE */
10040 #ifdef XFRCAN
10041     makestr(&(optlist[noptlist++]),"XFRCAN");
10042 #endif /* XFRCAN */
10043 #ifdef XPRINT
10044     makestr(&(optlist[noptlist++]),"XPRINT");
10045 #endif /* XPRINT */
10046 #ifdef PIPESEND
10047     makestr(&(optlist[noptlist++]),"PIPESEND");
10048 #endif /* PIPESEND */
10049 #ifdef CK_SPEED
10050     makestr(&(optlist[noptlist++]),"CK_SPEED");
10051 #endif /* CK_SPEED */
10052 #ifdef CK_FAST
10053     makestr(&(optlist[noptlist++]),"CK_FAST");
10054 #endif /* CK_FAST */
10055 #ifdef CK_APC
10056     makestr(&(optlist[noptlist++]),"CK_APC");
10057 #endif /* CK_APC */
10058 #ifdef CK_AUTODL
10059     makestr(&(optlist[noptlist++]),"CK_AUTODL");
10060 #endif /* CK_AUTODL */
10061 #ifdef CK_MKDIR
10062     makestr(&(optlist[noptlist++]),"CK_MKDIR");
10063 #endif /* CK_MKDIR */
10064 #ifdef NOMKDIR
10065     makestr(&(optlist[noptlist++]),"NOMKDIR");
10066 #endif /* NOMKDIR */
10067 #ifdef CK_LABELED
10068     makestr(&(optlist[noptlist++]),"CK_LABELED");
10069 #endif /* CK_LABELED */
10070 #ifdef NODIAL
10071     makestr(&(optlist[noptlist++]),"NODIAL");
10072 #endif /* NODIAL */
10073 #ifdef MINIDIAL
10074     makestr(&(optlist[noptlist++]),"MINIDIAL");
10075 #endif /* MINIDIAL */
10076 #ifdef WHATAMI
10077     makestr(&(optlist[noptlist++]),"WHATAMI");
10078 #endif /* WHATAMI */
10079 #ifdef DYNAMIC
10080     makestr(&(optlist[noptlist++]),"DYNAMIC");
10081 #endif /* DYNAMIC */
10082 #ifndef NOSPL
10083     sprintf(line,"CMDDEP=%d",CMDDEP);   /* SAFE */
10084     makestr(&(optlist[noptlist++]),line);
10085 #endif /* NOSPL */
10086
10087 #ifdef MAXPATHLEN
10088     sprintf(line,"MAXPATHLEN=%d",MAXPATHLEN); /* SAFE */
10089     makestr(&(optlist[noptlist++]),line);
10090 #endif /* MAXPATHLEN */
10091
10092 #ifdef DEVNAMLEN
10093     sprintf(line,"DEVNAMLEN=%d",DEVNAMLEN); /* SAFE */
10094     makestr(&(optlist[noptlist++]),line);
10095 #endif /* DEVNAMLEN */
10096
10097 #ifdef NO_PARAM_H
10098     makestr(&(optlist[noptlist++]),"NO_PARAM_H");
10099 #endif /* NO_PARAM_H */
10100
10101 #ifdef INCL_PARAM_H
10102     makestr(&(optlist[noptlist++]),"INCL_PARAM_H");
10103 #endif /* INCL_PARAM_H */
10104
10105     sprintf(line,"CKMAXPATH=%d",CKMAXPATH); /* SAFE */
10106     makestr(&(optlist[noptlist++]),line);
10107
10108     sprintf(line,"CKMAXOPEN=%d",CKMAXOPEN); /* SAFE */
10109     makestr(&(optlist[noptlist++]),line);
10110
10111     sprintf(line,"Z_MAXCHAN=%d",Z_MAXCHAN); /* SAFE */
10112     makestr(&(optlist[noptlist++]),line);
10113
10114 #ifdef OPEN_MAX
10115     sprintf(line,"OPEN_MAX=%d",OPEN_MAX); /* SAFE */
10116     makestr(&(optlist[noptlist++]),line);
10117 #endif /* OPEN_MAX */
10118
10119 #ifdef _POSIX_OPEN_MAX
10120     sprintf(line,"_POSIX_OPEN_MAX=%d",_POSIX_OPEN_MAX); /* SAFE */
10121     makestr(&(optlist[noptlist++]),line);
10122 #endif /* _POSIX_OPEN_MAX */
10123
10124 #ifdef CKCHANNELIO
10125     {
10126         extern int z_maxchan;
10127 #ifdef UNIX
10128         extern int ckmaxfiles;
10129         sprintf(line,"ckmaxfiles=%d",ckmaxfiles); /* SAFE */
10130         makestr(&(optlist[noptlist++]),line);
10131 #endif /* UNIX */
10132         sprintf(line,"z_maxchan=%d",z_maxchan); /* SAFE */
10133         makestr(&(optlist[noptlist++]),line);
10134     }
10135 #endif /* CKCHANNELIO */
10136
10137 #ifdef FOPEN_MAX
10138     sprintf(line,"FOPEN_MAX=%d",FOPEN_MAX); /* SAFE */
10139     makestr(&(optlist[noptlist++]),line);
10140 #endif /* FOPEN_MAX */
10141
10142 #ifdef MAXGETPATH
10143     sprintf(line,"MAXGETPATH=%d",MAXGETPATH); /* SAFE */
10144     makestr(&(optlist[noptlist++]),line);
10145 #endif /* MAXGETPATH */
10146
10147 #ifdef CMDBL
10148     sprintf(line,"CMDBL=%d",CMDBL);     /* SAFE */
10149     makestr(&(optlist[noptlist++]),line);
10150 #endif /* CMDBL */
10151
10152 #ifdef VNAML
10153     sprintf(line,"VNAML=%d",VNAML);     /* SAFE */
10154     makestr(&(optlist[noptlist++]),line);
10155 #endif /* VNAML */
10156
10157 #ifdef ARRAYREFLEN
10158     sprintf(line,"ARRAYREFLEN=%d",ARRAYREFLEN); /* SAFE */
10159     makestr(&(optlist[noptlist++]),line);
10160 #endif /* ARRAYREFLEN */
10161
10162 #ifdef UIDBUFLEN
10163     sprintf(line,"UIDBUFLEN=%d",UIDBUFLEN); /* SAFE */
10164     makestr(&(optlist[noptlist++]),line);
10165 #endif /* UIDBUFLEN */
10166
10167 #ifdef FORDEPTH
10168     sprintf(line,"FORDEPTH=%d",FORDEPTH); /* SAFE */
10169     makestr(&(optlist[noptlist++]),line);
10170 #endif /* FORDEPTH */
10171
10172 #ifdef MAXTAKE
10173     sprintf(line,"MAXTAKE=%d",MAXTAKE); /* SAFE */
10174     makestr(&(optlist[noptlist++]),line);
10175 #endif /* MAXTAKE */
10176
10177 #ifdef MACLEVEL
10178     sprintf(line,"MACLEVEL=%d",MACLEVEL); /* SAFE */
10179     makestr(&(optlist[noptlist++]),line);
10180 #endif /* MACLEVEL */
10181
10182 #ifdef MAC_MAX
10183     sprintf(line,"MAC_MAX=%d",MAC_MAX); /* SAFE */
10184     makestr(&(optlist[noptlist++]),line);
10185 #endif /* MAC_MAX */
10186
10187 #ifdef _LARGEFILE_SOURCE
10188     makestr(&(optlist[noptlist++]),"_LARGEFILE_SOURCE");
10189 #endif  /* _LARGEFILE_SOURCE */
10190
10191 #ifdef _FILE_OFFSET_BITS
10192     sprintf(line,"_FILE_OFFSET_BITS=%d",_FILE_OFFSET_BITS); /* SAFE */
10193     makestr(&(optlist[noptlist++]),line);
10194 #endif  /* _FILE_OFFSET_BITS */
10195
10196 #ifdef __USE_FILE_OFFSET64
10197     makestr(&(optlist[noptlist++]),"__USE_FILE_OFFSET64");
10198 #endif  /* __USE_FILE_OFFSET64 */
10199
10200 #ifdef __USE_LARGEFILE64
10201     makestr(&(optlist[noptlist++]),"__USE_LARGEFILE64");
10202 #endif  /* __USE_LARGEFILE64 */
10203
10204 #ifdef COMMENT
10205 #ifdef CHAR_MAX
10206     sprintf(line,"CHAR_MAX=%llx",CHAR_MAX); /* SAFE */
10207     makestr(&(optlist[noptlist++]),line);
10208 #endif /* CHAR_MAX */
10209 #ifdef UCHAR_MAX
10210     sprintf(line,"UCHAR_MAX=%llx",UCHAR_MAX); /* SAFE */
10211     makestr(&(optlist[noptlist++]),line);
10212 #endif /* UCHAR_MAX */
10213 #ifdef SHRT_MAX
10214     sprintf(line,"SHRT_MAX=%llx",SHRT_MAX); /* SAFE */
10215     makestr(&(optlist[noptlist++]),line);
10216 #endif /* SHRT_MAX */
10217 #ifdef USHRT_MAX
10218     sprintf(line,"USHRT_MAX=%llx",USHRT_MAX); /* SAFE */
10219     makestr(&(optlist[noptlist++]),line);
10220 #endif /* USHRT_MAX */
10221 #ifdef INT_MAX
10222     sprintf(line,"INT_MAX=%llx",INT_MAX); /* SAFE */
10223     makestr(&(optlist[noptlist++]),line);
10224 #endif /* INT_MAX */
10225 #ifdef UINT_MAX
10226     sprintf(line,"UINT_MAX=%llx",UINT_MAX); /* SAFE */
10227     makestr(&(optlist[noptlist++]),line);
10228 #endif /* UINT_MAX */
10229 #ifdef MAX_LONG
10230     sprintf(line,"MAX_LONG=%llx",MAX_LONG); /* SAFE */
10231     makestr(&(optlist[noptlist++]),line);
10232 #endif /* MAX_LONG */
10233 #ifdef LONG_MAX
10234     sprintf(line,"LONG_MAX=%llx",LONG_MAX); /* SAFE */
10235     makestr(&(optlist[noptlist++]),line);
10236 #endif /* LONG_MAX */
10237 #ifdef ULONG_MAX
10238     sprintf(line,"ULONG_MAX=%llx",ULONG_MAX); /* SAFE */
10239     makestr(&(optlist[noptlist++]),line);
10240 #endif /* ULONG_MAX */
10241 #ifdef MAXINT
10242     sprintf(line,"MAXINT=%llx",MAXINT); /* SAFE */
10243     makestr(&(optlist[noptlist++]),line);
10244 #endif /* MAXINT */
10245 #ifdef MAXLONG
10246     sprintf(line,"MAXLONG=%llx",MAXLONG); /* SAFE */
10247     makestr(&(optlist[noptlist++]),line);
10248 #endif /* MAXLONG */
10249 #ifdef NT
10250 #ifdef LLONG_MAX
10251     sprintf(line,"LLONG_MAX=%I64x",LLONG_MAX); /* SAFE */
10252     makestr(&(optlist[noptlist++]),line);
10253 #endif /* LLONG_MAX */
10254 #ifdef ULLONG_MAX
10255     sprintf(line,"ULLONG_MAX=%I64x",ULLONG_MAX); /* SAFE */
10256     makestr(&(optlist[noptlist++]),line);
10257 #endif /* ULLONG_MAX */
10258 #ifdef MAXLONGLONG
10259     sprintf(line,"MAXLONGLONG=%I64x",MAXLONGLONG);  /* SAFE */
10260     makestr(&(optlist[noptlist++]),line);
10261 #endif /* MAXLONGLONG */
10262 #else
10263 #ifdef LLONG_MAX
10264     sprintf(line,"LLONG_MAX=%llx",LLONG_MAX); /* SAFE */
10265     makestr(&(optlist[noptlist++]),line);
10266 #endif /* LLONG_MAX */
10267 #ifdef ULLONG_MAX
10268     sprintf(line,"ULLONG_MAX=%llx",ULLONG_MAX); /* SAFE */
10269     makestr(&(optlist[noptlist++]),line);
10270 #endif /* ULLONG_MAX */
10271 #ifdef MAXLONGLONG
10272     sprintf(line,"MAXLONGLONG=%llx",MAXLONGLONG);  /* SAFE */
10273     makestr(&(optlist[noptlist++]),line);
10274 #endif /* MAXLONGLONG */
10275 #endif
10276 #ifdef _INTEGRAL_MAX_BITS
10277     sprintf(line,"_INTEGRAL_MAX_BITS=%d",_INTEGRAL_MAX_BITS);  /* SAFE */
10278     makestr(&(optlist[noptlist++]),line);
10279 #endif /* _INTEGRAL_MAX_BITS */
10280 #endif  /* COMMENT */
10281
10282 #ifdef MINPUTMAX
10283     sprintf(line,"MINPUTMAX=%d",MINPUTMAX); /* SAFE */
10284     makestr(&(optlist[noptlist++]),line);
10285 #endif /* MINPUTMAX */
10286
10287 #ifdef MAXWLD
10288     sprintf(line,"MAXWLD=%d",MAXWLD); /* SAFE */
10289     makestr(&(optlist[noptlist++]),line);
10290 #else
10291 #ifdef OS2
10292     makestr(&(optlist[noptlist++]),"MAXWLD=unlimited");
10293 #endif /* OS2 */
10294 #endif /* MAXWLD */
10295
10296 #ifdef MSENDMAX
10297     sprintf(line,"MSENDMAX=%d",MSENDMAX); /* SAFE */
10298     makestr(&(optlist[noptlist++]),line);
10299 #endif /* MSENDMAX */
10300
10301 #ifdef MAXDDIR
10302     sprintf(line,"MAXDDIR=%d",MAXDDIR); /* SAFE */
10303     makestr(&(optlist[noptlist++]),line);
10304 #endif /* MAXDDIR */
10305
10306 #ifdef MAXDNUMS
10307     sprintf(line,"MAXDNUMS=%d",MAXDNUMS); /* SAFE */
10308     makestr(&(optlist[noptlist++]),line);
10309 #endif /* MAXDNUMS */
10310
10311 #ifdef UNIX
10312     makestr(&(optlist[noptlist++]),"UNIX");
10313 #endif /* UNIX */
10314
10315 #ifdef VMS
10316     makestr(&(optlist[noptlist++]),"VMS");
10317 #ifdef __VMS_VER
10318     sprintf(line,"__VMS_VER=%d",__VMS_VER); /* SAFE */
10319     makestr(&(optlist[noptlist++]),line);
10320 #endif /* __VMS_VER */
10321 #ifdef VMSV70
10322     makestr(&(optlist[noptlist++]),"VMSV70");
10323 #endif /* VMSV70 */
10324 #ifdef OLD_VMS
10325     makestr(&(optlist[noptlist++]),"OLD_VMS");
10326 #endif /* OLD_VMS */
10327 #ifdef vms
10328     makestr(&(optlist[noptlist++]),"vms");
10329 #endif /* vms */
10330 #ifdef VMSV60
10331     makestr(&(optlist[noptlist++]),"VMSV60");
10332 #endif /* VMSV60 */
10333 #ifdef VMSV80
10334     makestr(&(optlist[noptlist++]),"VMSV80");
10335 #endif /* VMSV80 */
10336 #ifdef VMSSHARE
10337     makestr(&(optlist[noptlist++]),"VMSSHARE");
10338 #endif /* VMSSHARE */
10339 #ifdef NOVMSSHARE
10340     makestr(&(optlist[noptlist++]),"NOVMSSHARE");
10341 #endif /* NOVMSSHARE */
10342 #endif /* VMS */
10343
10344 #ifdef datageneral
10345     makestr(&(optlist[noptlist++]),"datageneral");
10346 #endif /* datageneral */
10347 #ifdef apollo
10348     makestr(&(optlist[noptlist++]),"apollo");
10349 #endif /* apollo */
10350 #ifdef aegis
10351     makestr(&(optlist[noptlist++]),"aegis");
10352 #endif /* aegis */
10353 #ifdef A986
10354     makestr(&(optlist[noptlist++]),"A986");
10355 #endif /* A986 */
10356 #ifdef AMIGA
10357     makestr(&(optlist[noptlist++]),"AMIGA");
10358 #endif /* AMIGA */
10359 #ifdef CONVEX9
10360     makestr(&(optlist[noptlist++]),"CONVEX9");
10361 #endif /* CONVEX9 */
10362 #ifdef CONVEX10
10363     makestr(&(optlist[noptlist++]),"CONVEX10");
10364 #endif /* CONVEX9 */
10365 #ifdef MAC
10366     makestr(&(optlist[noptlist++]),"MAC");
10367 #endif /* MAC */
10368 #ifdef AUX
10369     makestr(&(optlist[noptlist++]),"AUX");
10370 #endif /* AUX */
10371
10372 #ifdef OS2
10373     makestr(&(optlist[noptlist++]),"OS2");
10374 #ifdef NT
10375     makestr(&(optlist[noptlist++]),"NT");
10376 #endif /* NT */
10377 #endif /* OS2 */
10378
10379 #ifdef OSK
10380     makestr(&(optlist[noptlist++]),"OS9");
10381 #endif /* OSK */
10382
10383 #ifdef MSDOS
10384     makestr(&(optlist[noptlist++]),"MSDOS");
10385 #endif /* MSDOS */
10386
10387 #ifdef DIRENT
10388     makestr(&(optlist[noptlist++]),"DIRENT");
10389 #endif /* DIRENT */
10390
10391 #ifdef SDIRENT
10392     makestr(&(optlist[noptlist++]),"SDIRENT");
10393 #endif /* SDIRENT */
10394
10395 #ifdef NDIR
10396     makestr(&(optlist[noptlist++]),"NDIR");
10397 #endif /* NDIR */
10398
10399 #ifdef XNDIR
10400     makestr(&(optlist[noptlist++]),"XNDIR");
10401 #endif /* XNDIR */
10402
10403 #ifdef SAVEDUID
10404     makestr(&(optlist[noptlist++]),"SAVEDUID");
10405 #endif /* SAVEDUID */
10406
10407 #ifdef RENAME
10408     makestr(&(optlist[noptlist++]),"RENAME");
10409 #endif /* RENAME */
10410
10411 #ifdef CK_TMPDIR
10412     makestr(&(optlist[noptlist++]),"CK_TMPDIR");
10413 #endif /* CK_TMPDIR */
10414
10415 #ifdef NOCCTRAP
10416     makestr(&(optlist[noptlist++]),"NOCCTRAP");
10417 #endif /* NOCCTRAP */
10418
10419 #ifdef NOCOTFMC
10420     makestr(&(optlist[noptlist++]),"NOCOTFMC");
10421 #endif /* NOCOTFMC */
10422
10423 #ifdef NOFRILLS
10424     makestr(&(optlist[noptlist++]),"NOFRILLS");
10425 #endif /* NOFRILLS */
10426
10427 #ifdef PARSENSE
10428     makestr(&(optlist[noptlist++]),"PARSENSE");
10429 #endif /* PARSENSE */
10430
10431 #ifdef TIMEH
10432     makestr(&(optlist[noptlist++]),"TIMEH");
10433 #endif /* TIMEH */
10434
10435 #ifdef NOTIMEH
10436     makestr(&(optlist[noptlist++]),"TIMEH");
10437 #endif /* NOTIMEH */
10438
10439 #ifdef SYSTIMEH
10440     makestr(&(optlist[noptlist++]),"SYSTIMEH");
10441 #endif /* SYSTIMEH */
10442
10443 #ifdef NOSYSTIMEH
10444     makestr(&(optlist[noptlist++]),"SYSTIMEH");
10445 #endif /* NOSYSTIMEH */
10446
10447 #ifdef SYSTIMEBH
10448     makestr(&(optlist[noptlist++]),"SYSTIMEBH");
10449 #endif /* SYSTIMEBH */
10450
10451 #ifdef NOSYSTIMEBH
10452     makestr(&(optlist[noptlist++]),"SYSTIMEBH");
10453 #endif /* NOSYSTIMEBH */
10454
10455 #ifdef UTIMEH
10456     makestr(&(optlist[noptlist++]),"UTIMEH");
10457 #endif /* UTIMEH */
10458
10459 #ifdef SYSUTIMEH
10460     makestr(&(optlist[noptlist++]),"SYSUTIMEH");
10461 #endif /* SYSUTIMEH */
10462
10463 #ifdef CK_NEED_SIG
10464     makestr(&(optlist[noptlist++]),"CK_NEED_SIG");
10465 #endif /* CK_NEED_SIG */
10466
10467 #ifdef CK_TTYFD
10468     makestr(&(optlist[noptlist++]),"CK_TTYFD");
10469 #endif /* CK_TTYFD */
10470
10471 #ifdef NETCONN
10472     makestr(&(optlist[noptlist++]),"NETCONN");
10473 #endif /* NETCONN */
10474
10475 #ifdef TCPSOCKET
10476     makestr(&(optlist[noptlist++]),"TCPSOCKET");
10477 #ifdef NOTCPOPTS
10478     makestr(&(optlist[noptlist++]),"NOTCPOPTS");
10479 #endif /* NOTCPOPTS */
10480 #ifdef CK_DNS_SRV
10481     makestr(&(optlist[noptlist++]),"CK_DNS_SRV");
10482 #endif /* CK_DNS_SRV */
10483 #ifdef NO_DNS_SRV
10484     makestr(&(optlist[noptlist++]),"NO_DNS_SRV");
10485 #endif /* NO_DNS_SRV */
10486 #ifdef CKGHNLHOST
10487     makestr(&(optlist[noptlist++]),"CKGHNLHOST");
10488 #endif /* CKGHNLHOST */
10489 #ifdef NOLISTEN
10490     makestr(&(optlist[noptlist++]),"NOLISTEN");
10491 #endif /* NOLISTEN */
10492 #ifdef SOL_SOCKET
10493     makestr(&(optlist[noptlist++]),"SOL_SOCKET");
10494 #endif /* SOL_SOCKET */
10495 #ifdef SO_OOBINLINE
10496     makestr(&(optlist[noptlist++]),"SO_OOBINLINE");
10497 #endif /* SO_OOBINLNE */
10498 #ifdef SO_DONTROUTE
10499     makestr(&(optlist[noptlist++]),"SO_DONTROUTE");
10500 #endif /* SO_DONTROUTE */
10501 #ifdef SO_KEEPALIVE
10502     makestr(&(optlist[noptlist++]),"SO_KEEPALIVE");
10503 #endif /* SO_KEEPALIVE */
10504 #ifdef SO_LINGER
10505     makestr(&(optlist[noptlist++]),"SO_LINGER");
10506 #endif /* SO_LINGER */
10507 #ifdef TCP_NODELAY
10508     makestr(&(optlist[noptlist++]),"TCP_NODELAY");
10509 #endif /* TCP_NODELAY */
10510 #ifdef SO_SNDBUF
10511     makestr(&(optlist[noptlist++]),"SO_SNDBUF");
10512 #endif /* SO_SNDBUF */
10513 #ifdef SO_RCVBUF
10514     makestr(&(optlist[noptlist++]),"SO_RCVBUF");
10515 #endif /* SO_RCVBUF */
10516 #ifdef h_addr
10517     makestr(&(optlist[noptlist++]),"h_addr");
10518 #endif /* h_addr */
10519 #ifdef HADDRLIST
10520     makestr(&(optlist[noptlist++]),"HADDRLIST");
10521 #endif /* HADDRLIST */
10522 #ifdef CK_SOCKS
10523     makestr(&(optlist[noptlist++]),"CK_SOCKS");
10524 #ifdef CK_SOCKS5
10525     makestr(&(optlist[noptlist++]),"CK_SOCKS5");
10526 #endif /* CK_SOCKS5 */
10527 #ifdef CK_SOCKS_NS
10528     makestr(&(optlist[noptlist++]),"CK_SOCKS_NS");
10529 #endif /* CK_SOCKS_NS */
10530 #endif /* CK_SOCKS */
10531 #ifdef RLOGCODE
10532     makestr(&(optlist[noptlist++]),"RLOGCODE");
10533 #endif /* RLOGCODE */
10534 #ifdef NETCMD
10535     makestr(&(optlist[noptlist++]),"NETCMD");
10536 #endif /* NETCMD */
10537 #ifdef NONETCMD
10538     makestr(&(optlist[noptlist++]),"NONETCMD");
10539 #endif /* NONETCMD */
10540 #ifdef NETPTY
10541     makestr(&(optlist[noptlist++]),"NETPTY");
10542 #endif /* NETPTY */
10543 #ifdef CK_ENVIRONMENT
10544     makestr(&(optlist[noptlist++]),"CK_ENVIRONMENT");
10545 #endif /* CK_ENVIRONMENT */
10546 #endif /* TCPSOCKET */
10547 #ifdef TNCODE
10548     makestr(&(optlist[noptlist++]),"TNCODE");
10549 #endif /* TNCODE */
10550 #ifdef CK_FORWARD_X
10551     makestr(&(optlist[noptlist++]),"CK_FORWARD_X");
10552 #endif /* CK_FORWARD_X */
10553 #ifdef TN_COMPORT
10554     makestr(&(optlist[noptlist++]),"TN_COMPORT");
10555 #endif /* TN_COMPORT */
10556 #ifdef MULTINET
10557     makestr(&(optlist[noptlist++]),"MULTINET");
10558 #endif /* MULTINET */
10559 #ifdef DEC_TCPIP
10560     makestr(&(optlist[noptlist++]),"DEC_TCPIP");
10561 #endif /* DEC_TCPIP */
10562 #ifdef TCPWARE
10563     makestr(&(optlist[noptlist++]),"TCPWARE");
10564 #endif /* TCPWARE */
10565 #ifdef UCX50
10566     makestr(&(optlist[noptlist++]),"UCX50");
10567 #endif /* UCX50 */
10568 #ifdef CMU_TCPIP
10569     makestr(&(optlist[noptlist++]),"CMU_TCPIP");
10570 #endif /* CMU_TCPIP */
10571 #ifdef TTLEBUF
10572     makestr(&(optlist[noptlist++]),"TTLEBUF");
10573 #endif /* TTLEBUF */
10574 #ifdef NETLEBUF
10575     makestr(&(optlist[noptlist++]),"NETLEBUF");
10576 #endif /* NETLEBUF */
10577 #ifdef IKS_OPTION
10578     makestr(&(optlist[noptlist++]),"IKS_OPTION");
10579 #endif /* IKS_OPTION */
10580 #ifdef IKSDB
10581     makestr(&(optlist[noptlist++]),"IKSDB");
10582 #endif /* IKSDB */
10583 #ifdef IKSDCONF
10584     makestr(&(optlist[noptlist++]),"IKSDCONF");
10585 #endif /* IKSDCONF */
10586 #ifdef CK_LOGIN
10587     makestr(&(optlist[noptlist++]),"CK_LOGIN");
10588 #endif /* CK_LOGIN */
10589 #ifdef CK_PAM
10590     makestr(&(optlist[noptlist++]),"CK_PAM");
10591 #endif /* CK_PAM */
10592 #ifdef CK_SHADOW
10593     makestr(&(optlist[noptlist++]),"CK_SHADOW");
10594 #endif /* CK_SHADOW */
10595 #ifdef CONGSPD
10596     makestr(&(optlist[noptlist++]),"CONGSPD");
10597 #endif /* CONGSPD */
10598 #ifdef SUNX25
10599     makestr(&(optlist[noptlist++]),"SUNX25");
10600 #endif /* SUNX25 */
10601 #ifdef IBMX25
10602     makestr(&(optlist[noptlist++]),"IBMX25");
10603 #endif /* IBMX25 */
10604 #ifdef HPX25
10605     makestr(&(optlist[noptlist++]),"HPX25");
10606 #endif /* HPX25 */
10607 #ifdef DECNET
10608     makestr(&(optlist[noptlist++]),"DECNET");
10609 #endif /* DECNET */
10610 #ifdef SUPERLAT
10611     makestr(&(optlist[noptlist++]),"SUPERLAT");
10612 #endif /* SUPERLAT */
10613 #ifdef NPIPE
10614     makestr(&(optlist[noptlist++]),"NPIPE");
10615 #endif /* NPIPE */
10616 #ifdef CK_NETBIOS
10617     makestr(&(optlist[noptlist++]),"CK_NETBIOS");
10618 #endif /* CK_NETBIOS */
10619 #ifdef ATT7300
10620     makestr(&(optlist[noptlist++]),"ATT7300");
10621 #endif /* ATT7300 */
10622 #ifdef ATT6300
10623     makestr(&(optlist[noptlist++]),"ATT6300");
10624 #endif /* ATT6300 */
10625 #ifdef HDBUUCP
10626     makestr(&(optlist[noptlist++]),"HDBUUCP");
10627 #endif /* HDBUUCP */
10628 #ifdef USETTYLOCK
10629     makestr(&(optlist[noptlist++]),"USETTYLOCK");
10630 #endif /* USETTYLOCK */
10631 #ifdef USE_UU_LOCK
10632     makestr(&(optlist[noptlist++]),"USE_UU_LOCK");
10633 #endif /* USE_UU_LOCK */
10634 #ifdef HAVE_LOCKDEV
10635     makestr(&(optlist[noptlist++]),"HAVE_LOCKDEV");
10636 #endif /* HAVE_LOCKDEV */
10637 #ifdef HAVE_BAUDBOY
10638     makestr(&(optlist[noptlist++]),"HAVE_BAUDBOY");
10639 #endif /* HAVE_BAUDBOY */
10640 #ifdef HAVE_OPENPTY
10641     makestr(&(optlist[noptlist++]),"HAVE_OPENPTY");
10642 #endif /* HAVE_OPENPTY */
10643 #ifdef TTPTYCMD
10644     makestr(&(optlist[noptlist++]),"TTPTYCMD");
10645 #endif /* TTPTYCMD */
10646 #ifdef NOUUCP
10647     makestr(&(optlist[noptlist++]),"NOUUCP");
10648 #endif /* NOUUCP */
10649 #ifdef LONGFN
10650     makestr(&(optlist[noptlist++]),"LONGFN");
10651 #endif /* LONGFN */
10652 #ifdef RDCHK
10653     makestr(&(optlist[noptlist++]),"RDCHK");
10654 #endif /* RDCHK */
10655 #ifdef SELECT
10656     makestr(&(optlist[noptlist++]),"SELECT");
10657 #endif /* SELECT */
10658 #ifdef USLEEP
10659     makestr(&(optlist[noptlist++]),"USLEEP");
10660 #endif /* USLEEP */
10661 #ifdef NAP
10662     makestr(&(optlist[noptlist++]),"NAP");
10663 #endif /* NAP */
10664 #ifdef NAPHACK
10665     makestr(&(optlist[noptlist++]),"NAPHACK");
10666 #endif /* NAPHACK */
10667 #ifdef CK_POLL
10668     makestr(&(optlist[noptlist++]),"CK_POLL");
10669 #endif /* CK_POLL */
10670 #ifdef NOIEXTEN
10671     makestr(&(optlist[noptlist++]),"NOIEXTEN");
10672 #endif /* NOIEXTEN */
10673 #ifdef EXCELAN
10674     makestr(&(optlist[noptlist++]),"EXCELAN");
10675 #endif /* EXCELAN */
10676 #ifdef INTERLAN
10677     makestr(&(optlist[noptlist++]),"INTERLAN");
10678 #endif /* INTERLAN */
10679 #ifdef NOFILEH
10680     makestr(&(optlist[noptlist++]),"NOFILEH");
10681 #endif /* NOFILEH */
10682 #ifdef NOSYSIOCTLH
10683     makestr(&(optlist[noptlist++]),"NOSYSIOCTLH");
10684 #endif /* NOSYSIOCTLH */
10685 #ifdef DCLPOPEN
10686     makestr(&(optlist[noptlist++]),"DCLPOPEN");
10687 #endif /* DCLPOPEN */
10688 #ifdef NOSETBUF
10689     makestr(&(optlist[noptlist++]),"NOSETBUF");
10690 #endif /* NOSETBUF */
10691 #ifdef NOXFER
10692     makestr(&(optlist[noptlist++]),"NOXFER");
10693 #endif /* NOXFER */
10694 #ifdef NOCURSES
10695     makestr(&(optlist[noptlist++]),"NOCURSES");
10696 #endif /* NOCURSES */
10697 #ifdef NOSERVER
10698     makestr(&(optlist[noptlist++]),"NOSERVER");
10699 #endif /* NOSERVER */
10700 #ifdef NOPATTERNS
10701     makestr(&(optlist[noptlist++]),"NOPATTERNS");
10702 #else
10703 #ifdef PATTERNS
10704     makestr(&(optlist[noptlist++]),"PATTERNS");
10705 #endif /* PATTERNS */
10706 #endif /* NOPATTERNS */
10707 #ifdef NOCKEXEC
10708     makestr(&(optlist[noptlist++]),"NOCKEXEC");
10709 #else
10710 #ifdef CKEXEC
10711     makestr(&(optlist[noptlist++]),"CKEXEC");
10712 #endif /* CKEXEC */
10713 #endif /* NOCKEXEC */
10714 #ifdef NOAUTODL
10715     makestr(&(optlist[noptlist++]),"NOAUTODL");
10716 #endif /* NOAUTODL */
10717 #ifdef NOMSEND
10718     makestr(&(optlist[noptlist++]),"NOMSEND");
10719 #endif /* NOMSEND */
10720 #ifdef NOFDZERO
10721     makestr(&(optlist[noptlist++]),"NOFDZERO");
10722 #endif /* NOFDZERO */
10723 #ifdef NOPOPEN
10724     makestr(&(optlist[noptlist++]),"NOPOPEN");
10725 #endif /* NOPOPEN */
10726 #ifdef NOPARTIAL
10727     makestr(&(optlist[noptlist++]),"NOPARTIAL");
10728 #endif /* NOPARTIAL */
10729 #ifdef NOKVERBS
10730     makestr(&(optlist[noptlist++]),"NOKVERBS");
10731 #endif /* NOKVERBS */
10732 #ifdef NOSETREU
10733     makestr(&(optlist[noptlist++]),"NOSETREU");
10734 #endif /* NOSETREU */
10735 #ifdef LCKDIR
10736     makestr(&(optlist[noptlist++]),"LCKDIR");
10737 #endif /* LCKDIR */
10738 #ifdef ACUCNTRL
10739     makestr(&(optlist[noptlist++]),"ACUCNTRL");
10740 #endif /* ACUCNTRL */
10741 #ifdef BSD4
10742     makestr(&(optlist[noptlist++]),"BSD4");
10743 #endif /* BSD4 */
10744 #ifdef BSD44
10745     makestr(&(optlist[noptlist++]),"BSD44");
10746 #endif /* BSD44 */
10747 #ifdef BSD41
10748     makestr(&(optlist[noptlist++]),"BSD41");
10749 #endif /* BSD41 */
10750 #ifdef BSD43
10751     makestr(&(optlist[noptlist++]),"BSD43");
10752 #endif /* BSD43 */
10753 #ifdef BSD29
10754     makestr(&(optlist[noptlist++]),"BSD29");
10755 #endif /* BSD29 */
10756 #ifdef BSDI
10757     makestr(&(optlist[noptlist++]),"BSDI");
10758 #endif /* BSDI */
10759 #ifdef __bsdi__
10760     makestr(&(optlist[noptlist++]),"__bsdi__");
10761 #endif /* __bsdi__ */
10762 #ifdef __NetBSD__
10763     makestr(&(optlist[noptlist++]),"__NetBSD__");
10764 #endif /* __NetBSD__ */
10765 #ifdef __OpenBSD__
10766     makestr(&(optlist[noptlist++]),"__OpenBSD__");
10767 #endif /* __OpenBSD__ */
10768 #ifdef __FreeBSD__
10769     makestr(&(optlist[noptlist++]),"__FreeBSD__");
10770 #endif /* __FreeBSD__ */
10771 #ifdef __linux__
10772     makestr(&(optlist[noptlist++]),"__linux__");
10773 #endif /* __linux__ */
10774 #ifdef LINUX_HI_SPD
10775     makestr(&(optlist[noptlist++]),"LINUX_HI_SPD");
10776 #endif /* LINUX_HI_SPD */
10777 #ifdef LYNXOS
10778     makestr(&(optlist[noptlist++]),"LYNXOS");
10779 #endif /* LYNXOS */
10780 #ifdef V7
10781     makestr(&(optlist[noptlist++]),"V7");
10782 #endif /* V7 */
10783 #ifdef AIX370
10784     makestr(&(optlist[noptlist++]),"AIX370");
10785 #endif /* AIX370 */
10786 #ifdef RTAIX
10787     makestr(&(optlist[noptlist++]),"RTAIX");
10788 #endif /* RTAIX */
10789 #ifdef HPUX
10790     makestr(&(optlist[noptlist++]),"HPUX");
10791 #endif /* HPUX */
10792 #ifdef HPUX9
10793     makestr(&(optlist[noptlist++]),"HPUX9");
10794 #endif /* HPUX9 */
10795 #ifdef HPUX10
10796     makestr(&(optlist[noptlist++]),"HPUX10");
10797 #endif /* HPUX10 */
10798 #ifdef HPUX1000
10799     makestr(&(optlist[noptlist++]),"HPUX1000");
10800 #endif /* HPUX1000 */
10801 #ifdef HPUX1100
10802     makestr(&(optlist[noptlist++]),"HPUX1100");
10803 #endif /* HPUX1100 */
10804 #ifdef HPUXPRE65
10805     makestr(&(optlist[noptlist++]),"HPUXPRE65");
10806 #endif /* HPUXPRE65 */
10807 #ifdef DGUX
10808     makestr(&(optlist[noptlist++]),"DGUX");
10809 #endif /* DGUX */
10810 #ifdef DGUX430
10811     makestr(&(optlist[noptlist++]),"DGUX430");
10812 #endif /* DGUX430 */
10813 #ifdef DGUX540
10814     makestr(&(optlist[noptlist++]),"DGUX540");
10815 #endif /* DGUX540 */
10816 #ifdef DGUX543
10817     makestr(&(optlist[noptlist++]),"DGUX543");
10818 #endif /* DGUX543 */
10819 #ifdef DGUX54410
10820     makestr(&(optlist[noptlist++]),"DGUX54410");
10821 #endif /* DGUX54410 */
10822 #ifdef DGUX54411
10823     makestr(&(optlist[noptlist++]),"DGUX54411");
10824 #endif /* DGUX54411 */
10825 #ifdef sony_news
10826     makestr(&(optlist[noptlist++]),"sony_news");
10827 #endif /* sony_news */
10828 #ifdef CIE
10829     makestr(&(optlist[noptlist++]),"CIE");
10830 #endif /* CIE */
10831 #ifdef XENIX
10832     makestr(&(optlist[noptlist++]),"XENIX");
10833 #endif /* XENIX */
10834 #ifdef SCO_XENIX
10835     makestr(&(optlist[noptlist++]),"SCO_XENIX");
10836 #endif /* SCO_XENIX */
10837 #ifdef ISIII
10838     makestr(&(optlist[noptlist++]),"ISIII");
10839 #endif /* ISIII */
10840 #ifdef I386IX
10841     makestr(&(optlist[noptlist++]),"I386IX");
10842 #endif /* I386IX */
10843 #ifdef RTU
10844     makestr(&(optlist[noptlist++]),"RTU");
10845 #endif /* RTU */
10846 #ifdef PROVX1
10847     makestr(&(optlist[noptlist++]),"PROVX1");
10848 #endif /* PROVX1 */
10849 #ifdef PYRAMID
10850     makestr(&(optlist[noptlist++]),"PYRAMID");
10851 #endif /* PYRAMID */
10852 #ifdef TOWER1
10853     makestr(&(optlist[noptlist++]),"TOWER1");
10854 #endif /* TOWER1 */
10855 #ifdef UTEK
10856     makestr(&(optlist[noptlist++]),"UTEK");
10857 #endif /* UTEK */
10858 #ifdef ZILOG
10859     makestr(&(optlist[noptlist++]),"ZILOG");
10860 #endif /* ZILOG */
10861 #ifdef TRS16
10862     makestr(&(optlist[noptlist++]),"TRS16");
10863 #endif /* TRS16 */
10864 #ifdef MINIX
10865     makestr(&(optlist[noptlist++]),"MINIX");
10866 #endif /* MINIX */
10867 #ifdef MINIX2
10868     makestr(&(optlist[noptlist++]),"MINIX2");
10869 #endif /* MINIX2 */
10870 #ifdef MINIX3
10871     makestr(&(optlist[noptlist++]),"MINIX3");
10872 #endif /* MINIX3 */
10873 #ifdef MINIX315
10874     makestr(&(optlist[noptlist++]),"MINIX315");
10875 #endif /* MINIX315 */
10876 #ifdef C70
10877     makestr(&(optlist[noptlist++]),"C70");
10878 #endif /* C70 */
10879 #ifdef AIXPS2
10880     makestr(&(optlist[noptlist++]),"AIXPS2");
10881 #endif /* AIXPS2 */
10882 #ifdef AIXRS
10883     makestr(&(optlist[noptlist++]),"AIXRS");
10884 #endif /* AIXRS */
10885 #ifdef UTSV
10886     makestr(&(optlist[noptlist++]),"UTSV");
10887 #endif /* UTSV */
10888 #ifdef ATTSV
10889     makestr(&(optlist[noptlist++]),"ATTSV");
10890 #endif /* ATTSV */
10891 #ifdef SVR3
10892     makestr(&(optlist[noptlist++]),"SVR3");
10893 #endif /* SVR3 */
10894 #ifdef SVR4
10895     makestr(&(optlist[noptlist++]),"SVR4");
10896 #endif /* SVR4 */
10897 #ifdef DELL_SVR4
10898     makestr(&(optlist[noptlist++]),"DELL_SVR4");
10899 #endif /* DELL_SVR4 */
10900 #ifdef ICL_SVR4
10901     makestr(&(optlist[noptlist++]),"ICL_SVR4");
10902 #endif /* ICL_SVR4 */
10903 #ifdef OSF
10904     makestr(&(optlist[noptlist++]),"OSF");
10905 #endif /* OSF */
10906 #ifdef OSF1
10907     makestr(&(optlist[noptlist++]),"OSF1");
10908 #endif /* OSF1 */
10909 #ifdef __OSF
10910     makestr(&(optlist[noptlist++]),"__OSF");
10911 #endif /* __OSF */
10912 #ifdef __OSF__
10913     makestr(&(optlist[noptlist++]),"__OSF__");
10914 #endif /* __OSF__ */
10915 #ifdef __osf__
10916     makestr(&(optlist[noptlist++]),"__osf__");
10917 #endif /* __osf__ */
10918 #ifdef __OSF1
10919     makestr(&(optlist[noptlist++]),"__OSF1");
10920 #endif /* __OSF1 */
10921 #ifdef __OSF1__
10922     makestr(&(optlist[noptlist++]),"__OSF1__");
10923 #endif /* __OSF1__ */
10924 #ifdef PTX
10925     makestr(&(optlist[noptlist++]),"PTX");
10926 #endif /* PTX */
10927 #ifdef POSIX
10928     makestr(&(optlist[noptlist++]),"POSIX");
10929 #endif /* POSIX */
10930 #ifdef BSD44ORPOSIX
10931     makestr(&(optlist[noptlist++]),"BSD44ORPOSIX");
10932 #endif /* BSD44ORPOSIX */
10933 #ifdef SVORPOSIX
10934     makestr(&(optlist[noptlist++]),"SVORPOSIX");
10935 #endif /* SVORPOSIX */
10936 #ifdef SVR4ORPOSIX
10937     makestr(&(optlist[noptlist++]),"SVR4ORPOSIX");
10938 #endif /* SVR4ORPOSIX */
10939 #ifdef OS2ORVMS
10940     makestr(&(optlist[noptlist++]),"OS2ORVMS");
10941 #endif /* OS2ORVMS */
10942 #ifdef OS2ORUNIX
10943     makestr(&(optlist[noptlist++]),"OS2ORUNIX");
10944 #endif /* OS2ORUNIX */
10945 #ifdef VMSORUNIX
10946     makestr(&(optlist[noptlist++]),"VMSORUNIX");
10947 #endif /* VMSORUNIX */
10948 #ifdef VMS64BIT
10949     makestr(&(optlist[noptlist++]),"VMS64BIT"); /* VMS on Alpha or IA64 */
10950 #endif /* VMS64BIT */
10951 #ifdef VMSI64
10952     makestr(&(optlist[noptlist++]),"VMSI64"); /* VMS on IA64 */
10953 #endif /* VMSI64 */
10954 #ifdef _POSIX_SOURCE
10955     makestr(&(optlist[noptlist++]),"_POSIX_SOURCE");
10956 #endif /* _POSIX_SOURCE */
10957 #ifdef _XOPEN_SOURCE
10958     makestr(&(optlist[noptlist++]),"_XOPEN_SOURCE");
10959 #endif
10960 #ifdef _ALL_SOURCE
10961     makestr(&(optlist[noptlist++]),"_ALL_SOURCE");
10962 #endif
10963 #ifdef _SVID3
10964     makestr(&(optlist[noptlist++]),"_SVID3");
10965 #endif /* _SVID3 */
10966 #ifdef Plan9
10967     makestr(&(optlist[noptlist++]),"Plan9");
10968 #endif /* Plan9 */
10969 #ifdef SOLARIS
10970     makestr(&(optlist[noptlist++]),"SOLARIS");
10971 #ifdef SOLARIS24
10972     makestr(&(optlist[noptlist++]),"SOLARIS24");
10973 #endif /* SOLARIS24 */
10974 #ifdef SOLARIS25
10975     makestr(&(optlist[noptlist++]),"SOLARIS25");
10976 #endif /* SOLARIS25 */
10977 #ifdef SOLARIS26
10978     makestr(&(optlist[noptlist++]),"SOLARIS26");
10979 #endif /* SOLARIS26 */
10980 #ifdef SOLARIS7
10981     makestr(&(optlist[noptlist++]),"SOLARIS7");
10982 #endif /* SOLARIS7 */
10983 #ifdef SOLARIS8
10984     makestr(&(optlist[noptlist++]),"SOLARIS8");
10985 #endif /* SOLARIS8 */
10986 #ifdef SOLARIS9
10987     makestr(&(optlist[noptlist++]),"SOLARIS9");
10988 #endif /* SOLARIS9 */
10989 #ifdef SOLARIS10
10990     makestr(&(optlist[noptlist++]),"SOLARIS10");
10991 #endif /* SOLARIS10 */
10992 #endif /* SOLARIS */
10993
10994 #ifdef SUNOS4
10995     makestr(&(optlist[noptlist++]),"SUNOS4");
10996 #endif /* SUNOS4 */
10997 #ifdef SUN4S5
10998     makestr(&(optlist[noptlist++]),"SUN4S5");
10999 #endif /* SUN4S5 */
11000 #ifdef IRIX
11001     makestr(&(optlist[noptlist++]),"IRIX");
11002 #endif /* IRIX */
11003 #ifdef ENCORE
11004     makestr(&(optlist[noptlist++]),"ENCORE");
11005 #endif /* ENCORE */
11006 #ifdef ultrix
11007     makestr(&(optlist[noptlist++]),"ultrix");
11008 #endif
11009 #ifdef sxaE50
11010     makestr(&(optlist[noptlist++]),"sxaE50");
11011 #endif
11012 #ifdef mips
11013     makestr(&(optlist[noptlist++]),"mips");
11014 #endif
11015 #ifdef MIPS
11016     makestr(&(optlist[noptlist++]),"MIPS");
11017 #endif
11018 #ifdef vax
11019     makestr(&(optlist[noptlist++]),"vax");
11020 #endif
11021 #ifdef VAX
11022     makestr(&(optlist[noptlist++]),"VAX");
11023 #endif
11024 #ifdef alpha
11025     makestr(&(optlist[noptlist++]),"alpha");
11026 #endif
11027 #ifdef ALPHA
11028     makestr(&(optlist[noptlist++]),"ALPHA");
11029 #endif
11030 #ifdef __ALPHA
11031     makestr(&(optlist[noptlist++]),"__ALPHA");
11032 #endif
11033 #ifdef __alpha
11034     makestr(&(optlist[noptlist++]),"__alpha");
11035 #endif
11036 #ifdef __AXP
11037     makestr(&(optlist[noptlist++]),"__AXP");
11038 #endif
11039 #ifdef AXP
11040     makestr(&(optlist[noptlist++]),"AXP");
11041 #endif
11042 #ifdef axp
11043     makestr(&(optlist[noptlist++]),"axp");
11044 #endif
11045 #ifdef __ALPHA__
11046     makestr(&(optlist[noptlist++]),"__ALPHA__");
11047 #endif
11048 #ifdef __alpha__
11049     makestr(&(optlist[noptlist++]),"__alpha__");
11050 #endif
11051 #ifdef sun
11052     makestr(&(optlist[noptlist++]),"sun");
11053 #endif
11054 #ifdef sun3
11055     makestr(&(optlist[noptlist++]),"sun3");
11056 #endif
11057 #ifdef sun386
11058     makestr(&(optlist[noptlist++]),"sun386");
11059 #endif
11060 #ifdef _SUN
11061     makestr(&(optlist[noptlist++]),"_SUN");
11062 #endif
11063 #ifdef sun4
11064     makestr(&(optlist[noptlist++]),"sun4");
11065 #endif
11066 #ifdef sparc
11067     makestr(&(optlist[noptlist++]),"sparc");
11068 #endif
11069 #ifdef _CRAY
11070     makestr(&(optlist[noptlist++]),"_CRAY");
11071 #endif /* _CRAY */
11072 #ifdef NEXT33
11073     makestr(&(optlist[noptlist++]),"NEXT33");
11074 #endif
11075 #ifdef NEXT
11076     makestr(&(optlist[noptlist++]),"NEXT");
11077 #endif
11078 #ifdef NeXT
11079     makestr(&(optlist[noptlist++]),"NeXT");
11080 #endif
11081 #ifdef MACH
11082     makestr(&(optlist[noptlist++]),"MACH");
11083 #endif
11084
11085 #ifdef MACOSX
11086     makestr(&(optlist[noptlist++]),"MACOSX");
11087 #endif
11088 #ifdef MACOSX10
11089     makestr(&(optlist[noptlist++]),"MACOSX10");
11090 #endif
11091 #ifdef MACOSX103
11092     makestr(&(optlist[noptlist++]),"MACOSX10e");
11093 #endif
11094 #ifdef COMMENT
11095 /* not used */
11096 #ifdef MACOSX103
11097     makestr(&(optlist[noptlist++]),"MACOSX103");
11098 #endif
11099 #endif  /* COMMENT */
11100
11101 #ifdef sgi
11102     makestr(&(optlist[noptlist++]),"sgi");
11103 #endif
11104 #ifdef M_SYS5
11105     makestr(&(optlist[noptlist++]),"M_SYS5");
11106 #endif
11107 #ifdef __SYSTEM_FIVE
11108     makestr(&(optlist[noptlist++]),"__SYSTEM_FIVE");
11109 #endif
11110 #ifdef sysV
11111     makestr(&(optlist[noptlist++]),"sysV");
11112 #endif
11113 #ifdef M_XENIX                          /* SCO Xenix V and UNIX/386 */
11114     makestr(&(optlist[noptlist++]),"M_XENIX");
11115 #endif
11116 #ifdef M_UNIX                           /* SCO UNIX */
11117     makestr(&(optlist[noptlist++]),"M_UNIX");
11118 #endif
11119 #ifdef _M_UNIX                          /* SCO UNIX 3.2v4 = ODT 2.0 */
11120     makestr(&(optlist[noptlist++]),"_M_UNIX");
11121 #endif
11122 #ifdef CK_SCOV5
11123     makestr(&(optlist[noptlist++]),"CK_SCOV5");
11124 #endif
11125 #ifdef SCO_OSR504
11126     makestr(&(optlist[noptlist++]),"SCO_OSR504");
11127 #endif
11128 #ifdef M_IA64
11129     makestr(&(optlist[noptlist++]),"M_IA64");
11130 #endif
11131 #ifdef _M_IA64
11132     makestr(&(optlist[noptlist++]),"_M_IA64");
11133 #endif
11134 #ifdef ia64
11135     makestr(&(optlist[noptlist++]),"ia64");
11136 #endif
11137 #ifdef _ia64
11138     makestr(&(optlist[noptlist++]),"_ia64");
11139 #endif
11140 #ifdef _ia64_
11141     makestr(&(optlist[noptlist++]),"_ia64_");
11142 #endif
11143 #ifdef __ia64
11144     makestr(&(optlist[noptlist++]),"__ia64");
11145 #endif
11146 #ifdef M_I686
11147     makestr(&(optlist[noptlist++]),"M_I686");
11148 #endif
11149 #ifdef _M_I686
11150     makestr(&(optlist[noptlist++]),"_M_I686");
11151 #endif
11152 #ifdef i686
11153     makestr(&(optlist[noptlist++]),"i686");
11154 #endif
11155 #ifdef M_I586
11156     makestr(&(optlist[noptlist++]),"M_I586");
11157 #endif
11158 #ifdef _M_I586
11159     makestr(&(optlist[noptlist++]),"_M_I586");
11160 #endif
11161 #ifdef i586
11162     makestr(&(optlist[noptlist++]),"i586");
11163 #endif
11164 #ifdef M_I486
11165     makestr(&(optlist[noptlist++]),"M_I486");
11166 #endif
11167 #ifdef _M_I486
11168     makestr(&(optlist[noptlist++]),"_M_I486");
11169 #endif
11170 #ifdef i486
11171     makestr(&(optlist[noptlist++]),"i486");
11172 #endif
11173 #ifdef M_I386
11174     makestr(&(optlist[noptlist++]),"M_I386");
11175 #endif
11176 #ifdef _M_I386
11177     makestr(&(optlist[noptlist++]),"_M_I386");
11178 #endif
11179 #ifdef i386
11180     makestr(&(optlist[noptlist++]),"i386");
11181 #endif
11182 #ifdef __i386
11183     makestr(&(optlist[noptlist++]),"__i386");
11184 #endif
11185 #ifdef __x86
11186     makestr(&(optlist[noptlist++]),"__x86");
11187 #endif
11188 #ifdef __amd64
11189     makestr(&(optlist[noptlist++]),"__amd64");
11190 #endif
11191 #ifdef _ILP32
11192     makestr(&(optlist[noptlist++]),"_ILP32");
11193 #endif
11194 #ifdef _ILP64
11195     makestr(&(optlist[noptlist++]),"_ILP64");
11196 #endif
11197 #ifdef _LP32
11198     makestr(&(optlist[noptlist++]),"_LP32");
11199 #endif
11200 #ifdef _LP64
11201     makestr(&(optlist[noptlist++]),"_LP64");
11202 #endif
11203 #ifdef __LP32__
11204     makestr(&(optlist[noptlist++]),"__LP32__");
11205 #endif
11206 #ifdef __LP64__
11207     makestr(&(optlist[noptlist++]),"__LP64__");
11208 #endif
11209 #ifdef _XGP4_2
11210     makestr(&(optlist[noptlist++]),"_XGP4_2");
11211 #endif
11212 #ifdef __ppc__
11213     makestr(&(optlist[noptlist++]),"__ppc__");
11214 #endif
11215 #ifdef __ppc32__
11216     makestr(&(optlist[noptlist++]),"__ppc32__");
11217 #endif
11218 #ifdef __ppc64__
11219     makestr(&(optlist[noptlist++]),"__ppc64__");
11220 #endif
11221 #ifdef CK_64BIT
11222     makestr(&(optlist[noptlist++]),"CK_64BIT");
11223 #endif
11224 #ifdef i286
11225     makestr(&(optlist[noptlist++]),"i286");
11226 #endif
11227 #ifdef M_I286
11228     makestr(&(optlist[noptlist++]),"M_I286");
11229 #endif
11230 #ifdef __sparc
11231     makestr(&(optlist[noptlist++]),"__sparc");
11232 #endif
11233 #ifdef __sparcv8
11234     makestr(&(optlist[noptlist++]),"__sparcv8");
11235 #endif
11236 #ifdef __sparcv9
11237     makestr(&(optlist[noptlist++]),"__sparcv9");
11238 #endif
11239 #ifdef mc68000
11240     makestr(&(optlist[noptlist++]),"mc68000");
11241 #endif
11242 #ifdef mc68010
11243     makestr(&(optlist[noptlist++]),"mc68010");
11244 #endif
11245 #ifdef mc68020
11246     makestr(&(optlist[noptlist++]),"mc68020");
11247 #endif
11248 #ifdef mc68030
11249     makestr(&(optlist[noptlist++]),"mc68030");
11250 #endif
11251 #ifdef mc68040
11252     makestr(&(optlist[noptlist++]),"mc68040");
11253 #endif
11254 #ifdef M_68000
11255     makestr(&(optlist[noptlist++]),"M_68000");
11256 #endif
11257 #ifdef M_68010
11258     makestr(&(optlist[noptlist++]),"M_68010");
11259 #endif
11260 #ifdef M_68020
11261     makestr(&(optlist[noptlist++]),"M_68020");
11262 #endif
11263 #ifdef M_68030
11264     makestr(&(optlist[noptlist++]),"M_68030");
11265 #endif
11266 #ifdef M_68040
11267     makestr(&(optlist[noptlist++]),"M_68040");
11268 #endif
11269 #ifdef m68k
11270     makestr(&(optlist[noptlist++]),"m68k");
11271 #endif
11272 #ifdef m88k
11273     makestr(&(optlist[noptlist++]),"m88k");
11274 #endif
11275 #ifdef pdp11
11276     makestr(&(optlist[noptlist++]),"pdp11");
11277 #endif
11278 #ifdef iAPX
11279     makestr(&(optlist[noptlist++]),"iAPX");
11280 #endif
11281 #ifdef hpux
11282     makestr(&(optlist[noptlist++]),"hpux");
11283 #endif
11284 #ifdef __hpux
11285     makestr(&(optlist[noptlist++]),"__hpux");
11286 #endif
11287 #ifdef __hp9000s800
11288     makestr(&(optlist[noptlist++]),"__hp9000s800");
11289 #endif
11290 #ifdef __hp9000s700
11291     makestr(&(optlist[noptlist++]),"__hp9000s700");
11292 #endif
11293 #ifdef __hp9000s500
11294     makestr(&(optlist[noptlist++]),"__hp9000s500");
11295 #endif
11296 #ifdef __hp9000s300
11297     makestr(&(optlist[noptlist++]),"__hp9000s300");
11298 #endif
11299 #ifdef __hp9000s200
11300     makestr(&(optlist[noptlist++]),"__hp9000s200");
11301 #endif
11302 #ifdef AIX
11303     makestr(&(optlist[noptlist++]),"AIX");
11304 #endif
11305 #ifdef _AIXFS
11306     makestr(&(optlist[noptlist++]),"_AIXFS");
11307 #endif
11308 #ifdef u370
11309     makestr(&(optlist[noptlist++]),"u370");
11310 #endif
11311 #ifdef u3b
11312     makestr(&(optlist[noptlist++]),"u3b");
11313 #endif
11314 #ifdef u3b2
11315     makestr(&(optlist[noptlist++]),"u3b2");
11316 #endif
11317 #ifdef multimax
11318     makestr(&(optlist[noptlist++]),"multimax");
11319 #endif
11320 #ifdef balance
11321     makestr(&(optlist[noptlist++]),"balance");
11322 #endif
11323 #ifdef ibmrt
11324     makestr(&(optlist[noptlist++]),"ibmrt");
11325 #endif
11326 #ifdef _IBMRT
11327     makestr(&(optlist[noptlist++]),"_IBMRT");
11328 #endif
11329 #ifdef ibmrs6000
11330     makestr(&(optlist[noptlist++]),"ibmrs6000");
11331 #endif
11332 #ifdef _AIX
11333     makestr(&(optlist[noptlist++]),"_AIX");
11334 #endif /* _AIX */
11335 #ifdef _IBMR2
11336     makestr(&(optlist[noptlist++]),"_IBMR2");
11337 #endif
11338 #ifdef UNIXWARE
11339     makestr(&(optlist[noptlist++]),"UNIXWARE");
11340 #endif
11341 #ifdef QNX
11342     makestr(&(optlist[noptlist++]),"QNX");
11343 #ifdef __QNX__
11344     makestr(&(optlist[noptlist++]),"__QNX__");
11345 #ifdef __16BIT__
11346     makestr(&(optlist[noptlist++]),"__16BIT__");
11347 #endif
11348 #ifdef CK_QNX16
11349     makestr(&(optlist[noptlist++]),"CK_QNX16");
11350 #endif
11351 #ifdef __32BIT__
11352     makestr(&(optlist[noptlist++]),"__32BIT__");
11353 #endif
11354 #ifdef CK_QNX32
11355     makestr(&(optlist[noptlist++]),"CK_QNX32");
11356 #endif
11357 #endif /* __QNX__ */
11358 #endif /* QNX */
11359
11360 #ifdef QNX6
11361     makestr(&(optlist[noptlist++]),"QNX6");
11362 #endif /* QNX6 */
11363
11364 #ifdef NEUTRINO
11365     makestr(&(optlist[noptlist++]),"NEUTRINO");
11366 #endif /* NEUTRINO */
11367
11368 #ifdef __STRICT_BSD__
11369     makestr(&(optlist[noptlist++]),"__STRICT_BSD__");
11370 #endif
11371 #ifdef __STRICT_ANSI__
11372     makestr(&(optlist[noptlist++]),"__STRICT_ANSI__");
11373 #endif
11374 #ifdef _ANSI_C_SOURCE
11375     makestr(&(optlist[noptlist++]),"_ANSI_C_SOURCE");
11376 #endif
11377 #ifdef __STDC__
11378     makestr(&(optlist[noptlist++]),"__STDC__");
11379 #endif
11380 #ifdef cplusplus
11381     makestr(&(optlist[noptlist++]),"cplusplus");
11382 #endif
11383 #ifdef __DECC
11384     makestr(&(optlist[noptlist++]),"__DECC");
11385 #ifdef __DECC_VER
11386     sprintf(line,"__DECC_VER=%d",__DECC_VER); /* SAFE */
11387     makestr(&(optlist[noptlist++]),line);
11388 #endif /* __DECC_VER */
11389 #endif /* __DECC */
11390 #ifdef __CRTL_VER
11391     sprintf(line,"__CRTL_VER=%d",__CRTL_VER); /* SAFE */
11392     makestr(&(optlist[noptlist++]),line);
11393 #endif /* __CRTL_VER */
11394 #ifdef __GNUC__                         /* gcc in ansi mode */
11395     makestr(&(optlist[noptlist++]),"__GNUC__");
11396 #endif
11397 #ifdef GNUC                             /* gcc in traditional mode */
11398     makestr(&(optlist[noptlist++]),"GNUC");
11399 #endif
11400 #ifdef __EGCS__                         /* egcs in ansi mode */
11401     makestr(&(optlist[noptlist++]),"__EGCS__");
11402 #endif
11403 #ifdef __egcs__                         /* egcs in ansi mode */
11404     makestr(&(optlist[noptlist++]),"__egcs__");
11405 #endif
11406 #ifdef __WATCOMC__
11407     makestr(&(optlist[noptlist++]),"__WATCOMC__");
11408 #endif
11409 #ifdef CK_ANSIC
11410     makestr(&(optlist[noptlist++]),"CK_ANSIC");
11411 #endif
11412 #ifdef CK_ANSILIBS
11413     makestr(&(optlist[noptlist++]),"CK_ANSILIBS");
11414 #endif
11415 #ifdef CKCONINTB4CB
11416     makestr(&(optlist[noptlist++]),"CKCONINTB4CB");
11417 #endif /* CKCONINTB4CB */
11418 #ifdef NOTERMCAP
11419     makestr(&(optlist[noptlist++]),"NOTERMCAP");
11420 #endif /* NOTERMCAP */
11421 #ifdef __GLIBC__
11422     makestr(&(optlist[noptlist++]),"__GLIBC__");
11423 #endif
11424 #ifdef _SC_JOB_CONTROL
11425     makestr(&(optlist[noptlist++]),"_SC_JOB_CONTROL");
11426 #endif
11427 #ifdef _POSIX_JOB_CONTROL
11428     makestr(&(optlist[noptlist++]),"_POSIX_JOB_CONTROL");
11429 #endif
11430 #ifdef SIG_I
11431     makestr(&(optlist[noptlist++]),"SIG_I");
11432 #endif /* SIG_I */
11433 #ifdef SIG_V
11434     makestr(&(optlist[noptlist++]),"SIG_V");
11435 #endif /* SIG_V */
11436 #ifdef CK_POSIX_SIG
11437     makestr(&(optlist[noptlist++]),"CK_POSIX_SIG");
11438 #endif
11439 #ifdef SVR3JC
11440     makestr(&(optlist[noptlist++]),"SVR3JC");
11441 #endif
11442 #ifdef _386BSD
11443     makestr(&(optlist[noptlist++]),"_386BSD");
11444 #endif
11445 #ifdef _BSD
11446     makestr(&(optlist[noptlist++]),"_BSD");
11447 #endif
11448 #ifdef USE_MEMCPY
11449     makestr(&(optlist[noptlist++]),"USE_MEMCPY");
11450 #endif /* USE_MEMCPY */
11451 #ifdef USE_LSTAT
11452     makestr(&(optlist[noptlist++]),"USE_LSTAT");
11453 #endif /* USE_LSTAT */
11454 #ifdef TERMIOX
11455     makestr(&(optlist[noptlist++]),"TERMIOX");
11456 #endif /* TERMIOX */
11457 #ifdef STERMIOX
11458     makestr(&(optlist[noptlist++]),"STERMIOX");
11459 #endif /* STERMIOX */
11460 #ifdef CK_CURSES
11461     makestr(&(optlist[noptlist++]),"CK_CURSES");
11462 #endif /* CK_CURSES */
11463 #ifdef CK_NEWTERM
11464     makestr(&(optlist[noptlist++]),"CK_NEWTERM");
11465 #endif /* CK_NEWTERM */
11466 #ifdef CK_WREFRESH
11467     makestr(&(optlist[noptlist++]),"CK_WREFRESH");
11468 #endif /* CK_WREFRESH */
11469 #ifdef CK_PCT_BAR
11470     makestr(&(optlist[noptlist++]),"CK_PCT_BAR");
11471 #endif /* CK_PCT_BAR */
11472 #ifdef CK_DTRCD
11473     makestr(&(optlist[noptlist++]),"CK_DTRCD");
11474 #endif /* CK_DTRCD */
11475 #ifdef CK_DTRCTS
11476     makestr(&(optlist[noptlist++]),"CK_DTRCTS");
11477 #endif /* CK_DTRCTS */
11478 #ifdef CK_RTSCTS
11479     makestr(&(optlist[noptlist++]),"CK_RTSCTS");
11480 #endif /* CK_RTSCTS */
11481 #ifdef POSIX_CRTSCTS
11482     makestr(&(optlist[noptlist++]),"POSIX_CRTSCTS");
11483 #endif /* POSIX_CRTSCTS */
11484 #ifdef FIXCRTSCTS
11485     makestr(&(optlist[noptlist++]),"FIXCRTSCTS");
11486 #endif /* FIXCRTSCTS */
11487 #ifdef HWPARITY
11488     makestr(&(optlist[noptlist++]),"HWPARITY");
11489 #endif /* HWPARITY */
11490 #ifdef CK_SYSINI
11491 #ifdef CK_INI_A
11492     makestr(&(optlist[noptlist++]),"CK_INI_A");
11493     ckmakmsg(line,LINBUFSIZ,"CK_SYSINI=\"",CK_SYSINI,"\"",NULL);
11494     makestr(&(optlist[noptlist++]),line);
11495 #else
11496 #ifdef CK_INI_B
11497     makestr(&(optlist[noptlist++]),"CK_INI_B");
11498     ckmakmsg(line,LINBUFSIZ,"CK_SYSINI=\"",CK_SYSINI,"\"",NULL);
11499     makestr(&(optlist[noptlist++]),line);
11500 #else
11501     makestr(&(optlist[noptlist++]),"CK_SYSINI");
11502 #endif /* CK_INI_B */
11503 #endif /* CK_INI_A */
11504 #endif /* CK_DSYSINI */
11505 #ifdef CK_DSYSINI
11506     makestr(&(optlist[noptlist++]),"CK_DSYSINI");
11507 #endif /* CK_DSYSINI */
11508 #ifdef CK_TTGWSIZ
11509     makestr(&(optlist[noptlist++]),"CK_TTGWSIZ");
11510 #endif /* CK_TTGWSIZ */
11511 #ifdef CK_NAWS
11512     makestr(&(optlist[noptlist++]),"CK_NAWS");
11513 #endif /* CK_NAWS */
11514 #ifdef MDMHUP
11515     makestr(&(optlist[noptlist++]),"MDMHUP");
11516 #endif /* MDMHUP */
11517 #ifdef HUP_CLOSE_POSIX
11518     makestr(&(optlist[noptlist++]),"HUP_CLOSE_POSIX");
11519 #endif /* HUP_CLOSE_POSIX */
11520 #ifdef NO_HUP_CLOSE_POSIX
11521     makestr(&(optlist[noptlist++]),"NO_HUP_CLOSE_POSIX");
11522 #endif /* NO_HUP_CLOSE_POSIX */
11523 #ifdef DCMDBUF
11524     makestr(&(optlist[noptlist++]),"DCMDBUF");
11525 #endif /* DCMDBUF */
11526 #ifdef CK_RECALL
11527     makestr(&(optlist[noptlist++]),"CK_RECALL");
11528 #endif /* CK_RECALL */
11529 #ifdef BROWSER
11530     makestr(&(optlist[noptlist++]),"BROWSER");
11531 #endif /* BROWSER */
11532 #ifdef CLSOPN
11533     makestr(&(optlist[noptlist++]),"CLSOPN");
11534 #endif /* CLSOPN */
11535 #ifdef STRATUS
11536     makestr(&(optlist[noptlist++]),"STRATUS");
11537 #endif /* STRATUS */
11538 #ifdef __VOS__
11539     makestr(&(optlist[noptlist++]),"__VOS__");
11540 #endif /* __VOS__ */
11541 #ifdef STRATUSX25
11542     makestr(&(optlist[noptlist++]),"STRATUSX25");
11543 #endif /* STRATUSX25 */
11544 #ifdef OS2MOUSE
11545     makestr(&(optlist[noptlist++]),"OS2MOUSE");
11546 #endif /* OS2MOUSE */
11547 #ifdef CK_REXX
11548     makestr(&(optlist[noptlist++]),"CK_REXX");
11549 #endif /* CK_REXX */
11550 #ifdef CK_TIMERS
11551     makestr(&(optlist[noptlist++]),"CK_TIMERS");
11552 #endif /* CK_TIMERS */
11553 #ifdef TTSPDLIST
11554     makestr(&(optlist[noptlist++]),"TTSPDLIST");
11555 #endif /* TTSPDLIST */
11556 #ifdef CK_PERMS
11557     makestr(&(optlist[noptlist++]),"CK_PERMS");
11558 #endif /* CK_PERMS */
11559 #ifdef CKTUNING
11560     makestr(&(optlist[noptlist++]),"CKTUNING");
11561 #endif /* CKTUNING */
11562 #ifdef NEWFTP
11563     makestr(&(optlist[noptlist++]),"NEWFTP");
11564 #endif /* NEWFTP */
11565 #ifdef SYSFTP
11566     makestr(&(optlist[noptlist++]),"SYSFTP");
11567 #endif /* SYSFTP */
11568 #ifdef NOFTP
11569     makestr(&(optlist[noptlist++]),"NOFTP");
11570 #endif /* NOFTP */
11571 #ifdef CKHTTP
11572     makestr(&(optlist[noptlist++]),"CKHTTP");
11573 #endif /* CKHTTP */
11574 #ifdef NOHTTP
11575     makestr(&(optlist[noptlist++]),"NOHTTP");
11576 #endif /* NOHTTP */
11577 #ifdef CKROOT
11578     makestr(&(optlist[noptlist++]),"CKROOT");
11579 #endif /* CKROOT */
11580 #ifdef CKREALPATH
11581     makestr(&(optlist[noptlist++]),"CKREALPATH");
11582 #endif /* CKREALPATH */
11583 #ifdef STREAMING
11584     makestr(&(optlist[noptlist++]),"STREAMING");
11585 #endif /* STREAMING */
11586 #ifdef UNPREFIXZERO
11587     makestr(&(optlist[noptlist++]),"UNPREFIXZERO");
11588 #endif /* UNPREFIXZERO */
11589 #ifdef CKREGEX
11590     makestr(&(optlist[noptlist++]),"CKREGEX");
11591 #endif /* CKREGEX */
11592 #ifdef ZXREWIND
11593     makestr(&(optlist[noptlist++]),"ZXREWIND");
11594 #endif /* ZXREWIND */
11595 #ifdef CKSYSLOG
11596     makestr(&(optlist[noptlist++]),"CKSYSLOG");
11597 #endif /* CKSYSLOG */
11598 #ifdef SYSLOGLEVEL
11599     sprintf(line,"SYSLOGLEVEL=%d",SYSLOGLEVEL); /* SAFE */
11600     makestr(&(optlist[noptlist++]),line);
11601 #endif /* SYSLOGLEVEL */
11602 #ifdef NOSEXP
11603     makestr(&(optlist[noptlist++]),"NOSEXP");
11604 #endif /* NOSEXP */
11605 #ifdef CKLEARN
11606     makestr(&(optlist[noptlist++]),"CKLEARN");
11607 #else
11608 #ifdef NOLOEARN
11609     makestr(&(optlist[noptlist++]),"NOLOEARN");
11610 #endif /* NOLOEARN */
11611 #endif /* CKLEARN */
11612
11613 #ifdef NOFLOAT
11614     makestr(&(optlist[noptlist++]),"NOFLOAT");
11615 #else
11616 #ifdef FNFLOAT
11617     makestr(&(optlist[noptlist++]),"FNFLOAT");
11618 #endif /* FNFLOAT */
11619 #ifdef CKFLOAT
11620 #ifdef GFTIMER
11621     makestr(&(optlist[noptlist++]),"GFTIMER");
11622 #endif /* GFTIMER */
11623 #ifdef CKFLOAT_S
11624     ckmakmsg(line,LINBUFSIZ,"CKFLOAT=",CKFLOAT_S,NULL,NULL);
11625     makestr(&(optlist[noptlist++]),line);
11626 #else
11627     makestr(&(optlist[noptlist++]),"CKFLOAT");
11628 #endif /* CKFLOAT_S */
11629 #endif /* CKFLOAT */
11630 #endif /* NOFLOAT */
11631
11632 #ifdef SSH
11633     makestr(&(optlist[noptlist++]),"SSH");
11634 #endif /* SSH */
11635 #ifdef NETDLL
11636     makestr(&(optlist[noptlist++]),"NETDLL");
11637 #endif /* NETDLL */
11638 #ifdef NETFILE
11639     makestr(&(optlist[noptlist++]),"NETFILE");
11640 #endif /* NETFILE */
11641 #ifdef CK_TAPI
11642     makestr(&(optlist[noptlist++]),"CK_TAPI");
11643 #endif /* CK_TAPI */
11644 #ifdef CK_SSL
11645     makestr(&(optlist[noptlist++]),"CK_SSL");
11646 #ifdef OPENSSL_VERSION_TEXT
11647     ckmakmsg(line,LINBUFSIZ,
11648              "OPENSSL_VERSION_TEXT=","\"",OPENSSL_VERSION_TEXT,"\"");
11649     makestr(&(optlist[noptlist++]),line);
11650 #endif  /* OPENSSL_VERSION_TEXT */
11651 #endif /* CK_SSL */
11652     debug(F101,"initoptlist noptlist","",noptlist);
11653     sh_sort(optlist,NULL,noptlist,0,0,0);
11654 }
11655
11656 int
11657 shofea() {
11658     int i;
11659     int flag = 0;
11660     int lines = 1;
11661 #ifdef FNFLOAT
11662     extern int fp_digits, fp_rounding;
11663 #endif /* FNFLOAT */
11664     extern int byteorder;
11665     printf("%s\n",versio);
11666     if (inserver)
11667       return(1);
11668
11669     debug(F101,"shofea NOPTLIST","",NOPTLIST);
11670     initoptlist();
11671     debug(F101,"shofea noptlist","",noptlist);
11672 #ifdef OS2
11673 #ifdef NT
11674 #ifdef _M_ALPHA
11675     printf("Microsoft Windows Operating Systems for Alpha CPUs.\n");
11676 #else /* _M_ALPHA */
11677 #ifdef _M_PPC
11678     printf("Microsoft Windows Operating Systems for PowerPC CPUs.\n");
11679 #else /* _M_PPC */
11680 #ifdef _M_MRX000
11681     printf("Microsoft Windows Operating Systems for MIPS CPUs.\n");
11682 #else /* _M_MRX000 */
11683 #ifdef _M_IX86
11684     printf("Microsoft Windows Operating Systems for 32-bit Intel CPUs.\n");
11685 #else /* _M_IX86 */
11686     UNKNOWN WINDOWS PLATFORM
11687 #endif /* _M_IX86 */
11688 #endif /* _M_MRX000 */
11689 #endif /* _M_PPC */
11690 #endif /* _M_ALPHA */
11691 #else /* NT */
11692 #ifdef M_I286
11693     printf("IBM OS/2 16-bit.\n");
11694 #else
11695     printf("IBM OS/2 32-bit.\n");
11696 #endif /* M_I286 */
11697 #endif /* NT */
11698     lines++;
11699 #endif /* OS2 */
11700     printf("\n");
11701     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11702     printf("Major optional features included:\n");
11703     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11704
11705     if (sizeof(CK_OFF_T) == 8) {
11706         printf(" Large files and large integers (64 bits)\n");
11707         if (++lines > cmd_rows - 3) {
11708             if (!askmore()) return(1); else lines = 0;
11709         }
11710     }
11711 #ifdef NETCONN
11712     printf(" Network support (type SHOW NET for further info)\n");
11713     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11714 #ifdef IKS_OPTION
11715     printf(" Telnet Kermit Option\n");
11716     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11717 #endif /* IKS_OPTION */
11718 #ifdef CK_AUTHENTICATION
11719     printf(" Telnet Authentication Option\n");
11720     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11721 #ifdef CK_KERBEROS
11722 #ifdef KRB4
11723 #ifdef KRB5
11724     printf(" Kerberos(TM) IV and Kerberos V authentication\n");
11725     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11726 #else /* KRB5 */
11727     printf(" Kerberos(TM) IV authentication\n");
11728     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11729 #endif /* KRB5 */
11730 #else /* KRB4 */
11731 #ifdef KRB5
11732     printf(" Kerberos(TM) V authentication\n");
11733     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11734 #endif /* KRB5 */
11735 #endif /* KRB4 */
11736 #endif /* CK_KERBEROS */
11737 #ifdef CK_SRP
11738     printf(" SRP(TM) (Secure Remote Password) authentication\n");
11739     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11740 #endif /* CK_SRP */
11741 #ifdef CK_SSL
11742     printf(" Secure Sockets Layer (SSL)\n");
11743     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11744     printf(" Transport Layer Security (TLS)\n");
11745     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11746 #endif /* CK_SSL */
11747 #ifdef SSHBUILTIN
11748     printf(" Secure Shell (SSH) [internal]\n");
11749     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11750 #endif /* SSHBUILTIN */
11751 #ifdef SSHCMD
11752     printf(" Secure Shell (SSH) [external]\n");
11753     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11754 #endif /* SSHCMD */
11755 #ifdef CK_ENCRYPTION
11756     printf(" Telnet Encryption Option\n");
11757     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11758 #ifdef CK_DES
11759     printf(" Telnet DES Encryption\n");
11760     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11761 #endif /* CK_DES */
11762 #ifdef CK_CAST
11763     printf(" Telnet CAST Encryption\n");
11764     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11765 #endif /* CK_CAST */
11766
11767 #ifdef CK_KERBEROS
11768 #ifdef KRB5
11769 #ifdef ALLOW_KRB_3DES_ENCRYPT
11770     printf(" Kerberos 3DES/AES Telnet Encryption\n");
11771     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11772 #endif /* ALLOW_KRB_3DES_ENCRYPT */
11773 #endif /* KRB5 */
11774 #endif /* CK_KERBEROS */
11775
11776 #endif /* CK_ENCRYPTION */
11777 #endif /* CK_AUTHENTICATION */
11778 #ifdef CK_FORWARD_X
11779     printf(" X Windows forwarding\n");
11780     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11781 #endif /* CK_FORWARD_X */
11782 #ifdef TN_COMPORT
11783     printf(" Telnet Remote Com Port Control Option\n");
11784     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11785 #endif /* TN_COMPORT */
11786 #ifdef CK_SOCKS
11787 #ifdef CK_SOCKS5
11788     printf(" SOCKS 5\n");
11789     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11790 #else /* CK_SOCKS5 */
11791     printf(" SOCKS 4\n");
11792     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11793 #endif /* CK_SOCKS5 */
11794 #endif /* CK_SOCKS */
11795 #ifdef NEWFTP
11796     printf(" Built-in FTP client\n");
11797     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11798 #endif /* NEWFTP */
11799 #ifdef CKHTTP
11800     printf(" Built-in HTTP client\n");
11801     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11802 #endif /* CKHTTP */
11803 #endif /* NETCONN */
11804
11805 #ifdef CK_RTSCTS
11806     printf(" Hardware flow control\n");
11807     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11808 #endif /* CK_RTSCTS */
11809
11810 #ifdef CK_XYZ
11811 #ifdef XYZ_INTERNAL
11812     printf(" Built-in XYZMODEM protocols\n");
11813 #else
11814     printf(" External XYZMODEM protocol support\n");
11815 #endif /* XYZ_INTERNAL */
11816     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11817 #endif /* CK_XYZ */
11818
11819 #ifndef NOCSETS
11820     printf(" Latin-1 (West European) character-set translation\n");
11821     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11822 #ifdef LATIN2
11823     printf(" Latin-2 (East European) character-set translation\n");
11824     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11825 #endif /* LATIN2 */
11826 #ifdef CYRILLIC
11827     printf(" Cyrillic (Russian, Ukrainian, etc) character-set translation\n");
11828     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11829 #endif /* CYRILLIC */
11830 #ifdef GREEK
11831     printf(" Greek character-set translation\n");
11832     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11833 #endif /* GREEK */
11834 #ifdef HEBREW
11835     printf(" Hebrew character-set translation\n");
11836     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11837 #endif /* HEBREW */
11838 #ifdef KANJI
11839     printf(" Japanese character-set translation\n");
11840     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11841 #endif /* KANJI */
11842 #ifdef UNICODE
11843     printf(" Unicode character-set translation\n");
11844     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11845 #endif /* UNICODE */
11846 #ifdef CKOUNI
11847     if (isunicode())
11848       printf(" Unicode support for ISO-2022 Terminal Emulation\n");
11849     else
11850       printf(" Unicode translation for Terminal Character-Sets\n");
11851     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11852 #endif /* CKOUNI */
11853 #endif /* NOCSETS */
11854
11855 #ifdef NETPTY
11856     printf(" Pseudoterminal control\n");
11857     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11858 #endif /* NETPTY */
11859
11860 #ifdef CK_REDIR
11861     printf(" REDIRECT command\n");
11862     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11863 #endif /* CK_REDIR */
11864
11865 #ifdef CK_RESEND
11866     printf(" RESEND command\n");
11867     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11868 #endif /* CK_RESEND */
11869
11870 #ifndef NOXFER
11871 #ifdef CK_CURSES
11872     printf(" Fullscreen file transfer display\n");
11873     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11874 #endif /* CK_CURSES */
11875 #endif /* NOXFER */
11876
11877 #ifdef CK_SPEED
11878     printf(" Control-character unprefixing\n");
11879     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11880 #endif /* CK_SPEED */
11881
11882 #ifdef STREAMING
11883     printf(" Streaming\n");
11884     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11885 #endif /* STREAMING */
11886
11887 #ifdef CK_AUTODL
11888     printf(" Autodownload\n");
11889     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11890 #endif /* CK_AUTODL */
11891
11892 #ifdef OS2MOUSE
11893     printf(" Mouse support\n");
11894     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11895 #endif /* OS2MOUSE */
11896
11897 #ifdef CK_REXX
11898     printf(" REXX script language interface\n");
11899     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11900 #endif /* CK_REXX */
11901
11902 #ifdef IKSD
11903 #ifdef CK_LOGIN
11904     printf(" Internet Kermit Service with user login support\n");
11905 #else /* CK_LOGIN */
11906     printf(" Internet Kermit Service without user login support\n");
11907 #endif /* CK_LOGIN */
11908     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11909 #endif /* IKSD */
11910
11911     printf("\n");
11912     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11913     printf("Major optional features not included:\n");
11914     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11915
11916     if (sizeof(CK_OFF_T) <= 4) {
11917         printf(" No large files or large integers\n");
11918         if (++lines > cmd_rows - 3) {
11919             if (!askmore()) return(1); else lines = 0;
11920         }
11921     }
11922
11923 #ifdef NOXFER
11924     printf(" No file-transfer protocols\n");
11925     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11926     flag = 1;
11927 #else
11928 #ifndef CK_CURSES
11929 #ifndef MAC
11930     printf(" No fullscreen file transfer display\n");
11931     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11932     flag = 1;
11933 #endif /* MAC */
11934 #endif /* CK_CURSES */
11935
11936 #ifdef NOSERVER
11937     printf(" No server mode\n");
11938     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11939     flag = 1;
11940 #endif /* NOSERVER */
11941
11942 #ifndef CK_SPEED
11943     printf(" No control-character unprefixing\n");
11944     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11945     flag = 1;
11946 #endif /* CK_SPEED */
11947
11948 #ifndef STREAMING
11949     printf(" No streaming\n");
11950     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11951     flag = 1;
11952 #endif /* STREAMING */
11953
11954 #ifndef CK_AUTODL
11955     printf(" No autodownload\n");
11956     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11957     flag = 1;
11958 #endif /* CK_AUTODL */
11959
11960 #ifndef CK_XYZ
11961     printf(" No built-in XYZMODEM protocols\n");
11962     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11963     flag = 1;
11964 #endif /* CK_XYZ */
11965
11966 #ifdef NOTLOG
11967     printf(" No transaction log\n");
11968     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11969     flag = 1;
11970 #endif /* NOTLOG */
11971 #endif /* NOXFER */
11972
11973 #ifdef NODEBUG
11974     printf(" No debugging\n");
11975     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11976     flag = 1;
11977 #endif /* NODEBUG */
11978
11979 #ifdef NOHELP
11980     printf(" No built-in help\n");
11981     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11982     flag = 1;
11983 #endif /* NOHELP */
11984
11985 #ifdef NOLOCAL
11986     printf(" No making connections\n");
11987     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11988     flag = 1;
11989 #else
11990 #ifndef NETCONN
11991     printf(" No network support\n");
11992     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11993     flag = 1;
11994 #else /* NETCONN */
11995 #ifndef IKS_OPTION
11996     printf(" No Telnet Kermit Option\n");
11997     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11998     flag = 1;
11999 #endif /* IKS_OPTION */
12000 #endif /* NETCONN */
12001
12002 #ifdef NOSSH
12003     printf(" No Secure Shell (SSH)\n");
12004     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12005 #endif /* NOSSH */
12006 #ifndef CK_AUTHENTICATION
12007     printf(" No Kerberos(TM) authentication\n");
12008     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12009     printf(" No SRP(TM) (Secure Remote Password) protocol\n");
12010     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12011     printf(" No Secure Sockets Layer (SSL) protocol\n");
12012     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12013     printf(" No Transport Layer Security (TLS) protocol\n");
12014     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12015     printf(" No encryption\n");
12016     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12017     flag = 1;
12018 #else /* CK_AUTHENTICATION */
12019 #ifndef CK_KERBEROS
12020     printf(" No Kerberos(TM) authentication\n");
12021     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12022     flag = 1;
12023 #else /* CK_KERBEROS */
12024 #ifndef KRB4
12025     printf(" No Kerberos(TM) IV authentication\n");
12026     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12027     flag = 1;
12028 #endif /* KRB4 */
12029 #ifndef KRB5
12030     printf(" No Kerberos(TM) V authentication\n");
12031     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12032     flag = 1;
12033 #endif /* KRB5 */
12034 #endif /* CK_KERBEROS */
12035 #ifndef CK_SRP
12036     printf(" No SRP(TM) (Secure Remote Password) authentication\n");
12037     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12038     flag = 1;
12039 #endif /* CK_SRP */
12040 #ifndef CK_SSL
12041     printf(" No Secure Sockets Layer (SSL) protocol\n");
12042     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12043     printf(" No Transport Layer Security (TLS) protocol\n");
12044     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12045     flag = 1;
12046 #endif /* CK_SSL */
12047 #ifndef CK_ENCRYPTION
12048     printf(" No Telnet Encryption Option\n");
12049     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12050     flag = 1;
12051 #else /* CK_ENCRYPTION */
12052 #ifndef OS2
12053 #ifndef CK_DES
12054     printf(" No Telnet DES encryption\n");
12055     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12056     flag = 1;
12057 #endif /* CK_DES */
12058 #ifndef CK_CAST
12059     printf(" No Telnet CAST encryption\n");
12060     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12061     flag = 1;
12062 #endif /* CK_CAST */
12063
12064 #ifdef COMMENT
12065 #ifdef CK_KERBEROS
12066 #ifdef KRB5
12067 #ifndef ALLOW_KRB_3DES_ENCRYPT
12068     printf(" No Kerberos 3DES/AES Telnet Encryption\n");
12069     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12070 #endif /* ALLOW_KRB_3DES_ENCRYPT */
12071 #endif /* KRB5 */
12072 #endif /* CK_KERBEROS */
12073 #endif /* COMMENT */
12074
12075 #endif /* OS2 */
12076 #endif /* CK_ENCRYPTION */
12077 #endif /* CK_AUTHENTICATION */
12078 #ifndef CK_FORWARD_X
12079     printf(" No X Windows forwarding\n");
12080     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12081 #endif /* CK_FORWARD_X */
12082 #ifndef TN_COMPORT
12083     printf(" No Telnet Remote Com Port Control Option\n");
12084     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12085 #endif /* TN_COMPORT */
12086 #ifndef CK_SOCKS
12087     printf(" No SOCKS\n");
12088     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12089 #endif /* CK_SOCKS */
12090 #ifndef NEWFTP
12091     printf(" No built-in FTP client\n");
12092     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12093 #endif /* NEWFTP */
12094 #ifdef NOHTTP
12095     printf(" No built-in HTTP client\n");
12096     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12097 #endif /* NOHTTP */
12098
12099 #ifdef NODIAL
12100     printf(" No DIAL command\n");
12101     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12102     flag = 1;
12103 #else
12104 #ifdef MINIDIAL
12105     printf(" Support for most modem types excluded\n");
12106     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12107     flag = 1;
12108 #endif /* MINIDIAL */
12109 #endif /* NODIAL */
12110 #endif /* NOLOCAL */
12111
12112 #ifndef CK_RTSCTS
12113 #ifndef MAC
12114     printf(" No hardware flow control\n");
12115     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12116     flag = 1;
12117 #endif /* MAC */
12118 #endif /* CK_RTSCTS */
12119
12120 #ifdef NOXMIT
12121     printf(" No TRANSMIT command\n");
12122     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12123     flag = 1;
12124 #endif /* NOXMIT */
12125
12126 #ifdef NOSCRIPT
12127     printf(" No SCRIPT command\n");
12128     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12129     flag = 1;
12130 #endif /* NOSCRIPT */
12131
12132 #ifdef NOSPL
12133     printf(" No script programming features\n");
12134     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12135     flag = 1;
12136 #endif /* NOSPL */
12137
12138 #ifdef NOCSETS
12139     printf(" No character-set translation\n");
12140     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12141     flag = 1;
12142 #else
12143
12144 #ifndef LATIN2
12145     printf(" No Latin-2 character-set translation\n");
12146     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12147     flag = 1;
12148 #endif /* LATIN2 */
12149
12150 #ifdef NOGREEK
12151     printf(" No Greek character-set translation\n");
12152     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12153     flag = 1;
12154 #endif /* NOGREEK */
12155
12156 #ifdef NOHEBREW
12157     printf(" No Hebrew character-set translation\n");
12158     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12159     flag = 1;
12160 #endif /* NOHEBREW */
12161
12162 #ifdef NOUNICODE
12163     printf(" No Unicode character-set translation\n");
12164     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12165     flag = 1;
12166 #endif /* NOUNICODE */
12167
12168 #ifdef NOCYRIL
12169     printf(" No Cyrillic character-set translation\n");
12170     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12171     flag = 1;
12172 #endif /* NOCYRIL */
12173
12174 #ifndef KANJI
12175     printf(" No Kanji character-set translation\n");
12176     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12177     flag = 1;
12178 #endif /* KANJI */
12179 #endif /* NOCSETS */
12180
12181 #ifdef NOCMDL
12182     printf(" No command-line arguments\n");
12183     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12184     flag = 1;
12185 #endif /* NOCMDL */
12186
12187 #ifdef NOPUSH
12188     printf(" No escape to system\n");
12189     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12190     flag = 1;
12191 #endif /* NOPUSH */
12192
12193 #ifdef NOJC
12194 #ifdef UNIX
12195     printf(" No UNIX job control\n");
12196     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12197     flag = 1;
12198 #endif /* UNIX */
12199 #endif /* NOJC */
12200
12201 #ifdef NOSETKEY
12202     printf(" No SET KEY command\n");
12203     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12204     flag = 1;
12205 #endif /* NOSETKEY */
12206
12207 #ifndef CK_REDIR
12208     printf(" No REDIRECT or PIPE command\n");
12209     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12210     flag = 1;
12211 #endif /* CK_REDIR */
12212
12213 #ifdef UNIX
12214 #ifndef NETPTY
12215     printf(" No pseudoterminal control\n");
12216     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12217     flag = 1;
12218 #endif /* NETPTY */
12219 #endif /* UNIX */
12220
12221 #ifndef CK_RESEND
12222     printf(" No RESEND command\n");
12223     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12224     flag = 1;
12225 #endif /* CK_RESEND */
12226
12227 #ifdef OS2
12228 #ifdef __32BIT__
12229 #ifndef OS2MOUSE
12230     printf(" No Mouse support\n");
12231     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12232     flag = 1;
12233 #endif /* __32BIT__ */
12234 #endif /* OS2 */
12235 #endif /* OS2MOUSE */
12236
12237 #ifdef OS2
12238 #ifndef NT
12239 #ifndef CK_REXX
12240     printf(" No REXX script language interface\n");
12241     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12242     flag = 1;
12243 #endif /* CK_REXX */
12244 #endif /* NT */
12245 #endif /* OS2 */
12246
12247 #ifndef IKSD
12248     printf(" No Internet Kermit Service\n");
12249     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12250     flag = 1;
12251 #endif /* IKSD */
12252
12253     if (flag == 0) {
12254         printf(" None\n");
12255         if (++lines > cmd_rows - 3)
12256           { if (!askmore()) return(1); else lines = 0; }
12257     }
12258     printf("\n");
12259     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12260
12261 #ifdef CK_UTSNAME
12262     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12263     printf("Host info:\n");
12264     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12265     printf(" Machine:    %s\n",unm_mch[0] ? unm_mch : "(unknown)");
12266     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12267     printf(" Model:      %s\n",unm_mod[0] ? unm_mod : "(unknown)");
12268     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12269     printf(" OS:         %s\n",unm_nam[0] ? unm_nam : "(unknown)");
12270     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12271     printf(" OS Release: %s\n",unm_rel[0] ? unm_rel : "(unknown)");
12272     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12273     printf(" OS Version: %s\n",unm_ver[0] ? unm_ver : "(unknown)");
12274     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12275     printf("\n");
12276     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12277 #endif /* CK_UTSNAME */
12278
12279 /*
12280   Print compile-time (-D) options, as well as C preprocessor
12281   predefined symbols that might affect us...
12282 */
12283 #ifdef KTARGET
12284     {
12285         char * s;                       /* Makefile target */
12286         s = KTARGET;
12287         if (!s) s = "";
12288         if (!*s) s = "(unknown)";
12289         printf("\n");
12290         if (++lines > cmd_rows - 3) {
12291             if (!askmore()) return(1); else lines = 0;
12292         }
12293         printf("Target: %s\n", s);
12294         if (++lines > cmd_rows - 3) {
12295             if (!askmore()) return(1); else lines = 0;
12296         }
12297     }
12298 #endif /* KTARGET */
12299
12300 #ifdef __VERSION__
12301 #ifdef __GNUC__
12302     printf("GCC version: %s\n", __VERSION__);
12303 #else
12304     printf("Compiler version: %s\n", __VERSION__);
12305 #endif /* __GNUC__ */
12306     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12307 #endif /* __VERSION__ */
12308
12309 #ifdef __DATE__                         /* GNU and other ANSI */
12310 #ifdef __TIME__
12311     printf("Compiled %s %s, options:\n", __DATE__, __TIME__);
12312 #else
12313     printf("Compiled %s, options:\n", __DATE__);
12314 #endif /* __TIME__ */
12315 #else /* !__DATE__ */
12316     printf("Compiler options:\n");
12317 #endif /* __DATE__ */
12318     if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12319
12320     for (i = 0; i < noptlist; i++)      /* Print sorted option list */
12321       if (!prtopt(&lines,optlist[i]))
12322         return(0);
12323
12324     if (!prtopt(&lines,"")) return(0);  /* Start a new section */
12325
12326 /* Sizes of data types */
12327
12328     ckmakmsg(line,
12329              LINBUFSIZ,
12330              "byte order: ",
12331              byteorder ? "little" : "big",
12332              " endian",
12333              NULL
12334              );
12335     if (!prtopt(&lines,line)) return(0);
12336     if (!prtopt(&lines,"")) return(0);  /* Start a new section */
12337     sprintf(line,"sizeofs: int=%d",sizeof(int)); /* SAFE */
12338     if (!prtopt(&lines,line)) return(0);
12339     sprintf(line,"long=%d",sizeof(long)); /* SAFE */
12340     if (!prtopt(&lines,line)) return(0);
12341
12342 #ifdef COMMENT
12343 #ifdef CK_LONGLONG
12344     sprintf(line,"long long=%d",sizeof(long long)); /* SAFE */
12345     if (!prtopt(&lines,line)) return(0);
12346 #endif /* CK_LONGLONG */
12347 #endif  /* COMMENT */
12348
12349 #ifndef OS2
12350     /* Windows doesn't have off_t */
12351     sprintf(line,"off_t=%d",sizeof(off_t)); /* SAFE */
12352     if (!prtopt(&lines,line)) return(0);
12353 #endif /* OS2 */
12354
12355     sprintf(line,"CK_OFF_T=%d",sizeof(CK_OFF_T)); /* SAFE */
12356     if (!prtopt(&lines,line)) return(0);
12357
12358 #ifdef BIGBUFOK
12359     sprintf(line,"size_t=%d",sizeof(size_t)); /* SAFE */
12360     if (!prtopt(&lines,line)) return(0);
12361 #endif /* BIGBUFOK */
12362
12363     sprintf(line,"short=%d",sizeof(short)); /* SAFE */
12364     if (!prtopt(&lines,line)) return(0);
12365     sprintf(line,"char=%d",sizeof(char)); /* SAFE */
12366     if (!prtopt(&lines,line)) return(0);
12367     sprintf(line,"char*=%d",sizeof(char *)); /* SAFE */
12368     if (!prtopt(&lines,line)) return(0);
12369     sprintf(line,"float=%d",sizeof(float)); /* SAFE */
12370     if (!prtopt(&lines,line)) return(0);
12371     sprintf(line,"double=%d",sizeof(double)); /* SAFE */
12372     if (!prtopt(&lines,line)) return(0);
12373 #ifdef FNFLOAT
12374     if (!prtopt(&lines,"")) return(0);  /* Start a new section */
12375     if (!prtopt(&lines,"floating-point:")) return(0);
12376     sprintf(line,"precision=%d",fp_digits); /* SAFE */
12377     if (!prtopt(&lines,line)) return(0);
12378     sprintf(line,"rounding=%d",fp_rounding); /* SAFE */
12379     if (!prtopt(&lines,line)) return(0);
12380 #endif /* FNFLOAT */
12381
12382     prtopt(&lines,"");
12383     return(0);
12384 }
12385 #endif /* NOSHOW */
12386 #endif /* NOICP */