1 #include "ckcsym.h"
2
3 int xcmdsrc = 0;
4
5 #ifdef NOICP
cmdsrc()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, New York City
15 Jeffrey E Altman <jaltman@secure-endpoints.com>
16 Secure Endpoints Inc., New York City
17
18 Copyright (C) 1985, 2021,
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 char lasttakeline[TMPBUFSIZ+1]; /* Last TAKE-file line */
39
40 #ifndef NOICP
41
42 #include "ckcnet.h"
43 #ifndef NOCSETS
44 #include "ckcxla.h"
45 #endif /* NOCSETS */
46 #ifdef MAC
47 #include "ckmasm.h"
48 #endif /* MAC */
49 #ifdef CK_SSL
50 #include "ck_ssl.h"
51 #endif /* CK_SSL */
52
53 extern char * ck_cryear; /* (ckcmai.c) Latest C-Kermit copyright year */
54
55 #ifdef OS2
56 #include "ckoetc.h"
57 #ifndef NT
58 #define INCL_NOPM
59 #define INCL_VIO /* Needed for ckocon.h */
60 #include <os2.h>
61 #undef COMMENT
62 #else /* NT */
63 #include <windows.h>
64 #define TAPI_CURRENT_VERSION 0x00010004
65 #include <tapi.h>
66 #include <mcx.h>
67 #include "ckntap.h"
68 #define APIRET ULONG
69 extern int DialerHandle;
70 extern int StartedFromDialer;
71 #endif /* NT */
72 #include "ckocon.h"
73 #include "ckokey.h"
74 #ifdef KUI
75 #include "ikui.h"
76 #endif /* KUI */
77 #ifdef putchar
78 #undef putchar
79 #endif /* putchar */
80 #define putchar(x) conoc(x)
81 extern int cursor_save ;
82 extern bool cursorena[] ;
83 #endif /* OS2 */
84
85 /* 2010-03-09 SMS. VAX C V3.1-051 needs <stat.h> for off_t. */
86 #ifdef VMS
87 #include <stat.h>
88 #endif /* def VMS */
89
90 /* For formatted screens, "more?" prompting, etc. */
91
92 #ifdef FT18
93 #define isxdigit(c) isdigit(c)
94 #endif /* FT18 */
95
96 #ifdef STRATUS /* Stratus Computer, Inc. VOS */
97 #ifdef putchar
98 #undef putchar
99 #endif /* putchar */
100 #define putchar(x) conoc(x)
101 #ifdef getchar
102 #undef getchar
103 #endif /* getchar */
104 #define getchar(x) coninc(0)
105 #endif /* STRATUS */
106
107 /* External variables */
108
109 extern int carrier, cdtimo, local, quiet, backgrd, bgset, sosi, xsuspend,
110 binary, escape, xargs, flow, cmdmsk, duplex, ckxech, seslog, what,
111 inserver, diractive, tlevel, cwdf, nfuncs, msgflg, remappd, hints, mdmtyp,
112 zincnt, cmask, rcflag, success, xitsta, pflag, tnlm, tn_nlm, xitwarn,
113 debses, xaskmore, parity, saveask, wasclosed, whyclosed, cdactive,
114 rcdactive, keepallchars, cmd_err;
115
116 #ifdef LOCUS
117 extern int locus, autolocus;
118 #endif /* LOCUS */
119
120 #ifndef NOMSEND
121 extern int addlist;
122 #endif /* NOMSEND */
123
124 #ifdef CK_SPEED
125 extern int prefixing;
126 #endif /* CK_SPEED */
127
128 extern int g_matchdot;
129
130 #ifdef RECURSIVE
131 extern int recursive;
132 #endif /* RECURSIVE */
133 extern int xfiletype;
134
135 #ifdef IKSDCONF
136 extern char * iksdconf;
137 extern int iksdcf;
138 #endif /* IKSDCONF */
139
140 #ifdef CK_RECALL
141 extern int on_recall;
142 #endif /* CK_RECALL */
143
144 extern int ngetpath, exitonclose;
145 extern char * getpath[];
146 extern CHAR * epktmsg;
147
148 extern char * snd_move;
149 extern char * snd_rename;
150 extern char * rcv_move;
151 extern char * rcv_rename;
152 extern char * g_snd_move;
153 extern char * g_snd_rename;
154 extern char * g_rcv_move;
155 extern char * g_rcv_rename;
156
157 extern char * nm[];
158
159 #ifdef CK_UTSNAME
160 extern char unm_mch[];
161 extern char unm_mod[];
162 extern char unm_nam[];
163 extern char unm_rel[];
164 extern char unm_ver[];
165 #endif /* CK_UTSNAME */
166
167 #ifndef NOPUSH
168 #ifndef NOFRILLS
169 extern char editor[];
170 extern char editfile[];
171 extern char editopts[];
172 #ifdef BROWSER
173 extern char browser[];
174 extern char browsopts[];
175 extern char browsurl[];
176 #endif /* BROWSER */
177 #endif /* NOFRILLS */
178 #endif /* NOPUSH */
179
180 #ifndef NOFRILLS
181 #ifndef NORENAME
182 _PROTOTYP(VOID shorename, (void));
183 #endif /* NORENAME */
184 #endif /* NOFRILLS */
185
186 #ifndef NOSERVER
187 extern char * x_user, * x_passwd, * x_acct;
188 #endif /* NOSERVER */
189
190 #ifdef CKLOGDIAL
191 extern int dialog;
192 extern char diafil[];
193 #endif /* CKLOGDIAL */
194
195 #ifdef CKROOT
196 extern int ckrooterr;
197 #endif /* CKROOT */
198
199 #ifndef NOSPL
200 extern int cfilef, xxdot, vareval;
201 extern char cmdfil[];
202
203 struct localvar * localhead[CMDSTKL];
204 struct localvar * localtail = NULL;
205 struct localvar * localnext = NULL;
206
207 _PROTOTYP( VOID shosexp, (void) );
208 _PROTOTYP( static VOID shoinput, (void) );
209 _PROTOTYP( static char gettok, (void) );
210 _PROTOTYP( static VOID factor, (void) );
211 _PROTOTYP( static VOID term, (void) );
212 _PROTOTYP( static VOID termp, (void) );
213 _PROTOTYP( static VOID exprp, (void) );
214 _PROTOTYP( static VOID expr, (void) );
215 _PROTOTYP( static VOID simple, (void) );
216 _PROTOTYP( static VOID simpler, (void) );
217 _PROTOTYP( static VOID simplest, (void) );
218 _PROTOTYP( static CK_OFF_T xparse, (void) );
219 #endif /* NOSPL */
220 #ifndef NOSHOW
221 _PROTOTYP( int sho_iks, (void) );
222 #endif /* NOSHOW */
223
224 #ifdef MAC
225 char * ckprompt = "Mac-Kermit>"; /* Default prompt for Macintosh */
226 char * ikprompt = "IKSD>";
227 #else /* Not MAC */
228 #ifdef NOSPL
229 #ifdef OS2
230 char * ckprompt = "K-95> "; /* Default prompt for Win32 */
231 char * ikprompt = "IKSD> ";
232 #else
233 char * ckprompt = "C-Kermit>";
234 char * ikprompt = "IKSD>";
235 #endif /* NT */
236 #else /* NOSPL */
237 #ifdef OS2
238 /* Default prompt for OS/2 and Win32 */
239 /* fdc 2013-12-06 - C-Kermit 9.0 and later is just "C-Kermit" */
240 #ifdef NT
241 #ifdef COMMENT
242 char * ckprompt = "[\\freplace(\\flongpath(\\v(dir)),/,\\\\)] K-95> ";
243 #else
244 char * ckprompt = "[\\freplace(\\flongpath(\\v(dir)),/,\\\\)] C-Kermit> ";
245 #endif /* COMMENT */
246 char * ikprompt = "[\\freplace(\\flongpath(\\v(dir)),/,\\\\)] IKSD> ";
247 #else /* NT */
248 #ifdef COMMENT
249 char * ckprompt = "[\\freplace(\\v(dir),/,\\\\)] K-95> ";
250 #else
251 char * ckprompt = "[\\freplace(\\v(dir),/,\\\\)] C-Kermit> ";
252 #endif /* COMMENT */
253 char * ikprompt = "[\\freplace(\\v(dir),/,\\\\)] IKSD> ";
254 #endif /* NT */
255 #else /* OS2 */
256 #ifdef VMS
257 char * ckprompt = "\\v(dir) C-Kermit>"; /* Default prompt VMS */
258 char * ikprompt = "\\v(dir) IKSD>";
259 #else
260 #ifdef UNIX
261 /* Note: parens, not brackets, because of ISO646 */
262 /* Collapse long paths using ~ notation if in home directory tree */
263 char * ckprompt = "(\\freplace(\\v(dir),\\fpathname(\\v(home)),~/)) C-Kermit>";
264 char * ikprompt = "(\\freplace(\\v(dir),\\fpathname(\\v(home)),~/)) IKSD>";
265 #else
266 /* Default prompt for other platforms */
267 char * ckprompt = "(\\v(dir)) C-Kermit>"; /* Default prompt for others */
268 char * ikprompt = "(\\v(dir)) IKSD>";
269 #endif /* UNIX */
270 #endif /* VMS */
271 #endif /* NT */
272 #endif /* NOSPL */
273 #endif /* MAC */
274
275 #ifndef CCHMAXPATH
276 #define CCHMAXPATH 257
277 #endif /* CCHMAXPATH */
278 char inidir[CCHMAXPATH] = { NUL, NUL }; /* Directory INI file executed from */
279
280 #ifdef TNCODE
281 extern int tn_b_nlm; /* TELNET BINARY newline mode */
282 #endif /* TNCODE */
283
284 #ifndef NOKVERBS
285 extern struct keytab kverbs[]; /* Table of \Kverbs */
286 extern int nkverbs; /* Number of \Kverbs */
287 #endif /* NOKVERBS */
288
289 #ifndef NOPUSH
290 extern int nopush;
291 #endif /* NOPUSH */
292
293 #ifdef CK_RECALL
294 extern int cm_recall;
295 #endif /* CK_RECALL */
296
297 extern char *ccntab[];
298
299 /* Printer stuff */
300
301 extern char *printername;
302 extern int printpipe;
303 #ifdef BPRINT
304 extern int printbidi, pportparity, pportflow;
305 extern long pportspeed;
306 #endif /* BPRINT */
307
308 #ifdef OS2
309 _PROTOTYP (int os2getcp, (void) );
310 _PROTOTYP (int os2getcplist, (int *, int) );
311 #ifdef OS2MOUSE
312 extern int tt_mouse;
313 #endif /* OS2MOUSE */
314 extern int tt_update, tt_updmode, updmode, tt_utf8;
315 #ifndef IKSDONLY
316 extern int tt_status[];
317 #endif /* IKSDONLY */
318 #ifdef PCFONTS
319 extern struct keytab term_font[];
320 #else
321 #ifdef KUI
322 extern struct keytab * term_font;
323 #endif /* KUI */
324 #endif /* PCFONTS */
325 extern int ntermfont, tt_font, tt_font_size;
326 extern unsigned char colornormal, colorunderline, colorstatus,
327 colorhelp, colorselect, colorborder, colorgraphic, colordebug,
328 colorreverse, colorcmd, coloritalic;
329 extern int priority;
330 extern struct keytab prtytab[];
331 extern int nprty;
332 char * cmdmac = NULL;
333 #endif /* OS2 */
334
335 #ifdef VMS
336 _PROTOTYP (int zkermini, (char *, int, char *) );
337 #endif /* VMS */
338
339 extern long vernum;
340 extern int inecho, insilence, inbufsize, nvars, inintr;
341 extern char *protv, *fnsv, *cmdv, *userv, *ckxv, *ckzv, *ckzsys, *xlav,
342 *cknetv, *clcmds;
343 #ifdef OS2
344 extern char *ckyv;
345 #endif /* OS2 */
346 #ifdef CK_AUTHENTICATION
347 extern char * ckathv;
348 #endif /* CK_AUTHENTICATION */
349 #ifdef CK_SSL
350 extern char * cksslv;
351 #endif /* CK_SSL */
352 #ifdef CK_ENCRYPTION
353 #ifndef CRYPT_DLL
354 extern char * ckcrpv;
355 #endif /* CRYPT_DLL */
356 #endif /* CK_ENCRYPTION */
357
358 #ifdef SSHBUILTIN
359 extern char *cksshv;
360 #ifdef SFTP_BUILTIN
361 extern char *cksftpv;
362 #endif /* SFTP_BUILTIN */
363 #endif /* SSHBUILTIN */
364
365 #ifdef TNCODE
366 extern char *cktelv;
367 #endif /* TNCODE */
368 #ifndef NOFTP
369 #ifndef SYSFTP
370 extern char * ckftpv;
371 #endif /* SYSFTP */
372 #endif /* NOFTP */
373
374 extern int srvidl;
375
376 #ifdef OS2
377 extern char *ckonetv;
378 extern int interm;
379 #ifdef CK_NETBIOS
380 extern char *ckonbiv;
381 #endif /* CK_NETBIOS */
382 #ifdef OS2MOUSE
383 extern char *ckomouv;
384 #endif /* OS2MOUSE */
385 #endif /* OS2 */
386
387 #ifndef NOLOCAL
388 extern char *connv;
389 #endif /* NOLOCAL */
390 #ifndef NODIAL
391 extern char *dialv;
392 #endif /* NODIAL */
393 #ifndef NOSCRIPT
394 extern char *loginv;
395 extern int secho;
396 #endif /* NOSCRIPT */
397
398 #ifndef NODIAL
399 extern int nmdm, dirline;
400 extern struct keytab mdmtab[];
401 #endif /* NODIAL */
402
403 extern int network, nettype, ttnproto;
404
405 #ifdef OS2
406 #ifndef NOTERM
407 /* SET TERMINAL items... */
408 extern int tt_type, tt_arrow, tt_keypad, tt_wrap, tt_answer, tt_scrsize[];
409 extern int tt_bell, tt_roll[], tt_ctstmo, tt_cursor, tt_pacing, tt_type_mode;
410 extern char answerback[];
411 extern struct tt_info_rec tt_info[]; /* Indexed by terminal type */
412 extern int max_tt;
413 #endif /* NOTERM */
414 #endif /* OS2 */
415
416 _PROTOTYP( VOID shotrm, (void) );
417 _PROTOTYP( int shofea, (void) );
418
419 #ifdef OS2
420 extern int tt_rows[], tt_cols[];
421 #else /* OS2 */
422 extern int tt_rows, tt_cols;
423 #endif /* OS2 */
424 extern int cmd_rows, cmd_cols;
425
426 #ifdef CK_TMPDIR
427 extern int f_tmpdir; /* Directory changed temporarily */
428 extern char savdir[]; /* Temporary directory */
429 #endif /* CK_TMPDIR */
430
431 #ifndef NOLOCAL
432 extern int tt_crd, tt_lfd, tt_escape;
433 #endif /* NOLOCAL */
434
435 #ifndef NOCSETS
436 extern int language, nfilc, tcsr, tcsl, tcs_transp, fcharset;
437 extern struct keytab fcstab[];
438 extern struct csinfo fcsinfo[];
439 #ifndef MAC
440 extern struct keytab ttcstab[];
441 #endif /* MAC */
442 #endif /* NOCSETS */
443
444 extern long speed;
445
446 #ifndef NOXMIT
447 extern int xmitf, xmitl, xmitp, xmitx, xmits, xmitw, xmitt;
448 extern char xmitbuf[];
449 #endif /* NOXMIT */
450
451 extern char **xargv, *versio, *ckxsys, *dftty, *lp;
452
453 #ifdef DCMDBUF
454 extern char *cmdbuf, *atmbuf; /* Command buffers */
455 #ifndef NOSPL
456 extern char *savbuf; /* Command buffers */
457 #endif /* NOSPL */
458 #else
459 extern char cmdbuf[], atmbuf[]; /* Command buffers */
460 #ifndef NOSPL
461 extern char savbuf[]; /* Command buffers */
462 #endif /* NOSPL */
463 #endif /* DCMDBUF */
464
465 extern char toktab[], ttname[], psave[];
466 extern CHAR sstate, feol;
467 extern int cmflgs, techo, repars, ncmd;
468 extern struct keytab cmdtab[];
469
470 #ifndef NOSETKEY
471 KEY *keymap;
472 #ifndef OS2
473 #define mapkey(x) keymap[x]
474 #endif /* OS2 */
475 MACRO *macrotab;
476 _PROTOTYP( VOID shostrdef, (CHAR *) );
477 #endif /* NOSETKEY */
478
479 extern int cmdlvl;
480
481 #ifndef NOSPL
482 extern struct mtab *mactab;
483 extern struct keytab mackey[];
484 extern struct keytab vartab[], fnctab[], iftab[];
485 extern int maclvl, nmac, mecho, fndiags, fnerror, fnsuccess, nif;
486 #endif /* NOSPL */
487
488 FILE *tfile[MAXTAKE]; /* TAKE file stack */
489 char *tfnam[MAXTAKE]; /* Name of TAKE file */
490 int tfline[MAXTAKE]; /* Current line number */
491 int tfblockstart[MAXTAKE]; /* Current block-start line */
492
493 int topcmd = -1; /* cmdtab index of current command */
494 int havetoken = 0;
495 extern int dblquo; /* Doublequoting enabled */
496
497 #ifdef DCMDBUF /* Initialization filespec */
498 char *kermrc = NULL;
499 #else
500 char kermrcb[KERMRCL];
501 char *kermrc = kermrcb;
502 #endif /* DCMDBUF */
503
504 int noherald = 0;
505 int cm_retry = 1; /* Command retry enabled */
506 xx_strp xxstring = zzstring;
507
508 #ifndef NOXFER
509 extern int displa, bye_active, protocol, pktlog, remfile, rempipe, unkcs,
510 keep, lf_opts, fncnv, pktpaus, autodl, xfrcan, xfrchr, xfrnum, srvtim,
511 srvdis, query, retrans, streamed, reliable, crunched, timeouts,
512 fnrpath, autopath, rpackets, spackets, epktrcvd, srvping;
513
514 #ifdef CK_AUTODL
515 extern int inautodl, cmdadl;
516 #endif /* CK_AUTODL */
517
518 #ifndef NOSERVER
519 extern int en_asg, en_cwd, en_cpy, en_del, en_dir, en_fin, en_bye, en_ret,
520 en_get, en_hos, en_que, en_ren, en_sen, en_set, en_spa, en_typ, en_who,
521 en_mai, en_pri, en_mkd, en_rmd, en_xit, en_ena;
522 #endif /* NOSERVER */
523
524 extern int atcapr,
525 atenci, atenco, atdati, atdato, atleni, atleno, atblki, atblko,
526 attypi, attypo, atsidi, atsido, atsysi, atsyso, atdisi, atdiso;
527
528 #ifdef STRATUS
529 extern int atfrmi, atfrmo, atcrei, atcreo, atacti, atacto;
530 #endif /* STRATUS */
531
532 #ifdef CK_PERMS
533 extern int atlpri, atlpro, atgpri, atgpro;
534 #endif /* CK_PERMS */
535
536 #ifdef CK_LOGIN
537 extern char * anonfile; /* Anonymous login init file */
538 extern char * anonroot; /* Anonymous file-system root */
539 extern char * userfile; /* Forbidden user file */
540 extern int isguest; /* Flag for anonymous user */
541 #endif /* CK_LOGIN */
542 #endif /* NOXFER */
543
544 #ifdef DCMDBUF
545 int *xquiet = NULL;
546 int *xvarev = NULL;
547 #else
548 int xquiet[CMDSTKL];
549 int xvarev[CMDSTKL];
550 #endif /* DCMDBUF */
551
552 char * prstring[CMDSTKL];
553
554 #ifndef NOSPL
555
556 extern long ck_alarm;
557 extern char alrm_date[], alrm_time[];
558
559 /* Local declarations */
560
561 static int nulcmd = 0; /* Flag for next cmd to be ignored */
562
563 /* Definitions for predefined macros */
564
565 /* First, the single-line macros, installed with addmac()... */
566
567 /* IBM-LINEMODE macro */
568 char *m_ibm = "set parity mark, set dupl half, set handsh xon, set flow none";
569
570 /* FATAL macro */
571 char *m_fat = "if def \\%1 echo \\%1, if not = \\v(local) 0 hangup, stop 1";
572
573 #ifdef CK_SPEED
574 #ifdef IRIX65
575 char *m_fast = "set win 30, set rec pack 4000, set prefix cautious";
576 #else
577 #ifdef IRIX
578 /* Because of bug in telnet server */
579 char *m_fast = "set window 30, set rec pack 4000, set send pack 4000,\
580 set pref cautious";
581 #else
582 #ifdef pdp11
583 char *m_fast = "set win 3, set rec pack 1024, set prefix cautious";
584 #else
585 #ifdef BIGBUFOK
586 char *m_fast = "set win 30, set rec pack 4000, set prefix cautious";
587 #else
588 char *m_fast = "set win 4, set rec pack 2200, set prefix cautious";
589 #endif /* BIGBUFOK */
590 #endif /* IRIX */
591 #endif /* IRIX65 */
592 #endif /* pdp11 */
593 #ifdef pdp11
594 char *m_cautious = "set win 2, set rec pack 512, set prefixing cautious";
595 #else
596 char *m_cautious = "set win 4, set rec pack 1000, set prefixing cautious";
597 #endif /* pdp11 */
598 char *m_robust = "set win 1, set rec pack 90, set prefixing all, \
599 set reliable off, set clearchannel off, set send timeout 20 fixed";
600 #else
601 #ifdef BIGBUFOK
602 #ifdef IRIX65
603 char *m_fast = "set win 30, set rec pack 4000";
604 #else
605 #ifdef IRIX
606 char *m_fast = "set win 30, set rec pack 4000, set send pack 4000";
607 #else
608 char *m_fast = "set win 30, set rec pack 4000";
609 #endif /* IRIX */
610 #endif /* IRIX65 */
611 #else /* Not BIGBUFOK */
612 char *m_fast = "set win 4, set rec pack 2200";
613 #endif /* BIGBUFOK */
614 char *m_cautious = "set win 4, set rec pack 1000";
615 char *m_robust = "set win 1, set rec pack 90, set reliable off,\
616 set send timeout 20 fixed";
617 #endif /* CK_SPEED */
618
619 #ifdef VMS
620 char *m_purge = "run purge \\%*";
621 #endif /* VMS */
622
623 #ifdef OS2
624 char *m_manual = "browse \\v(exedir)docs/manual/kermit95.htm";
625 #endif /* OS2 */
626
627 /* Now the multiline macros, defined with addmmac()... */
628
629 /*
630 Kermit's scripting language is so much more powerful than C that it was
631 about a thousand time easier to implement FOR, WHILE, IF, and SWITCH
632 commands as internal Kermit macros. This was done in 1996 for C-Kermit 6.0.
633
634 The following definitions, down to #ifdef COMMENT, are from C-Kermit
635 9.0.304 Dev.22, April 2017, where the command parser was changed to not
636 evaluate macro arguments on the DO command line, but to defer evaluation
637 until after the arguments had been separated and counted. This change
638 required subtle modifications to the internal macro templates.
639
640 IMPORTANT: Internal macros must have names that start with '_', followed
641 by three letters, e.g. _whi for WHILE. The definitions below are just
642 templates for some other code that constructs the actual menu to be
643 executed by filling in the \%x variables. The generated macros have names
644 like _whil2, _whil3, etc, where the trailing number is the execution stack
645 level. The reason for the strict naming convention is so internal macros
646 can be parsed differently than regular ones. See
647 ckuusr.c:isinternalmacro(), which determines the type of macro.
648 */
649
650 /*
651 The WHILE macro:
652 \%1 = Loop condition
653 \%2 = Loop body
654 */
655 char *whil_def[] = { "_assign _whi\\v(cmdlevel) {_getargs,",
656 ":_..inc,\\fcontents(\\%1),\\fcontents(\\%2),goto _..inc,:_..bot,_putargs},",
657 "_define break goto _..bot, _define continue goto _..inc,",
658 "do _whi\\v(cmdlevel),_assign _whi\\v(cmdlevel)",
659 ""};
660
661 /*
662 FOR macro for \%i-style loop variables (see dofor()...)
663 \%1 = Loop variable
664 \%2 = Initial value (can be an expression)
665 \%3 = Loop exit value
666 \%4 = Loop increment
667 \%5 = > or <
668 \%6 = Loop body
669 */
670 char *for_def[] = { "_assign _for\\v(cmdlevel) { _getargs,",
671 "define \\\\\\%1 \\feval(\\%2),:_..top,if \\%5 \\\\\\%1 \\%3 goto _..bot,",
672 "\\fcontents(\\%6),:_..inc,incr \\\\\\%1 \\%4,goto _..top,:_..bot,_putargs},",
673 "define break goto _..bot, define continue goto _..inc,",
674 "do _for\\v(cmdlevel) \\\\%1 \\%2 \\%3 \\%4 { \\%5 },_assign _for\\v(cmdlevel)",
675 ""};
676
677 /*
678 FOR macro when the loop variable is itself a macro, with same arguments
679 but slightly different quoting.
680 */
681 char *foz_def[] = { "_assign _for\\v(cmdlevel) { _getargs,",
682 "def \\%1 \\feval(\\%2),:_..top,if \\%5 \\%1 \\%3 goto _..bot,",
683 "\\fcontents(\\%6),:_..inc,incr \\%1 \\%4,goto _..top,:_..bot,_putargs},",
684 "def break goto _..bot, def continue goto _..inc,",
685 "do _for\\v(cmdlevel) \\%1 \\%2 \\%3 \\%4 { \\%5 },_assign _for\\v(cmdlevel)",
686 ""};
687
688 /*
689 SWITCH macro
690 \%1 = Switch variable
691 \%2 = Switch body
692 */
693 char *sw_def[] = { "_assign _sw_\\v(cmdlevel) {_getargs,",
694 "_forward {\\fcontents(\\%1)},\\fcontents(\\%2),:default,:_..bot,_putargs},_def break goto _..bot,",
695 "do _sw_\\v(cmdlevel),_assign _sw_\\v(cmdlevel)",
696 ""};
697
698 /*
699 IF macro
700 /%1 = Commands to execute (IF part and ELSE part if any)
701 */
702 char *xif_def[] = {
703 "_assign _if_\\v(cmdlevel) {_getargs,\\fcontents(\\%1),_putargs},",
704 "do _if_\\v(cmdlevel),_assign _if\\v(cmdlevel)",
705 ""};
706
707 #ifdef COMMENT
708 /* Internal macro definitions for C-Kermit 6.0 through 9.0.302 */
709
710 char *for_def[] = { "_assign _for\\v(cmdlevel) { _getargs,",
711 "def \\\\\\%1 \\feval(\\%2),:_..top,if \\%5 \\\\\\%1 \\%3 goto _..bot,",
712 "\\%6,:_..inc,incr \\\\\\%1 \\%4,goto _..top,:_..bot,_putargs},",
713 "def break goto _..bot, def continue goto _..inc,",
714 "do _for\\v(cmdlevel) \\%1 \\%2 \\%3 \\%4 { \\%5 },_assign _for\\v(cmdlevel)",
715 ""};
716
717 char *foz_def[] = { "_assign _for\\v(cmdlevel) { _getargs,",
718 "def \\%1 \\feval(\\%2),:_..top,if \\%5 \\%1 \\%3 goto _..bot,",
719 "\\%6,:_..inc,incr \\%1 \\%4,goto _..top,:_..bot,_putargs},",
720 "def break goto _..bot, def continue goto _..inc,",
721 "do _for\\v(cmdlevel) \\%1 \\%2 \\%3 \\%4 { \\%5 },_assign _for\\v(cmdlevel)",
722 ""};
723
724 /* SWITCH macro */
725 char *sw_def[] = { "_assign _sw_\\v(cmdlevel) {_getargs,",
726 "_forward {\\%1},\\%2,:default,:_..bot,_putargs},_def break goto _..bot,",
727 "do _sw_\\v(cmdlevel),_assign _sw_\\v(cmdlevel)",
728 ""};
729
730 /* XIF macro */
731 char *xif_def[] = {
732 "_assign _if\\v(cmdlevel) {_getargs,\\%1,_putargs},",
733 "do _if\\v(cmdlevel),_assign _if\\v(cmdlevel)",
734 ""};
735
736 #endif /* COMMENT */
737
738 /*
739 Variables declared here for use by other ckuus*.c modules.
740 Space is allocated here to save room in ckuusr.c.
741 */
742 #ifdef DCMDBUF
743 struct cmdptr *cmdstk;
744 int
745 *ifcmd = NULL,
746 *count = NULL,
747 *iftest = NULL,
748 *intime = NULL,
749 *inpcas = NULL,
750 *takerr = NULL,
751 *merror = NULL;
752 #else
753 struct cmdptr cmdstk[CMDSTKL];
754 int ifcmd[CMDSTKL], count[CMDSTKL], iftest[CMDSTKL], intime[CMDSTKL],
755 inpcas[CMDSTKL], takerr[CMDSTKL], merror[CMDSTKL];
756 #endif /* DCMDBUF */
757
758 /* Macro stack */
759
760 #ifdef COMMENT
761 char *topline = NULL; /* Program invocation arg line */
762 char *m_line[MACLEVEL] = { NULL, NULL }; /* Stack of macro invocation lines */
763 #endif /* COMMENT */
764
765 char **m_xarg[MACLEVEL]; /* Pointers to arg vector arrays */
766 int n_xarg[MACLEVEL]; /* Sizes of arg vector arrays */
767 char *m_arg[MACLEVEL][NARGS]; /* Args of each level */
768 int macargc[MACLEVEL]; /* Argc of each level */
769 char *macp[MACLEVEL]; /* Current position in each macro */
770 char *macx[MACLEVEL]; /* Beginning of each macro def */
771 char *mrval[MACLEVEL]; /* RETURN value at each level */
772 int lastcmd[MACLEVEL]; /* Last command at each level */
773 int topargc = 0; /* Argc at top level */
774 char **topxarg = NULL; /* Argv at top level */
775 char *toparg[MAXARGLIST+2];
776
777 /* Global Variables */
778
779 char *g_var[GVARS+1]; /* Global \%a..z pointers */
780 extern char varnam[]; /* \%x variable name buffer */
781
782 /* Arrays -- Dimension must be 'z' - ARRAYBASE + 1 */
783 /* Note: a_link[x] < 0 means no link; >= 0 is a link */
784
785 char **a_ptr[32]; /* Array pointers, for arrays a-z */
786 int a_dim[32]; /* Dimensions for each array */
787 int a_link[32]; /* Link (index of linked-to-array) */
788
789 char **aa_ptr[CMDSTKL][32]; /* Array stack for automatic arrays */
790 int aa_dim[CMDSTKL][32]; /* Dimensions for each array */
791
792 /* INPUT command buffers and variables */
793
794 char * inpbuf = NULL; /* Buffer for INPUT and REINPUT */
795 extern char * inpbp; /* Global/static pointer to it */
796 char inchar[2] = { NUL, NUL }; /* Last character that was INPUT */
797 int incount = 0; /* INPUT character count */
798 extern int instatus; /* INPUT status */
799 static char * i_text[] = { /* INPUT status text */
800 "success", "timeout", "interrupted", "internal error", "i/o error"
801 };
802
803 char lblbuf[LBLSIZ]; /* Buffer for labels */
804
805 #else /* NOSPL */
806
807 int takerr[MAXTAKE];
808 #endif /* NOSPL */
809
810 static char *prevdir = NULL;
811
812 int pacing = 0; /* OUTPUT pacing */
813
814 char *tp; /* Temporary buffer pointer */
815
816 int timelimit = 0, asktimer = 0; /* Timers for time-limited commands */
817
818 #ifdef CK_APC /* Application Program Command (APC) */
819 int apcactive = APC_INACTIVE;
820 int apcstatus = APC_OFF; /* OFF by default everywhere */
821 #ifdef DCMDBUF
822 char *apcbuf;
823 #else
824 char apcbuf[APCBUFLEN];
825 #endif /* DCMDBUF */
826 #endif /* CK_APC */
827
828 extern char pktfil[],
829 #ifdef DEBUG
830 debfil[],
831 #endif /* DEBUG */
832 #ifdef TLOG
833 trafil[],
834 #endif /* TLOG */
835 sesfil[];
836
837 #ifndef NOFRILLS
838 extern int rmailf, rprintf; /* REMOTE MAIL & PRINT items */
839 extern char optbuf[];
840 #endif /* NOFRILLS */
841
842 extern int noinit; /* Flat to skip init file */
843
844 #ifndef NOSPL
845 static struct keytab kcdtab[] = { /* Symbolic directory names */
846 #ifdef NT
847 { "appdata", VN_APPDATA, 0 },
848 { "common", VN_COMMON, 0 },
849 { "desktop", VN_DESKTOP, 0 },
850 #endif /* NT */
851 { "download", VN_DLDIR, 0 },
852 #ifdef OS2ORUNIX
853 { "exedir", VN_EXEDIR, 0 },
854 #endif /* OS2ORUNIX */
855 { "home", VN_HOME, 0 },
856 { "inidir", VN_INI, 0 },
857 #ifdef UNIX
858 { "lockdir", VN_LCKDIR, 0 },
859 #endif /* UNIX */
860 #ifdef NT
861 { "my_documents",VN_PERSONAL, 0 },
862 { "personal", VN_PERSONAL, CM_INV },
863 #endif /* NT */
864 { "startup", VN_STAR, 0 },
865 { "textdir", VN_TXTDIR, 0 },
866 { "tmpdir", VN_TEMP, 0 }
867 };
868 static int nkcdtab = (sizeof(kcdtab) / sizeof(struct keytab));
869 #endif /* NOSPL */
870
871 #ifndef NOSPL
872 _PROTOTYP( VOID freelocal, (int) );
873 _PROTOTYP( static CK_OFF_T expon, (CK_OFF_T, CK_OFF_T) );
874 _PROTOTYP( static CK_OFF_T gcd, (CK_OFF_T, CK_OFF_T) );
875 _PROTOTYP( static CK_OFF_T fact, (CK_OFF_T) );
876
877 int /* Initialize macro data structures. */
macini()878 macini() { /* Allocate mactab and preset the first element. */
879 int i;
880 if (!(mactab = (struct mtab *) malloc(sizeof(struct mtab) * MAC_MAX)))
881 return(-1);
882 mactab[0].kwd = NULL;
883 mactab[0].mval = NULL;
884 mactab[0].flgs = 0;
885 for (i = 0; i < MACLEVEL; i++)
886 localhead[i] = NULL;
887 return(0);
888 }
889 #endif /* NOSPL */
890
891 /* C M D S R C -- Returns current command source */
892
893 /* 0 = top level, 1 = file, 2 = macro, -1 = error (shouldn't happen) */
894
895 /*
896 As of 19 Aug 2000 this routine is obsolete. The scalar global variable
897 xcmdsrc can be checked instead to save the overhead of a function call.
898 */
899 int
cmdsrc()900 cmdsrc() {
901 #ifdef COMMENT
902 return(xcmdsrc);
903 #else
904 #ifndef NOSPL
905 if (cmdlvl == 0)
906 return(0);
907 else if (cmdstk[cmdlvl].src == CMD_MD)
908 return(2);
909 else if (cmdstk[cmdlvl].src == CMD_TF)
910 return(1);
911 else
912 return(-1);
913 #else
914 if (tlevel < 0)
915 return(0);
916 else
917 return(1);
918 #endif /* NOSPL */
919 #endif /* COMMENT */
920 }
921
922 /* C M D I N I -- Initialize the interactive command parser */
923
924 static int cmdinited = 0; /* Command parser initialized */
925 extern int cmdint; /* Interrupts are allowed */
926 #ifdef CK_AUTODL
927 int cmdadl = 1; /* Autodownload */
928 #else
929 int cmdadl = 0;
930 #endif /* CK_AUTODL */
931
932 char * k_info_dir = NULL; /* Where to find text files */
933 #ifdef UNIX
934 static char * txtdir[] = {
935 "/usr/local/doc/", /* Linux, SunOS, ... */
936 "/usr/share/lib/", /* HP-UX 10.xx... */
937 "/usr/share/doc/", /* Other possibilities... */
938 "/usr/local/lib/", /* NOTE: Each of these is tried */
939 "/usr/local/share/", /* as is, and also with a kermit */
940 "/usr/local/share/doc/", /* subdirectory. */
941 "/usr/local/share/lib/",
942 "/opt/kermit/", /* Solaris */
943 "/opt/kermit/doc/",
944 "/opt/",
945 "/usr/doc/",
946 "/doc/",
947 ""
948 };
949 #endif /* UNIX */
950
951 /*
952 lookup() cache to speed up script execution.
953
954 This is a static cache. Items are stored in decreasing frequency of
955 reference based on statistics from a range of scripts. This gives
956 better performance than a dynamic cache, which would require a lot more
957 code and also would require system-dependent elements including system
958 calls (e.g. to get subsecond times for entry aging).
959 */
960 #ifdef USE_LUCACHE /* Set in ckuusr.h */
961 #define LUCACHE 32 /* Change this to reduce cache size */
962 int lusize = 0;
963 char * lucmd[LUCACHE];
964 int luval[LUCACHE];
965 int luidx[LUCACHE];
966 struct keytab * lutab[LUCACHE];
967 #endif /* USE_LUCACHE */
968
969 static VOID
luinit()970 luinit() { /* Initialize lookup() cache */
971 int x, y;
972
973 #ifdef USE_LUCACHE
974 x = lookup(cmdtab,"if",ncmd,&y);
975 lucmd[lusize] = "if";
976 luval[lusize] = x;
977 luidx[lusize] = y;
978 lutab[lusize] = cmdtab;
979 if (++lusize > LUCACHE) return;
980
981 x = lookup(iftab,"not",nif,&y);
982 lucmd[lusize] = "not";
983 luval[lusize] = x;
984 luidx[lusize] = y;
985 lutab[lusize] = iftab;
986 if (++lusize > LUCACHE) return;
987
988 x = lookup(vartab,"cmdlevel",nvars,&y);
989 lucmd[lusize] = "cmdlevel";
990 luval[lusize] = x;
991 luidx[lusize] = y;
992 lutab[lusize] = vartab;
993 if (++lusize > LUCACHE) return;
994
995 x = lookup(cmdtab,"goto",ncmd,&y);
996 lucmd[lusize] = "goto";
997 luval[lusize] = x;
998 luidx[lusize] = y;
999 lutab[lusize] = cmdtab;
1000 if (++lusize > LUCACHE) return;
1001
1002 x = lookup(iftab,">",nif,&y);
1003 lucmd[lusize] = ">";
1004 luval[lusize] = x;
1005 luidx[lusize] = y;
1006 lutab[lusize] = iftab;
1007 if (++lusize > LUCACHE) return;
1008
1009 x = lookup(cmdtab,"incr",ncmd,&y);
1010 lucmd[lusize] = "incr";
1011 luval[lusize] = x;
1012 luidx[lusize] = y;
1013 lutab[lusize] = cmdtab;
1014 if (++lusize > LUCACHE) return;
1015
1016 x = lookup(cmdtab,"def",ncmd,&y);
1017 lucmd[lusize] = "def";
1018 luval[lusize] = x;
1019 luidx[lusize] = y;
1020 lutab[lusize] = cmdtab;
1021 if (++lusize > LUCACHE) return;
1022
1023 x = lookup(cmdtab,"_assign",ncmd,&y);
1024 lucmd[lusize] = "_assign";
1025 luval[lusize] = x;
1026 luidx[lusize] = y;
1027 lutab[lusize] = cmdtab;
1028 if (++lusize > LUCACHE) return;
1029
1030 x = lookup(cmdtab,"echo",ncmd,&y);
1031 lucmd[lusize] = "echo";
1032 luval[lusize] = x;
1033 luidx[lusize] = y;
1034 lutab[lusize] = cmdtab;
1035 if (++lusize > LUCACHE) return;
1036
1037 x = lookup(fnctab,"eval",nfuncs,&y);
1038 lucmd[lusize] = "eval";
1039 luval[lusize] = x;
1040 luidx[lusize] = y;
1041 lutab[lusize] = fnctab;
1042 if (++lusize > LUCACHE) return;
1043
1044 x = lookup(fnctab,"lit",nfuncs,&y);
1045 lucmd[lusize] = "lit";
1046 luval[lusize] = x;
1047 luidx[lusize] = y;
1048 lutab[lusize] = fnctab;
1049 if (++lusize > LUCACHE) return;
1050
1051 x = lookup(cmdtab,"do",ncmd,&y);
1052 lucmd[lusize] = "do";
1053 luval[lusize] = x;
1054 luidx[lusize] = y;
1055 lutab[lusize] = cmdtab;
1056 if (++lusize > LUCACHE) return;
1057
1058 x = lookup(cmdtab,"_getargs",ncmd,&y);
1059 lucmd[lusize] = "_getargs";
1060 luval[lusize] = x;
1061 luidx[lusize] = y;
1062 lutab[lusize] = cmdtab;
1063 if (++lusize > LUCACHE) return;
1064
1065 x = lookup(iftab,"<",nif,&y);
1066 lucmd[lusize] = "<";
1067 luval[lusize] = x;
1068 luidx[lusize] = y;
1069 lutab[lusize] = iftab;
1070 if (++lusize > LUCACHE) return;
1071
1072 x = lookup(cmdtab,"_putargs",ncmd,&y);
1073 lucmd[lusize] = "_putargs";
1074 luval[lusize] = x;
1075 luidx[lusize] = y;
1076 lutab[lusize] = cmdtab;
1077 if (++lusize > LUCACHE) return;
1078
1079 x = lookup(cmdtab,"asg",ncmd,&y);
1080 lucmd[lusize] = "asg";
1081 luval[lusize] = x;
1082 luidx[lusize] = y;
1083 lutab[lusize] = cmdtab;
1084 if (++lusize > LUCACHE) return;
1085
1086 x = lookup(cmdtab,"else",ncmd,&y);
1087 lucmd[lusize] = "else";
1088 luval[lusize] = x;
1089 luidx[lusize] = y;
1090 lutab[lusize] = cmdtab;
1091 #endif /* USE_LUCACHE */
1092 }
1093
1094 VOID
cmdini()1095 cmdini() {
1096 int i = 0, x = 0, y = 0, z = 0, skip = 0;
1097 char * p;
1098 #ifdef TTSPDLIST
1099 long * ss = NULL;
1100 extern int nspd;
1101 extern struct keytab * spdtab;
1102 #endif /* TTSPDLIST */
1103
1104 #ifndef NOSPL
1105 /*
1106 On stack to allow recursion!
1107 */
1108 char vnambuf[VNAML]; /* Buffer for variable names */
1109 #endif /* NOSPL */
1110
1111 if (cmdinited) /* Already initialized */
1112 return; /* Don't do it again */
1113
1114 for (i = 0; i < CMDSTKL; i++) /* Prompt strings for each */
1115 prstring[i] = NULL; /* command level */
1116
1117 #ifndef NOCSETS
1118 p = getenv("K_CHARSET"); /* Set default file character set */
1119 if (p) { /* from environment */
1120 x = lookup(fcstab,p,nfilc,&y);
1121 if (x > -1)
1122 fcharset = x;
1123 }
1124 #endif /* NOCSETS */
1125
1126 p = getenv("K_INFO_DIRECTORY"); /* Find Kermit info directory */
1127 if (p && *p && strlen(p) <= CKMAXPATH)
1128 makestr(&k_info_dir,p);
1129 if (!k_info_dir) {
1130 p = getenv("K_INFO_DIR");
1131 if (p && *p && strlen(p) <= CKMAXPATH)
1132 makestr(&k_info_dir,p);
1133 }
1134 #ifdef UNIX
1135 if (k_info_dir) { /* Look for Kermit docs directory */
1136 if (zchki(k_info_dir) == -2) {
1137 char xbuf[CKMAXPATH+32], *s = "";
1138 if (ckrchar(k_info_dir) != '/')
1139 s = "/";
1140 ckmakmsg(xbuf,CKMAXPATH+32,k_info_dir,s,"ckubwr.txt",NULL);
1141 if (zchki(xbuf) < 0)
1142 makestr(&k_info_dir,NULL);
1143 }
1144 }
1145 if (!k_info_dir) {
1146 char xbuf[CKMAXPATH+32];
1147 int i;
1148 for (i = 0; *(txtdir[i]); i++) {
1149 ckmakmsg(xbuf,CKMAXPATH+32,txtdir[i],"ckubwr.txt",NULL,NULL);
1150 if (zchki(xbuf) > 0) {
1151 makestr(&k_info_dir,txtdir[i]);
1152 debug(F110,"k_info_dir 1",k_info_dir,0);
1153 break;
1154 }
1155 ckmakmsg(xbuf,CKMAXPATH+32,
1156 txtdir[i],"kermit/","ckubwr.txt",NULL);
1157 if (zchki(xbuf) > 0) {
1158 ckmakmsg(xbuf,CKMAXPATH+32,txtdir[i],"kermit/",NULL,NULL);
1159 makestr(&k_info_dir,xbuf);
1160 debug(F110,"k_info_dir 2",k_info_dir,0);
1161 break;
1162 }
1163 ckmakmsg(xbuf,CKMAXPATH+32,
1164 txtdir[i],"ckermit/","ckubwr.txt",NULL);
1165 if (zchki(xbuf) > 0) {
1166 ckmakmsg(xbuf,CKMAXPATH+32,txtdir[i],"ckermit/",NULL,NULL);
1167 makestr(&k_info_dir,xbuf);
1168 debug(F110,"k_info_dir 3",k_info_dir,0);
1169 break;
1170 }
1171 }
1172 if (k_info_dir) { /* Make sure it ends with "/" */
1173 if (ckrchar(k_info_dir) != '/') {
1174 char xbuf[CKMAXPATH+32];
1175 ckmakmsg(xbuf,CKMAXPATH+32,k_info_dir,"/",NULL,NULL);
1176 makestr(&k_info_dir,xbuf);
1177 }
1178 }
1179 }
1180 #else
1181 #ifdef OS2
1182 {
1183 char xdir[CKMAXPATH+8], *s = "";
1184 extern char startupdir[];
1185 xdir[0] = NUL;
1186 if (ckrchar(startupdir) != '/')
1187 s = "/";
1188 if (strlen(s) + strlen(startupdir) + 5 < CKMAXPATH + 8 )
1189 ckmakmsg(xdir,CKMAXPATH+8,s,startupdir,"DOC/",NULL);
1190 makestr(&k_info_dir,xdir);
1191 }
1192 #endif /* OS2 */
1193 #endif /* UNIX */
1194
1195 #ifdef TTSPDLIST
1196 if (!spdtab && (ss = ttspdlist())) { /* Get speed list if necessary */
1197 int j, k, m = 0, n; /* Create sorted keyword table */
1198 char buf[16];
1199 char * p;
1200 if ((spdtab =
1201 (struct keytab *) malloc(sizeof(struct keytab) * ss[0]))) {
1202 for (i = 1; i <= ss[0]; i++) { /* ss[0] = number of elements */
1203 if (ss[i] < 1L) break; /* Shouldn't happen */
1204 buf[0] = NUL; /* Make string */
1205 sprintf(buf,"%ld",ss[i]); /* SAFE */
1206 if (ss[i] == 8880L)
1207 ckstrncpy(buf,"75/1200",sizeof(buf));
1208 if (ss[i] == 134L)
1209 ckstrncat(buf,".5",16);
1210 n = strlen(buf);
1211 if ((n > 0) && (p = (char *)malloc(n+1))) {
1212 if (m > 0) { /* Have at least one in list */
1213 for (j = 0; /* Find slot */
1214 j < m && strcmp(buf,spdtab[j].kwd) > 0;
1215 j++
1216 )
1217 ;
1218 if (j < m) { /* Must insert */
1219 for (k = m-1; k >= j; k--) { /* Move others down */
1220 spdtab[k+1].kwd = spdtab[k].kwd;
1221 spdtab[k+1].flgs = spdtab[k].flgs;
1222 spdtab[k+1].kwval = spdtab[k].kwval;
1223 }
1224 }
1225 } else /* First one */
1226 j = 0;
1227 ckstrncpy(p,buf,n+1); /* Add new speed */
1228 spdtab[j].kwd = p;
1229 spdtab[j].flgs = 0;
1230 spdtab[j].kwval = (int) ss[i] / 10;
1231 m++; /* Count this one */
1232 }
1233 }
1234 }
1235 nspd = m;
1236 }
1237 #endif /* TTSPDLIST */
1238
1239 #ifndef NOSPL
1240 /* Allocate INPUT command buffer */
1241 if (!inpbuf) {
1242 if (!(inpbuf = (char *) malloc(INPBUFSIZ+8)))
1243 fatal("cmdini: no memory for INPUT buffer");
1244 }
1245 for (x = 0; x < INPBUFSIZ; x++) /* Initialize it */
1246 inpbuf[x] = NUL;
1247 inpbp = inpbuf; /* Initialize pointer */
1248 inbufsize = INPBUFSIZ; /* and size. */
1249 #endif /* NOSPL */
1250
1251 #ifdef DCMDBUF
1252 if (cmsetup() < 0) fatal("Can't allocate command buffers!");
1253
1254 #ifndef NOSPL
1255 /* Allocate command stack allowing command parser to call itself */
1256
1257 if (!(cmdstk = (struct cmdptr *) malloc(sizeof(struct cmdptr)*CMDSTKL)))
1258 fatal("cmdini: no memory for cmdstk");
1259 if (!(ifcmd = (int *) malloc(sizeof(int)*CMDSTKL)))
1260 fatal("cmdini: no memory for ifcmd");
1261 if (!(count = (int *) malloc(sizeof(int)*CMDSTKL)))
1262 fatal("cmdini: no memory for count");
1263 if (!(iftest = (int *) malloc(sizeof(int)*CMDSTKL)))
1264 fatal("cmdini: no memory for iftest");
1265 if (!(intime = (int *) malloc(sizeof(int)*CMDSTKL)))
1266 fatal("cmdini: no memory for intime");
1267 if (!(inpcas = (int *) malloc(sizeof(int)*CMDSTKL)))
1268 fatal("cmdini: no memory for inpcas");
1269 if (!(takerr = (int *) malloc(sizeof(int)*CMDSTKL)))
1270 fatal("cmdini: no memory for takerr");
1271 if (!(merror = (int *) malloc(sizeof(int)*CMDSTKL)))
1272 fatal("cmdini: no memory for merror");
1273 if (!(xquiet = (int *) malloc(sizeof(int)*CMDSTKL)))
1274 fatal("cmdini: no memory for xquiet");
1275 if (!(xvarev = (int *) malloc(sizeof(int)*CMDSTKL)))
1276 fatal("cmdini: no memory for xvarev");
1277 if (!kermrc)
1278 if (!(kermrc = (char *) malloc(KERMRCL+1)))
1279 fatal("cmdini: no memory for kermrc");
1280 #ifdef CK_APC
1281 /* Application Program Command buffer */
1282 if (!(apcbuf = malloc(APCBUFLEN + 1)))
1283 fatal("cmdini: no memory for apcbuf");
1284 #endif /* CK_APC */
1285 #endif /* NOSPL */
1286
1287 /* line[] and tmpbuf[] are the two string buffers used by the command parser */
1288
1289 if (!(line = malloc(LINBUFSIZ + 1)))
1290 fatal("cmdini: no memory for line");
1291 if (!(tmpbuf = malloc(LINBUFSIZ + 1)))
1292 fatal("cmdini: no memory for tmpbuf");
1293 #endif /* DCMDBUF */
1294
1295 #ifndef NOSPL
1296 #ifdef CK_MINPUT
1297 { /* Initialize MINPUT pointers */
1298 int i;
1299 extern char *ms[];
1300 for (i = 0; i < MINPMAX; i++)
1301 ms[i] = NULL;
1302 }
1303 #endif /* CK_MINPUT */
1304
1305 if (macini() < 0) /* Allocate macro buffers */
1306 fatal("Can't allocate macro buffers!");
1307
1308 ifcmd[0] = 0; /* Command-level related variables. */
1309 iftest[0] = 0; /* Initialize variables at top level */
1310 count[0] = 0; /* of stack... */
1311 intime[0] = 0;
1312 inpcas[0] = 0;
1313 takerr[0] = 0;
1314 merror[0] = 0;
1315 xquiet[0] = quiet;
1316 xvarev[0] = vareval;
1317 #endif /* NOSPL */
1318
1319 #ifndef NOSPL
1320 cmdlvl = 0; /* Initialize the command stack */
1321 xcmdsrc = CMD_KB;
1322 cmdstk[cmdlvl].src = CMD_KB; /* Source is console */
1323 cmdstk[cmdlvl].lvl = 0; /* Level is 0 */
1324 cmdstk[cmdlvl].ccflgs = 0; /* No flags */
1325 #endif /* NOSPL */
1326
1327 tlevel = -1; /* Take file level = keyboard */
1328 for (i = 0; i < MAXTAKE; i++) /* Initialize command file names */
1329 tfnam[i] = NULL;
1330
1331 cmsetp(ckprompt); /* Set up C-Kermit's prompt */
1332 /* Can't set IKSD prompt here since */
1333 /* we do not yet know if we are IKSD */
1334 #ifndef NOSPL
1335
1336 initmac(); /* Initialize macro table */
1337
1338 /* Predefine built-in one-line macros */
1339
1340 addmac("ibm-linemode",m_ibm); /* IBM-LINEMODE */
1341 addmac("fatal",m_fat); /* FATAL macro */
1342 y = addmac("fast",m_fast); /* FAST macro */
1343 addmac("cautious",m_cautious); /* CAUTIOUS macro */
1344 addmac("robust",m_robust); /* ROBUST macro */
1345 #ifdef OS2
1346 addmac("manual",m_manual); /* MANUAL macro */
1347 #endif /* OS2 */
1348 #ifdef VMS
1349 addmac("purge",m_purge); /* PURGE macro */
1350 #endif /* VMS */
1351
1352 /*
1353 Predefine built-in multiline macros; these are top-level commands
1354 that are implemented internally as macros. NOTE: When adding a new
1355 one of these, remember to update the END and RETURN commands to
1356 account for it, or else END and RETURN from within it won't work right.
1357 */
1358 x = addmmac("_forx",for_def); /* FOR macro */
1359 if (x > -1) mactab[x].flgs = CM_INV;
1360 x = addmmac("_forz",foz_def); /* Other FOR macro */
1361 if (x > -1) mactab[x].flgs = CM_INV;
1362 x = addmmac("_xif",xif_def); /* XIF macro */
1363 if (x > -1) mactab[x].flgs = CM_INV;
1364 x = addmmac("_while",whil_def); /* WHILE macro */
1365 if (x > -1) mactab[x].flgs = CM_INV;
1366 x = addmmac("_switx",sw_def); /* SWITCH macro */
1367 if (x > -1) mactab[x].flgs = CM_INV;
1368
1369 /* Fill in command-line argument vector */
1370
1371 sprintf(vnambuf,"\\&@[%d]",xargs); /* SAFE */
1372 if (inserver) { /* But hidden in IKSD */
1373 y = -1;
1374 xargs = 0;
1375 } else
1376 y = arraynam(vnambuf,&x,&z); /* goes in array \&@[] */
1377
1378 tmpbuf[0] = NUL;
1379 if (y > -1) {
1380 int j = -1;
1381 int yy = 0;
1382 dclarray((char)x,z); /* Declare the array */
1383 #ifndef NOTAKEARGS
1384 /* Macro argument vector */
1385 sprintf(vnambuf,"\\&_[%d]",z); /* SAFE */
1386 yy = arraynam(vnambuf,&x,&z); /* goes in array \&_[] */
1387 if (yy > -1) /* Name is OK */
1388 dclarray((char)x,z); /* Declare the array */
1389 #endif /* NOTAKEARGS */
1390 skip = 0;
1391 for (i = 0; i < xargs; i++) { /* Fill the arrays */
1392 sprintf(vnambuf,"\\&@[%d]",i); /* SAFE */
1393 addmac(vnambuf,xargv[i]);
1394 if (cfilef && i == 0)
1395 continue;
1396 #ifdef KERBANG
1397 if (skip) {
1398 j = 0;
1399 skip = 0;
1400 continue;
1401 }
1402 #endif /* KERBANG */
1403 if (j < 0 && /* Assign items after "=" or "--"*/
1404 (!strcmp(xargv[i],"=") || !strcmp(xargv[i],"--"))
1405 ) {
1406 j = 0; /* to \%1..\%9 */
1407 #ifdef KERBANG
1408 } else if (j < 0 &&
1409 (!strcmp(xargv[i],"+") ||
1410 !strncmp(xargv[i],"+ ",2) ||
1411 !strncmp(xargv[i],"+\t",2))
1412 ) {
1413 skip = 1;
1414 continue;
1415 #endif /* KERBANG */
1416 } else if (j > -1) {
1417 j++;
1418 if (j <= 9) {
1419 vnambuf[0] = '\\';
1420 vnambuf[1] = '%';
1421 vnambuf[2] = (char)(j+'0');
1422 vnambuf[3] = NUL;
1423 addmac(vnambuf,xargv[i]);
1424 }
1425 if (yy > -1) {
1426 char c, * p;
1427 int flag = 0;
1428 p = xargv[i];
1429 makestr(&(toparg[j]),p);
1430 while ((c = *p++)) { if (c == SP) { flag++; break; } }
1431 if (flag)
1432 ckstrncat(tmpbuf,"\"",TMPBUFSIZ);
1433 ckstrncat(tmpbuf,xargv[i],TMPBUFSIZ);
1434 if (flag)
1435 ckstrncat(tmpbuf,"\"",TMPBUFSIZ);
1436 ckstrncat(tmpbuf," ",TMPBUFSIZ);
1437 }
1438 }
1439 }
1440 if (cfilef) {
1441 addmac("\\%0",cmdfil);
1442 if (yy > -1)
1443 makestr(&(toparg[0]),cmdfil);
1444 } else {
1445 addmac("\\%0",xargv[0]);
1446 if (yy > -1)
1447 makestr(&(toparg[0]),xargv[0]);
1448 }
1449 if (yy > -1) {
1450 topargc = (j < 0) ? 1 : j + 1;
1451 topxarg = toparg;
1452 #ifdef COMMENT
1453 /* This needs work */
1454 if (!cfilef)
1455 makestr(&topline,tmpbuf);
1456 #endif /* COMMENT */
1457 } else {
1458 topargc = 0;
1459 topxarg = NULL;
1460 }
1461 a_dim[0] = topargc - 1;
1462 a_ptr[0] = topxarg;
1463 debug(F111,"a_dim[0]","A",a_dim[0]);
1464 }
1465 *vnambuf = NUL;
1466 #endif /* NOSPL */
1467
1468 luinit(); /* Initialize lookup() cache */
1469
1470 /* Get our home directory now. This needed in lots of places. */
1471
1472 cmdinited = 1;
1473 }
1474
1475 #ifdef NT
1476 _PROTOTYP(char * GetAppData,(int));
1477 #endif /* NT */
1478
1479 VOID
doinit()1480 doinit() {
1481 #ifdef CKROOT
1482 extern int ckrooterr;
1483 #endif /* CKROOT */
1484 int x = 0, ok = 0;
1485 #ifdef OS2
1486 char * ptr = 0;
1487 #endif /* OS2 */
1488
1489 if (!cmdinited)
1490 cmdini();
1491
1492 #ifdef MAC
1493 return; /* Mac Kermit has no init file */
1494
1495 #else /* !MAC */
1496
1497 /* If skipping init file ('-Y' on Kermit command line), return now. */
1498
1499 if (noinit) {
1500 kermrc[0] = '\0';
1501 inidir[0] = '\0';
1502 /*
1503 But returning from here results in inidir[] never being set to anything.
1504 Instead it should be set to wherever the init file *would* have been
1505 executed from. So this bit of code should be removed, and then we should
1506 sprinkle "if (noinit)" tests throughout the following code until we have
1507 set inidir[], and then return without actually taking the init file.
1508 */
1509 return;
1510 }
1511
1512 #ifdef OS2
1513 /*
1514 The -y init file must be fully specified or in the current directory.
1515 KERMRC is looked for via INIT, DPATH and PATH in that order. Finally, our
1516 own executable file path is taken and the .EXE suffix is replaced by .INI
1517 and this is tried as the initialization file.
1518 */
1519 #ifdef CK_LOGIN
1520 debug(F101,"doinit inserver","",inserver);
1521 debug(F101,"doinit isguest","",isguest);
1522 debug(F110,"doinit anonfile",anonfile,0);
1523
1524 if (isguest && anonfile) {
1525 ckstrncpy(line, anonfile, LINBUFSIZ+1);
1526 } else
1527 #endif /* CK_LOGIN */
1528 if (rcflag) {
1529 ckstrncpy(line,kermrc,LINBUFSIZ+1);
1530 #ifdef CK_LOGIN
1531 } else if (inserver) {
1532 char * appdata = NULL;
1533 #ifdef NT
1534 appdata = GetAppData(1);
1535 if ( appdata ) {
1536 ckmakmsg(line,LINBUFSIZ+1,appdata,
1537 "Kermit 95/k95.ini",NULL,NULL);
1538 if ( zchki(line) < 0 )
1539 line[0] = '\0';
1540 }
1541 if (line[0] == 0) {
1542 appdata = GetAppData(0);
1543 if ( appdata ) {
1544 ckmakmsg(line,LINBUFSIZ+1,appdata,
1545 "Kermit 95/k95.ini",NULL,NULL);
1546 if ( zchki(line) < 0 )
1547 line[0] = '\0';
1548 }
1549 }
1550 #endif /* NT */
1551 if (line[0] == 0) {
1552 appdata = zhome();
1553 if ( appdata ) {
1554 ckmakmsg(line,LINBUFSIZ+1,appdata,
1555 #ifdef NT
1556 "k95.ini",
1557 #else /* NT */
1558 "k2.ini",
1559 #endif /* NT */
1560 NULL,NULL);
1561 if ( zchki(line) < 0 )
1562 line[0] = '\0';
1563 }
1564 }
1565 debug(F110,"doinit inserver inifile",line,0);
1566 #endif /* CK_LOGIN */
1567 } else {
1568 char * env = 0;
1569 #ifdef NT
1570 env = getenv("K95.KSC");
1571 #else
1572 env = getenv("K2.KSC");
1573 #endif /* NT */
1574 if (!env) {
1575 #ifdef NT
1576 env = getenv("K95.INI");
1577 #else
1578 env = getenv("K2.INI");
1579 #endif /* NT */
1580 }
1581 if (!env)
1582 env = getenv("CKERMIT.INI");
1583 if (!env)
1584 env = getenv("CKERMIT_INI");
1585 line[0] = '\0';
1586
1587 debug(F110,"doinit env",env,0);
1588 if (env)
1589 ckstrncpy(line,env,LINBUFSIZ+1);
1590
1591 #ifdef NT
1592 if (line[0] == 0) {
1593 env = GetAppData(1);
1594 if ( env ) {
1595 ckmakmsg(line,LINBUFSIZ+1,env,"Kermit 95/k95.ini",NULL,NULL);
1596 if ( zchki(line) < 0 )
1597 line[0] = '\0';
1598 }
1599 }
1600 if (line[0] == 0) {
1601 env = GetAppData(0);
1602 if ( env ) {
1603 ckmakmsg(line,LINBUFSIZ+1,env,"Kermit 95/k95.ini",NULL,NULL);
1604 if ( zchki(line) < 0 )
1605 line[0] = '\0';
1606 }
1607 }
1608 #endif /* NT */
1609
1610 if (line[0] == 0) {
1611 env = zhome();
1612 if ( env ) {
1613 ckmakmsg(line,LINBUFSIZ+1,env,
1614 #ifdef NT
1615 "k95.ini",
1616 #else /* NT */
1617 "k2.ini",
1618 #endif /* NT */
1619 NULL,NULL);
1620 if ( zchki(line) < 0 )
1621 line[0] = '\0';
1622 }
1623 }
1624
1625 if (line[0] == 0)
1626 _searchenv(kermrc,"INIT",line);
1627 if (line[0] == 0)
1628 _searchenv(kermrc,"DPATH",line);
1629 if (line[0] == 0)
1630 _searchenv(kermrc,"PATH",line);
1631 if (line[0] == 0) {
1632 char *pgmptr = GetLoadPath();
1633 if (pgmptr && strlen(pgmptr) < LINBUFSIZ-8) {
1634 lp = strrchr(pgmptr, '\\');
1635 if (lp) {
1636 strncpy(line, pgmptr, lp - pgmptr);
1637 #ifdef NT
1638 strcpy(line + (lp - pgmptr), "/k95.ini");
1639 #else /* NT */
1640 strcpy(line + (lp - pgmptr), "/k2.ini");
1641 #endif /* NT */
1642 } else {
1643 lp = strrchr(pgmptr, '.');
1644 if (lp) {
1645 strncpy(line, pgmptr, lp - pgmptr);
1646 strcpy(line + (lp - pgmptr), ".ini");
1647 }
1648 }
1649 }
1650 }
1651 }
1652
1653 #ifdef CKROOT
1654 if (!zinroot(line)) {
1655 debug(F110,"doinit setroot violation",line,0);
1656 return;
1657 }
1658 #endif /* CKROOT */
1659
1660 debug(F110,"doinit fopen()",line,0);
1661 if ((tfile[0] = fopen(line,"r")) != NULL) {
1662 ok = 1;
1663 tlevel = 0;
1664 tfline[tlevel] = 0;
1665 tfblockstart[tlevel] = 1;
1666 if (tfnam[tlevel] = malloc(strlen(line)+1))
1667 strcpy(tfnam[tlevel],line); /* safe */
1668 #ifndef NOSPL
1669 cmdlvl++;
1670 xcmdsrc = CMD_TF;
1671 cmdstk[cmdlvl].src = CMD_TF;
1672 cmdstk[cmdlvl].lvl = tlevel;
1673 cmdstk[cmdlvl].ccflgs = 0;
1674 ifcmd[cmdlvl] = 0;
1675 iftest[cmdlvl] = 0;
1676 count[cmdlvl] = count[cmdlvl-1]; /* Inherit from previous level */
1677 intime[cmdlvl] = intime[cmdlvl-1];
1678 inpcas[cmdlvl] = inpcas[cmdlvl-1];
1679 takerr[cmdlvl] = takerr[cmdlvl-1];
1680 merror[cmdlvl] = merror[cmdlvl-1];
1681 xquiet[cmdlvl] = quiet;
1682 xvarev[cmdlvl] = vareval;
1683 #endif /* NOSPL */
1684 debug(F110,"doinit init file",line,0);
1685 } else {
1686 debug(F100,"doinit no init file","",0);
1687 }
1688 ckstrncpy(kermrc,line,KERMRCL);
1689 for (ptr = kermrc; *ptr; ptr++) /* Convert backslashes to slashes */
1690 if (*ptr == '\\')
1691 *ptr = '/';
1692 #else /* not OS2 */
1693 lp = line;
1694 lp[0] = '\0';
1695 debug(F101,"doinit rcflag","",rcflag);
1696 #ifdef GEMDOS
1697 zkermini(line, rcflag, kermrc);
1698 #else
1699 #ifdef VMS
1700 {
1701 int x;
1702 x = zkermini(line,LINBUFSIZ,kermrc);
1703 debug(F111,"CUSTOM zkermini",line,x);
1704 if (x == 0)
1705 line[0] = NUL;
1706 }
1707 #else /* not VMS */
1708 #ifdef CK_LOGIN
1709 debug(F101,"doinit isguest","",isguest);
1710 if (isguest)
1711 ckstrncpy(lp, anonfile ? anonfile : kermrc, LINBUFSIZ);
1712 else
1713 #endif /* CK_LOGIN */
1714 if (rcflag) { /* If init file name from cmd line */
1715 ckstrncpy(lp,kermrc,LINBUFSIZ); /* use it, */
1716 } else { /* otherwise... */
1717 #ifdef CK_INI_A /* If we've a system-wide init file */
1718 /* And it takes precedence over the user's... */
1719 ckstrncpy(lp,CK_SYSINI,KERMRCL); /* Use it */
1720 if (zchki(lp) < 0) { /* (if it exists...) */
1721 #endif /* CK_INI_A */
1722 char * homdir;
1723 char * env = 0;
1724 line[0] = NUL;
1725
1726 /* Add support for environment variable */
1727 env = getenv("CKERMIT.INI");
1728 if (!env)
1729 env = getenv("CKERMIT_INI");
1730 if (env)
1731 ckstrncpy(lp,env,KERMRCL);
1732
1733 if (lp[0] == 0) {
1734 homdir = zhome();
1735 if (homdir) { /* Home directory for init file. */
1736 ckstrncpy(lp,homdir,KERMRCL);
1737 #ifdef STRATUS
1738 ckstrncat(lp,">",KERMRCL);/* VOS dirsep */
1739 #else
1740 if (lp[0] == '/') ckstrncat(lp,"/",KERMRCL);
1741 #endif /* STRATUS */
1742 }
1743 ckstrncat(lp,kermrc,KERMRCL);/* Append default file name */
1744 }
1745 #ifdef CK_INI_A
1746 }
1747 #endif /* CK_INI_A */
1748 #ifdef CK_INI_B /* System-wide init defined? */
1749 /* But user's ini file takes precedence */
1750 if (zchki(lp) < 0) /* If user doesn't have her own, */
1751 ckstrncpy(lp,CK_SYSINI,KERMRCL); /* use system-wide one. */
1752 #endif /* CK_INI_B */
1753 }
1754 #endif /* VMS */
1755 #endif /* GEMDOS */
1756
1757 #ifdef AMIGA
1758 reqoff(); /* Disable requestors */
1759 #endif /* AMIGA */
1760
1761 #ifdef USE_CUSTOM
1762 /* If no init file was found, execute the customization file */
1763 debug(F111,"CUSTOM 1",line,rcflag);
1764 if ((!line[0] || zchki(line) < 0) && !rcflag) {
1765 int x;
1766 #ifdef OS2
1767 x = ckmakestr(line,LINBUFSIZ,GetAppData(1),"/","K95CUSTOM.INI",NULL);
1768 debug(F111,"CUSTOM 2",line,x);
1769 if (zchki(line) < 0) {
1770 x = ckmakestr(line,LINBUFSIZ,GetAppData(0),"/","K95USER.INI",NULL);
1771 debug(F111,"CUSTOM 3",line,x);
1772 }
1773 #else /* OS2 */
1774 x = ckstrncpy(line,zhome(),LINBUFSIZ);
1775 #ifndef VMS
1776 /* VMS zhome() returns "SYS$LOGIN:" */
1777 if (line[x-1] != DIRSEP) {
1778 line[x++] = DIRSEP;
1779 line[x] = NUL;
1780 }
1781 #endif /* VMS */
1782 x = ckstrncat(line,MYCUSTOM,LINBUFSIZ);
1783 debug(F111,"CUSTOM 4",line,x);
1784 #endif /* OS2 */
1785 }
1786 debug(F110,"CUSTOM 5",line,0);
1787 #endif /* USE_CUSTOM */
1788
1789 #ifdef CKROOT
1790 if (!zinroot(line)) {
1791 debug(F110,"doinit setroot violation",line,0);
1792 return;
1793 }
1794 #endif /* CKROOT */
1795
1796 debug(F110,"doinit ini file is",line,0);
1797 if ((tfile[0] = fopen(line,"r")) != NULL) { /* Try to open init file. */
1798 ok = 1;
1799 tlevel = 0;
1800 tfline[tlevel] = 0;
1801 tfblockstart[tlevel] = 1;
1802 if ((tfnam[tlevel] = malloc(strlen(line)+1)))
1803 strcpy(tfnam[tlevel],line); /* safe */
1804
1805 ckstrncpy(kermrc,line,KERMRCL);
1806
1807 #ifndef NOSPL
1808 cmdlvl++;
1809 ifcmd[cmdlvl] = 0;
1810 iftest[cmdlvl] = 0;
1811 count[cmdlvl] = count[cmdlvl-1]; /* Inherit from previous level */
1812 intime[cmdlvl] = intime[cmdlvl-1];
1813 inpcas[cmdlvl] = inpcas[cmdlvl-1];
1814 takerr[cmdlvl] = takerr[cmdlvl-1];
1815 merror[cmdlvl] = merror[cmdlvl-1];
1816 xquiet[cmdlvl] = quiet;
1817 xvarev[cmdlvl] = vareval;
1818 debug(F101,"doinit open ok","",cmdlvl);
1819 xcmdsrc = CMD_TF;
1820 cmdstk[cmdlvl].src = CMD_TF;
1821 cmdstk[cmdlvl].lvl = tlevel;
1822 cmdstk[cmdlvl].ccflgs = 0;
1823 #endif /* NOSPL */
1824 } else if (rcflag) {
1825 /* Print an error message only if a specific file was asked for. */
1826 printf("?%s - %s\n", ck_errstr(), line);
1827 }
1828
1829 #ifdef datageneral
1830 /* If CKERMIT.INI not found in home directory, look in searchlist */
1831 if (/* homdir && */ (tlevel < 0)) {
1832 ckstrncpy(lp,kermrc,LINBUFSIZ);
1833 if ((tfile[0] = fopen(line,"r")) != NULL) {
1834 ok = 1;
1835 tlevel = 0;
1836 tfline[tlevel] = 0;
1837 tfblockstart[tlevel] = 1;
1838 if (tfnam[tlevel] = malloc(strlen(line)+1))
1839 strcpy(tfnam[tlevel],line); /* safe */
1840 #ifndef NOSPL
1841 cmdlvl++;
1842 xcmdsrc = CMD_TF;
1843 cmdstk[cmdlvl].src = CMD_TF;
1844 cmdstk[cmdlvl].lvl = tlevel;
1845 cmdstk[cmdlvl].ccflgs = 0;
1846 ifcmd[cmdlvl] = 0;
1847 iftest[cmdlvl] = 0;
1848 count[cmdlvl] = count[cmdlvl-1]; /* Inherit from previous level */
1849 intime[cmdlvl] = intime[cmdlvl-1];
1850 inpcas[cmdlvl] = inpcas[cmdlvl-1];
1851 takerr[cmdlvl] = takerr[cmdlvl-1];
1852 merror[cmdlvl] = merror[cmdlvl-1];
1853 xquiet[cmdlvl] = quiet;
1854 xvarev[cmdlvl] = vareval;
1855 #endif /* NOSPL */
1856 }
1857 }
1858 #endif /* datageneral */
1859
1860 #ifdef AMIGA /* Amiga... */
1861 reqpop(); /* Restore requestors */
1862 #endif /* AMIGA */
1863 #endif /* OS2 */
1864 #endif /* MAC */
1865
1866 /* Assign value to inidir */
1867
1868 if (!ok) {
1869 inidir[0] = NUL;
1870 } else {
1871 ckstrncpy(inidir, kermrc, CCHMAXPATH);
1872 x = strlen(inidir);
1873 if (x > 0) {
1874 int i;
1875 for (i = x - 1; i > 0; i-- ) {
1876 if (ISDIRSEP(inidir[i])) {
1877 inidir[i+1] = NUL;
1878 break;
1879 }
1880 }
1881 }
1882 #ifdef NT
1883 GetShortPathName(inidir,inidir,CCHMAXPATH);
1884 #endif /* NT */
1885 }
1886 }
1887
1888 VOID
doiksdinit()1889 doiksdinit() {
1890 #ifdef CK_SSL
1891 /* IKSD doesn't request client certs */
1892 ssl_verify_flag = SSL_VERIFY_NONE;
1893 #endif /* CK_SSL */
1894
1895 if (!cmdinited)
1896 cmdini();
1897
1898 #ifdef IKSDCONF
1899 #ifdef OS2
1900 line[0] = '\0';
1901 _searchenv(iksdconf,"INIT",line);
1902 if (line[0] == 0)
1903 _searchenv(iksdconf,"DPATH",line);
1904 if (line[0] == 0)
1905 _searchenv(iksdconf,"PATH",line);
1906 if (line[0] == 0) {
1907 char *pgmptr = GetLoadPath();
1908 if (pgmptr && strlen(pgmptr) < LINBUFSIZ-8) {
1909 lp = strrchr(pgmptr, '\\');
1910 if (lp) {
1911 strncpy(line, pgmptr, lp - pgmptr);
1912 strcpy(line + (lp - pgmptr), "\\");
1913 strcpy(line + (lp - pgmptr + 1), iksdconf);
1914 } else {
1915 lp = strrchr(pgmptr, '.');
1916 if (lp) {
1917 strncpy(line, pgmptr, lp - pgmptr);
1918 strcpy(line + (lp - pgmptr), ".ksc");
1919 }
1920 }
1921 }
1922 }
1923 debug(F110,"doiksdinit() line",line,0);
1924 tfile[0] = fopen(line,"r");
1925 #else /* OS2 */
1926 tfile[0] = fopen(iksdconf,"r");
1927 #endif /* OS2 */
1928 if (tfile[0] != NULL) {
1929 tlevel = 0;
1930 tfline[tlevel] = 0;
1931 tfblockstart[tlevel] = 1;
1932 #ifdef OS2
1933 if (tfnam[tlevel] = malloc(strlen(line)+1))
1934 strcpy(tfnam[tlevel],line);
1935 #else /* OS2 */
1936 if ((tfnam[tlevel] = malloc(strlen(iksdconf)+1)))
1937 strcpy(tfnam[tlevel],iksdconf);
1938 #endif /* OS2 */
1939 #ifndef NOSPL
1940 cmdlvl++;
1941 xcmdsrc = CMD_TF;
1942 cmdstk[cmdlvl].src = CMD_TF;
1943 cmdstk[cmdlvl].lvl = tlevel;
1944 cmdstk[cmdlvl].ccflgs = 0;
1945 ifcmd[cmdlvl] = 0;
1946 iftest[cmdlvl] = 0;
1947 count[cmdlvl] = count[cmdlvl-1]; /* Inherit from previous level */
1948 intime[cmdlvl] = intime[cmdlvl-1];
1949 inpcas[cmdlvl] = inpcas[cmdlvl-1];
1950 takerr[cmdlvl] = takerr[cmdlvl-1];
1951 merror[cmdlvl] = merror[cmdlvl-1];
1952 xquiet[cmdlvl] = quiet;
1953 xvarev[cmdlvl] = vareval;
1954 #endif /* NOSPL */
1955 debug(F110,"doiksdinit file ok",tfnam[tlevel],0);
1956 } else {
1957 debug(F110,"doiksdinit open failed",tfnam[tlevel],0);
1958 }
1959 #endif /* IKSDCONF */
1960 }
1961
1962 #ifndef NOSPL
1963 /*
1964 G E T N C M
1965
1966 Get next command from current macro definition. Command is copied
1967 into string pointed to by argument s, max length n. Returns:
1968 0 if a string was copied;
1969 -1 if there was no string to copy.
1970 */
1971 int
getncm(s,n)1972 getncm(s,n) char *s; int n; {
1973 int y = 0; /* Character counter */
1974 int quote = 0;
1975 int kp = 0; /* Brace up-down counter */
1976 int pp = 0; /* Parenthesis up-down counter */
1977 #ifndef NODQMACRO
1978 int dq = 0; /* Doublequote counter */
1979 #endif /* NODQMACRO */
1980 char *s2; /* Copy of destination pointer */
1981
1982 s2 = s; /* Initialize string pointers */
1983 *s = NUL; /* and destination buffer */
1984
1985 /* debug(F010,"getncm entry",macp[maclvl],0); */
1986
1987 for (y = 0; /* Loop for n bytes max */
1988 macp[maclvl] && *macp[maclvl] && y < n;
1989 y++, s++, macp[maclvl]++) {
1990
1991 *s = *macp[maclvl]; /* Get next char from macro def */
1992
1993 #ifndef COMMENT
1994 /*
1995 This is to allow quoting of parentheses, commas, etc, in function
1996 arguments, but it breaks just about everything else. DON'T REMOVE THIS
1997 COMMENT! (Otherwise you'll wind up adding the same code again and breaking
1998 everything again.) <-- The preceding warning should be obsolete since the
1999 statements below have been fixed, but in case of fire, remove the "n" from
2000 the <#>ifndef above. NEW WARNING: code added 12 Apr 2002 to exempt the
2001 opening brace in \{nnn} from being treated as a quoted brace.
2002 */
2003 if (!quote && *s == CMDQ) {
2004 quote = 1;
2005 continue;
2006 }
2007 if (quote) {
2008 int notquote = 0;
2009 quote = 0;
2010 if (*s == '{') { /* Check for \{nnn} (8.0.203) */
2011 char c, * p;
2012 p = macp[maclvl] + 1;
2013 while ((c = *p++)) {
2014 if (isdigit(c))
2015 continue;
2016 else if (c == '}') {
2017 notquote++;
2018 break;
2019 } else {
2020 break;
2021 }
2022 }
2023 }
2024 if (notquote == 0)
2025 continue;
2026 }
2027 #endif /* COMMENT */
2028
2029 /*
2030 Allow braces around macro definition to prevent commas from being turned to
2031 end-of-lines and also treat any commas within parens as text so that
2032 multiple-argument functions won't cause the command to break prematurely.
2033 19 Oct 2001: Similar treatment was added for doublequotes, so
2034
2035 define foo { echo "one, two, three" }
2036
2037 would work as expected. This doesn't seem to have broken anything but
2038 if something comes up later, rebuild with NODQMACRO defined.
2039 */
2040 if (*s == '{') kp++; /* Count braces */
2041 if (*s == '}' && kp > 0) kp--;
2042 if (*s == '(') pp++; /* Count parentheses. */
2043 if (*s == ')' && pp > 0) pp--;
2044 #ifndef NODQMACRO
2045 #ifndef COMMENT
2046 /* Too many false positives */
2047 /* No, not really -- this is indeed the best we can do */
2048 /* Reverted to this method Sun May 11 18:43:45 2003 */
2049 if (*s == '"') dq = 1 - dq; /* Account for doublequotes */
2050 #else /* Fri Apr 4 13:21:29 2003 */
2051 /* The code below breaks the SWITCH statement */
2052 /* There is no way to make this work -- it would require */
2053 /* building in all the knowledge of command parser. */
2054 if (dblquo && (*s == '"')) { /* Have doublequote */
2055 if (dq == 1) { /* Close quote only if... */
2056 if ((*(macp[maclvl]+1) == SP) || /* followed by space or... */
2057 (!*(macp[maclvl]+1)) || /* at end or ... */
2058 /* Next char is command separator... */
2059 /* Sun May 11 17:24:12 2003 */
2060 (kp < 1 && pp < 1 && (*(macp[maclvl]+1) == ','))
2061 )
2062 dq = 0; /* Close the quote */
2063 } else if (dq == 0) {
2064 /* Open quote only if at beginning or preceded by space */
2065 if (s > s2) {
2066 if (*(s-1) == SP)
2067 dq = 1;
2068 } else if (s == s2) {
2069 dq = 1;
2070 }
2071 }
2072 }
2073 #endif /* COMMENT */
2074 #endif /* NODQMACRO */
2075 if (*s == ',' && pp <= 0 && kp <= 0
2076 #ifndef NODQMACRO
2077 && dq == 0
2078 #endif /* NODQMACRO */
2079 ) {
2080 macp[maclvl]++; /* Comma not in {} or () */
2081 /* debug(F110,"next cmd",s,0); */
2082 kp = pp = 0; /* so we have the next command */
2083 break;
2084 }
2085 } /* Reached end. */
2086 #ifdef COMMENT
2087 /* DON'T DO THIS - IT BREAKS EVERYTHING */
2088 *s = NUL;
2089 #endif /* COMMENT */
2090 if (*s2 == NUL) { /* If nothing was copied, */
2091 /* debug(F100,"getncm eom","",0); */
2092 popclvl(); /* pop command level. */
2093 return(-1);
2094 } else { /* otherwise, tack CR onto end */
2095 *s++ = CR;
2096 *s = '\0';
2097 /* debug(F110,"getncm OK",s,0); */
2098 if (mecho && pflag) /* If MACRO ECHO ON, echo the cmd */
2099 printf("%s\n",s2);
2100 }
2101 return(0);
2102 }
2103
2104 /* D O M A C -- Define and then execute a macro */
2105
2106 int
domac(name,def,flags)2107 domac(name, def, flags) char *name, *def; int flags; {
2108 int x, m;
2109 #ifndef NOLOCAL
2110 #ifdef OS2
2111 extern int term_io;
2112 int term_io_sav = term_io;
2113 term_io = 0; /* Disable Terminal Emulator I/O */
2114 #endif /* OS2 */
2115 #endif /* NOLOCAL */
2116 m = maclvl; /* Current macro stack level */
2117 x = addmac(name, def); /* Define a new macro */
2118 if (x > -1) { /* If successful, */
2119 dodo(x,NULL,flags); /* start it (increments maclvl). */
2120 while (maclvl > m) { /* Keep going till done with it, */
2121 debug(F101,"domac loop maclvl 1","",maclvl);
2122 sstate = (CHAR) parser(1); /* parsing & executing each command, */
2123 debug(F101,"domac loop maclvl 2","",maclvl);
2124 if (sstate) proto(); /* including protocol commands. */
2125 }
2126 debug(F101,"domac loop exit maclvl","",maclvl);
2127 }
2128 #ifndef NOLOCAL
2129 #ifdef OS2
2130 term_io = term_io_sav;
2131 #endif /* OS2 */
2132 #endif /* NOLOCAL */
2133 return(success);
2134 }
2135 #endif /* NOSPL */
2136
2137 /*
2138 G E T N C T
2139
2140 Get next command from TAKE (command) file.
2141
2142 Call with:
2143 s Pointer to buffer to read into
2144 n Length of buffer
2145 f File descriptor of file to read from
2146 flag 0 == keep line terminator on and allow continuation
2147 1 == discard line terminator and don't allow continuation
2148
2149 Call with flag == 0 to read a command from a TAKE file;
2150 Call with flag != 0 to read a line from a dialing or network directory.
2151
2152 In both cases, trailing comments and/or trailing whitespace is/are stripped.
2153 If flag == 0, continued lines are combined into one line. A continued line
2154 is one that ends in hypen, or any line in a "block", which starts with "{"
2155 at the end of a line and ends with a matching "}" at the beginning of a
2156 subsequent line; blocks may be nested.
2157
2158 Returns:
2159 0 if a string was copied,
2160 -1 on EOF,
2161 -2 on malloc failure
2162 -3 if line is not properly terminated
2163 -4 if (possibly continued) line is too long.
2164 */
2165 static int lpxlen = 0;
2166
2167 int
getnct(s,n,f,flag)2168 getnct(s,n,f,flag) char *s; int n; FILE *f; int flag; {
2169 int i = 0, len = 0, buflen = 0;
2170 char c = NUL, cc = NUL, ccl = NUL, ccx = NUL, *s2 = NULL;
2171 char *lp = NULL, *lpx = NULL, *lp2 = NULL, *lp3 = NULL, *lastcomma = NULL;
2172 char * prev = NULL;
2173 int bc = 0; /* Block counter */
2174 int firstread = 1;
2175
2176 s2 = s; /* Remember original pointer */
2177 prev = s2; /* Here too */
2178 buflen = n; /* Remember original buffer length */
2179
2180 if (n < 0)
2181 return(-2);
2182
2183 /* Allocate a line buffer only if we don't have one that's big enough */
2184
2185 debug(F111,"getnct",ckitoa(lpxlen),n);
2186
2187 if (lpx && (n > lpxlen)) { /* Have one already */
2188 debug(F101,"getnct new buffer","",lpxlen);
2189 free(lpx); /* But it's not big enough */
2190 lpx = NULL; /* Free current one */
2191 lpxlen = 0;
2192 }
2193 if (!lpx) { /* Get new one */
2194 if (!(lpx = (char *) malloc(n))) {
2195 debug(F101,"getnct malloc failure","",0);
2196 printf("?Memory allocation failure [getnct:%d]\n",n);
2197 return(-2);
2198 }
2199 lpxlen = n;
2200 }
2201 lp2 = lpx;
2202 #ifdef KLUDGE
2203 /* NOTE: No longer used as of 14 Aug 2000 */
2204 lp2++;
2205 #endif /* KLUDGE */
2206
2207 while (1) { /* Loop to read lines from file */
2208 debug(F101,"getnct while (1)","",n);
2209 if (fgets(lp2,n,f) == NULL) { /* Read a line into lp2 */
2210 debug(F110,"getnct EOF",s2,0); /* EOF */
2211 free(lpx); /* Free temporary storage */
2212 lpx = NULL;
2213 *s = NUL; /* Make destination be empty */
2214 return(-1); /* Return failure code */
2215 }
2216 if (firstread) { /* Beginning of a block or statement */
2217 tfblockstart[tlevel] = tfline[tlevel];
2218 firstread = 0;
2219 }
2220 #ifndef NODIAL
2221 if (flag) /* Count this line */
2222 dirline++;
2223 else
2224 #endif /* NODIAL */
2225 tfline[tlevel]++;
2226 len = strlen(lp2) - 1; /* Position of line terminator */
2227 if (len == 0 && lp2[0] != '\n') { /* Last line in file has one char */
2228 lp2[++len] = '\n'; /* that is not a newline */
2229 lp2[len] = NUL;
2230 }
2231 debug(F010,"getnct",lp2,0);
2232 if (len < 0)
2233 len = 0;
2234 if (techo && pflag) { /* If TAKE ECHO ON, */
2235 if (flag) {
2236 printf("%3d. %s", /* echo it this line. */
2237 #ifndef NODIAL
2238 flag ? dirline :
2239 #endif /* NODIAL */
2240 tfline[tlevel],
2241 lp2
2242 );
2243 } else {
2244 printf("%3d. %3d. %s", /* echo it this line. */
2245 tfline[tlevel],
2246 tfblockstart[tlevel],
2247 lp2
2248 );
2249 }
2250 }
2251 lp3 = lp2; /* Working pointer */
2252 i = len; /* Get first nonwhitespace character */
2253 while (i > 0 && (*lp3 == SP || *lp3 == HT)) {
2254 i--;
2255 lp3++;
2256 }
2257 if (i == 0 && bc > 0) /* Blank line in {...} block */
2258 continue;
2259
2260 /* Isolate, remove, and check terminator */
2261
2262 c = lp2[len]; /* Value of line terminator */
2263 /* debug(F101,"getnct terminator","",c); */
2264 if (c < LF || c > CR) { /* It's not a terminator */
2265 /* debug(F111,"getnct bad line",lp2,c); */
2266 if (feof(f) && len > 0 && len < n) {
2267 /* Kludge Alert... */
2268 if (!quiet)
2269 printf("WARNING: Last line of %s lacks terminator\n",
2270 s2 == cmdbuf ? "command file" : "directory file");
2271 c = lp2[++len] = '\n'; /* No big deal - supply one. */
2272 } else { /* Something's wrong, fail. */
2273 free(lpx);
2274 lpx = NULL;
2275 return(-3);
2276 }
2277 }
2278 /* Trim trailing whitespace */
2279
2280 for (i = len - 1; i > -1 && lp2[i] <= SP; i--) /* Trim */
2281 ;
2282 /* debug(F101,"getnct i","",i); */
2283 lp2[i+1] = NUL; /* Terminate the string */
2284 /* debug(F110,"getnct lp2",lp2,0); */
2285 lp = lp2; /* Make a working pointer */
2286
2287 /* Remove trailing or full-line comment */
2288
2289 while ((cc = *lp)) {
2290 if (cc == ';' || cc == '#') { /* Comment introducer? */
2291 if (lp == lp2) { /* First char on line */
2292 *lp = NUL;
2293 break;
2294 } else if (*(lp - 1) == SP || *(lp - 1) == HT) {
2295 lp--;
2296 *lp = NUL; /* Or preceded by whitespace */
2297 break;
2298 }
2299 }
2300 lp++;
2301 }
2302 if (lp > lp2)
2303 lp--; /* Back up over the NUL */
2304
2305 /* Now trim any space that preceded the comment */
2306
2307 while ((*lp == SP || *lp == HT) && lp >= lp2) {
2308 *lp = NUL;
2309 if (lp <= lp2)
2310 break;
2311 lp--;
2312 }
2313 /* debug(F110,"getnct comment trimmed",lp2,0); */
2314
2315 len = strlen(lp2); /* Length after trimming */
2316
2317 if (n - len < 2) { /* Check remaining space */
2318 debug(F111,"getnct command too long",s2,buflen);
2319 printf("?Line too long, maximum length: %d.\n",buflen);
2320 free(lpx);
2321 return(-4);
2322 }
2323 ccl = (len > 0) ? lp2[len-1] : 0; /* Last character in line */
2324 ccx = (len > 1) ? lp2[len-2] : 0; /* Penultimate char in line */
2325
2326 #ifdef COMMENT
2327 /* Line containing only whitespace and ,- */
2328 if ((len > 1) && (lp3 == lp2+len-2) && (ccl == '-') && (ccx == ','))
2329 continue;
2330 #endif /* COMMENT */
2331
2332 #ifdef KLUDGE
2333 /*
2334 If it is a command and it begins with a token (like ! or .) that is not
2335 followed by a space, insert a space now; otherwise cmkey() can get mighty
2336 confused.
2337 */
2338 if (s == s2 && !flag) {
2339 char *p = toktab;
2340 while (*p) {
2341 if (*p == *lp3 && *(p+1) != SP) {
2342 debug(F110,"getnct token",p,0);
2343 *lp3-- = SP;
2344 *lp3 = *p;
2345 if (lp3 < lp2) {
2346 lp2--;
2347 len++;
2348 }
2349 break;
2350 } else
2351 p++;
2352 }
2353 }
2354 #endif /* KLUDGE */
2355 lp = lp2;
2356
2357 while ((*s++ = *lp++)) /* Copy result to target buffer */
2358 n--; /* accounting for length */
2359 s--; /* Back up over the NUL */
2360
2361 /* Check whether this line is continued */
2362
2363 if (flag) /* No line continuation when flag=1 */
2364 break; /* So break out of read-lines loop */
2365
2366 #ifdef COMMENT
2367 debug(F000,"getnct first char","",*lp3);
2368 debug(F000,"getnct last char","",ccl);
2369 debug(F000,"getnct next-to-last char","",ccx);
2370 #endif /* COMMENT */
2371
2372 if (bc > 0 && *lp3 == '}') { /* First char on line is '}' */
2373 bc--; /* Decrement block counter */
2374 }
2375
2376 if (bc == 0 && /* Line is continued if bc > 0 */
2377 #ifdef COMMENT
2378 /* Not supported as of C-Kermit 6.0 */
2379 ccl != CMDQ && /* or line ends with CMDQ */
2380 #endif /* COMMENT */
2381 ccl != '-' && /* or line ends with dash */
2382 ccl != '{') { /* or line ends with opening brace */
2383 break; /* None of those, we're done. */
2384 }
2385 if (ccl == '-' || ccl == '{') /* Continuation character */
2386 if (ccx == CMDQ) /* But it's quoted */
2387 break; /* so ignore it */
2388
2389 if (ccl == '{') { /* Last char on line is '{'? */
2390 bc++; /* Count the block opener. */
2391 } else if (ccl == '-') { /* Explicit continue? */
2392 char c, * ss;
2393 int state = 0, nn;
2394 s--; /* Yes, back up over terminators */
2395 n++; /* and over continuation character */
2396 nn = n; /* Save current count */
2397 ss = s; /* and pointer */
2398 s--; /* Back up over dash */
2399 n++;
2400 while (state < 2 && s >= prev) { /* Check for "{,-" */
2401 n++;
2402 c = *s--;
2403 if (c <= SP)
2404 continue;
2405 if (c != ',' && c != '{')
2406 break;
2407 switch (state) {
2408 case 0: /* Looking for comma */
2409 if (c == ',')
2410 state = 1;
2411 break;
2412 case 1: /* Looking for left brace */
2413 if (c == '{') {
2414 state = 2;
2415 s += 2;
2416 *s = NUL;
2417 bc++;
2418 }
2419 break;
2420 }
2421 }
2422 if (state != 2) { s = ss; n = nn; }
2423 *s = NUL;
2424 } else { /* None of those but (bc > 0) */
2425 lastcomma = s;
2426 *s++ = ','; /* and insert a comma */
2427 n--;
2428 }
2429 #ifdef COMMENT
2430 debug(F101,"getnct bc","",bc);
2431 debug(F100,"getnct continued","",0);
2432 #endif /* COMMENT */
2433
2434 *s = NUL;
2435 prev = s;
2436
2437 } /* read-lines while loop */
2438
2439 if (lastcomma)
2440 *lastcomma = SP;
2441 if (!flag) /* Tack line terminator back on */
2442 *s++ = c;
2443 *s++ = NUL; /* Terminate the string */
2444 untab(s2); /* Done, convert tabs to spaces */
2445 #ifdef DEBUG
2446 if (!flag) {
2447 debug(F010,"CMD(F)",s2,0);
2448 }
2449 #endif /* DEBUG */
2450 {
2451 int i = 0; char *s = s2; char prev = '\0'; char c = '\0';
2452 while (*s) { /* Save beginning of this command for error messages */
2453 c = *s++;
2454 if (c == '\n' || c == '\r') c = SP;
2455 if (c == SP && prev == SP) /* Squeeze spaces */
2456 continue;
2457 lasttakeline[i++] = c;
2458 prev = c;
2459 if (i > TMPBUFSIZ-5) {
2460 lasttakeline[i++] = '.';
2461 lasttakeline[i++] = '.';
2462 lasttakeline[i++] = '.';
2463 lasttakeline[i++] = NUL;
2464 break;
2465 }
2466 }
2467 i = (int)strlen((char *)lasttakeline) - 1;
2468 while (i > 0 && lasttakeline[i] == SP) { /* Trim treailing spaces */
2469 lasttakeline[i] = NUL;
2470 i--;
2471 } }
2472 free(lpx); /* Free temporary storage */
2473 return(0); /* Return success */
2474 }
2475
2476 VOID
shostack()2477 shostack() { /* Dump the command stack */
2478 int i;
2479 char *p;
2480 #ifndef NOSPL
2481 for (i = cmdlvl; i > 0; i--) {
2482 if (cmdstk[i].src == CMD_TF) {
2483 p = tfnam[cmdstk[i].lvl];
2484 if (zfnqfp(p,TMPBUFSIZ,tmpbuf))
2485 p = tmpbuf;
2486 printf(" %2d. File : %s (line %d)\n",
2487 i,
2488 p,
2489 tfline[cmdstk[i].lvl]
2490 );
2491 } else if (cmdstk[i].src == CMD_MD) {
2492 char * m;
2493 m = m_arg[cmdstk[i].lvl][0]; /* Name of this macro */
2494 if (i > 0) { /* Special handling for 2-level */
2495 char *s; /* built-in macros... */
2496 s = m_arg[cmdstk[i-1].lvl][0]; /* Name next level up */
2497 if (s && cmdstk[i-1].src == CMD_MD) {
2498 if (!strcmp(s,"_forx"))
2499 m = "FOR";
2500 else if (!strcmp(s,"_xif"))
2501 m = "XIF";
2502 else if (!strcmp(s,"_while"))
2503 m = "WHILE";
2504 else if (!strcmp(s,"_switx"))
2505 m = "SWITCH";
2506 }
2507 }
2508 printf(" %2d. Macro : %s\n",i,m);
2509 } else if (cmdstk[i].src == CMD_KB) {
2510 printf(" %2d. Prompt:\n",i);
2511 } else {
2512 printf(" %2d. ERROR : Command source unknown\n",i);
2513 }
2514 }
2515 #else
2516 for (i = tlevel; i > -1; i--) {
2517 p = tfnam[i];
2518 if (zfnqfp(p,TMPBUFSIZ,tmpbuf))
2519 p = tmpbuf;
2520 printf(" %2d. File : %s (line %d)\n",
2521 i,
2522 p,
2523 tfline[i]
2524 );
2525 }
2526 #endif /* NOSPL */
2527 if (i == 0)
2528 printf(" %2d. Prompt: (top level)\n",0);
2529 }
2530
2531 /* For command error messages - avoid dumping out the contents of some */
2532 /* some huge FOR loop if it contains a syntax error. */
2533
2534 static char *
cmddisplay(s,cx)2535 cmddisplay(s, cx) char * s; int cx; {
2536 static char buf[80];
2537 if ((int)strlen(s) > 70) {
2538 sprintf(buf,"%.64s...",s); /* SAFE */
2539 s = buf;
2540 }
2541 return(s);
2542 }
2543
2544 static VOID
cmderr()2545 cmderr() {
2546 if (xcmdsrc > 0) {
2547 switch (cmd_err) { /* SET COMMAND ERROR-DISPLAY */
2548 case 0:
2549 break;
2550 case 1:
2551 case 2:
2552 if (tlevel > -1) {
2553 #ifndef NOSPL
2554 if (xcmdsrc == 2)
2555 printf(
2556 "In macro or block defined in file: %s starting about line %d\n",
2557 tfnam[tlevel] ? tfnam[tlevel] : "", tfline[tlevel]
2558 );
2559 else
2560 #endif /* NOSPL */
2561 printf("File: %s, Line: %d\n",
2562 tfnam[tlevel] ? tfnam[tlevel] : "", tfline[tlevel]
2563 );
2564 }
2565 #ifndef NOSPL
2566 if (cmd_err == 2) {
2567 if (cmdstk[cmdlvl].src == CMD_MD) { /* Executing a macro? */
2568 int m;
2569 m = cmdstk[cmdlvl].lvl;
2570 if (mlook(mactab,m_arg[m][0],nmac) >= 0)
2571 printf("Macro name: %s\n", m_arg[m][0]);
2572 }
2573 }
2574 #endif /* NOSPL */
2575 break;
2576
2577 case 3:
2578 printf("Command stack:\n");
2579 shostack();
2580 }
2581 }
2582 }
2583
2584 /* P A R S E R -- Top-level interactive command parser. */
2585
2586 /*
2587 Call with:
2588 m = 0 for normal behavior: keep parsing and executing commands
2589 until an action command is parsed, then return with a
2590 Kermit start-state as the value of this function.
2591 m = 1 to parse only one command, can also be used to call parser()
2592 recursively.
2593 m = 2 to read but do not execute one command.
2594 In all cases, parser() returns:
2595 0 if no Kermit protocol action required
2596 > 0 with a Kermit protocol start-state.
2597 < 0 upon error.
2598 */
2599 int
parser(m)2600 parser(m) int m; {
2601 int tfcode, xx, yy, zz; /* Workers */
2602 int is_tn = 0;
2603 int cdlost = 0;
2604
2605 #ifndef NOSPL
2606 int inlevel; /* Level we were called at */
2607 extern int askflag, echostars;
2608 #endif /* NOSPL */
2609 char *cbp; /* Command buffer pointer */
2610 #ifdef MAC
2611 extern char *lfiles; /* Fake extern cast */
2612 #endif /* MAC */
2613 extern int interrupted;
2614 #ifndef NOXFER
2615 extern int sndcmd, getcmd, fatalio, clearrq;
2616 #endif /* NOXFER */
2617
2618 #ifdef AMIGA
2619 reqres(); /* Restore AmigaDOS requestors */
2620 #endif /* AMIGA */
2621
2622 #ifdef OS2
2623 if (cursor_save > -1) { /* Restore cursor if it was */
2624 cursorena[VCMD] = cursor_save; /* turned off during file transfer */
2625 cursor_save = -1;
2626 }
2627 #endif /* OS2 */
2628
2629 #ifdef IKSDB
2630 if (ikdbopen) slotstate(what,"COMMAND PROMPT","",""); /* IKSD database */
2631 #endif /* IKSDB */
2632
2633 is_tn = (local && network && IS_TELNET()) ||
2634 (!local && sstelnet);
2635
2636 if (!xcmdsrc) /* If at top (interactive) level ... */
2637 concb((char)escape); /* put console in 'cbreak' mode. */
2638
2639 #ifdef CK_TMPDIR
2640 /* If we were cd'd temporarily to another device or directory ... */
2641 if (f_tmpdir) {
2642 int x;
2643 x = zchdir((char *) savdir); /* ... restore previous directory */
2644 f_tmpdir = 0; /* and remember we did it. */
2645 debug(F111,"parser tmpdir restoring",savdir,x);
2646 }
2647 #endif /* CK_TMPDIR */
2648
2649 #ifndef NOSPL
2650 inlevel = cmdlvl; /* Current macro level */
2651 #ifdef DEBUG
2652 if (deblog) {
2653 debug(F101,"&parser entry maclvl","",maclvl);
2654 debug(F101,"&parser entry inlevel","",inlevel);
2655 debug(F101,"&parser entry tlevel","",tlevel);
2656 debug(F101,"&parser entry cmdlvl","",cmdlvl);
2657 debug(F101,"&parser entry m","",m);
2658 }
2659 #endif /* DEBUG */
2660 #endif /* NOSPL */
2661
2662 #ifndef NOXFER
2663 ftreset(); /* Reset global file settings */
2664 #endif /* NOXFER */
2665 /*
2666 sstate becomes nonzero when a command has been parsed that requires some
2667 action from the protocol module. Any non-protocol actions, such as local
2668 directory listing or terminal emulation, are invoked directly from below.
2669 */
2670 sstate = 0; /* Start with no start state. */
2671
2672 #ifndef NOXFER
2673 #ifndef NOSPL
2674 query = 0; /* QUERY not active */
2675 #endif /* NOSPL */
2676 #ifndef NOHINTS
2677 if (!success) {
2678 if (local && !network && carrier != CAR_OFF) {
2679 int x; /* Serial connection */
2680 x = ttgmdm(); /* with carrier checking */
2681 if (x > -1) {
2682 if (!(x & BM_DCD)) {
2683 cdlost = 1;
2684 fatalio = 1;
2685 }
2686 }
2687 }
2688 }
2689 #ifdef DEBUG
2690 if (deblog) {
2691 debug(F101,"parser top what","",what);
2692 debug(F101,"parser top interrupted","",interrupted);
2693 debug(F101,"parser top cdlost","",cdlost);
2694 debug(F101,"parser top sndcmd","",sndcmd);
2695 debug(F101,"parser top getcmd","",getcmd);
2696 }
2697 #endif /* DEBUG */
2698 if (cdlost && !interrupted && (sndcmd || getcmd)) {
2699 printf("?Connection broken (carrier signal lost)\n");
2700 }
2701 if (sndcmd && protocol == PROTO_K &&
2702 !success && hints && !interrupted && !fatalio && !xcmdsrc) {
2703 int x = 0, n = 0;
2704 printf("\n*************************\n");
2705 printf("SEND-class command failed.\n");
2706 printf(" Packets sent: %d\n", spackets);
2707 printf(" Retransmissions: %d\n",retrans);
2708 printf(" Timeouts: %d\n", timeouts);
2709 printf(" Damaged packets: %d\n", crunched);
2710 if (epktrcvd) {
2711 printf(" Transfer canceled by receiver.\n");
2712 printf(" Receiver's message: \"%s\"\n",(char *)epktmsg);
2713 n++;
2714 } else {
2715 if (epktmsg) if (*epktmsg) {
2716 printf(" Fatal Kermit Protocol Error: %s\n",epktmsg);
2717 n++;
2718 }
2719 }
2720 if (local && !network && carrier != CAR_OFF) {
2721 int xx; /* Serial connection */
2722 xx = ttgmdm(); /* with carrier checking */
2723 if (xx > -1) {
2724 if (!(xx & BM_DCD))
2725 cdlost = 1;
2726 }
2727 }
2728
2729 #ifdef UNIX
2730 if (errno != 0)
2731 #endif /* UNIX */
2732 {
2733 printf(" Most recent local OS error: \"%s\"\n",ck_errstr());
2734 n++;
2735 }
2736 printf(
2737 "\nHINTS... If the preceding error message%s not explain the failure:\n",
2738 (n > 1) ? "s do" : " does"
2739 );
2740 #ifndef NOLOCAL
2741 if (local) {
2742 if (rpackets == 0) {
2743 printf(" . Did you start a Kermit receiver on the far end?\n");
2744 } else {
2745 printf(
2746 " . Try changing the remote Kermit's FLOW-CONTROL setting.\n");
2747 if (!network && mdmtyp > 0)
2748 if ((3 * crunched) > spackets)
2749 printf(
2750 " . Try placing a new call to get a cleaner connection.\n");
2751 }
2752 } else if (rpackets > 0) {
2753 if (flow == FLO_NONE)
2754 printf(" . Give me a SET FLOW XON/XOFF command and try again.\n");
2755 else
2756 printf(" . Give me a SET FLOW NONE command and try again.\n");
2757 }
2758 x++;
2759 #endif /* NOLOCAL */
2760
2761 if ((3 * timeouts) > spackets)
2762 printf(" . Adjust the timeout method (see HELP SET SEND).\n");
2763 if ((3 * retrans) > spackets)
2764 printf(" . Increase the retry limit (see HELP SET RETRY).\n");
2765
2766 #ifdef CK_SPEED
2767 if (prefixing != PX_ALL && rpackets > 2) {
2768 printf(" . Try it again with: SET PREFIXING ALL\n");
2769 x++;
2770 }
2771 #endif /* CK_SPEED */
2772 #ifdef STREAMING
2773 if (streamed) {
2774 printf(" . Try it again with: SET STREAMING OFF\n");
2775 x++;
2776 } else if (reliable) {
2777 printf(" . Try it again with: SET RELIABLE OFF\n");
2778 x++;
2779 }
2780 #endif /* STREAMING */
2781
2782 #ifdef CK_SPEED
2783 if (clearrq > 0 && prefixing == PX_NON) {
2784 printf(" . Try it again with: SET CLEAR-CHANNEL OFF\n");
2785 x++;
2786 }
2787 #endif /* CK_SPEED */
2788 if (!parity) {
2789 printf(" . Try it again with: SET PARITY SPACE\n");
2790 x++;
2791 }
2792 printf(" . %sive a ROBUST command and try again.\n",
2793 (x > 0) ? "As a last resort, g" : "G"
2794 );
2795 printf("Also:\n");
2796 printf(" . Be sure the source file has read permission.\n");
2797 printf(" . Be sure the target directory has write permission.\n");
2798 /*
2799 if the file was 2G or larger make sure other Kermit supports LFs...
2800 */
2801 printf(" . Be sure the target disk has sufficient space.\n");
2802 printf("(Use SET HINTS OFF to suppress hints.)\n");
2803 printf("*************************\n\n");
2804 }
2805 debug(F101,"topcmd","",topcmd);
2806 if (getcmd && protocol == PROTO_K &&
2807 !success && hints && !interrupted && !fatalio && !xcmdsrc) {
2808 int x = 0;
2809 extern int urpsiz, wslotr;
2810 printf("\n*************************\n");
2811 printf("RECEIVE- or GET-class command failed.\n");
2812 printf(" Packets received: %d\n", rpackets);
2813 printf(" Damaged packets: %d\n", crunched);
2814 printf(" Timeouts: %d\n", timeouts);
2815 if (rpackets > 0)
2816 printf(" Packet length: %d\n", urpsiz);
2817 if (epktrcvd) {
2818 printf(" Transfer canceled by sender.\n");
2819 printf(" Sender's message: \"%s\"\n",(char *)epktmsg);
2820 if (ckindex("not found",(char *)epktmsg,0,0,0) ||
2821 ckindex("no such",(char *)epktmsg,0,0,0)) {
2822 printf(" Did you spell the filename right?\n");
2823 printf(" Is the other Kermit CD'd to the right directory?\n");
2824 }
2825 }
2826 #ifdef UNIX
2827 if (errno != 0)
2828 #endif /* UNIX */
2829 {
2830 (VOID) ckstrncpy(tmpbuf,ck_errstr(),TMPBUFSIZ);
2831 printf(" Most recent local error: \"%s\"\n",tmpbuf);
2832 }
2833 #ifdef COMMENT
2834 printf(
2835 "\nHINTS... If the preceding error message%s not explain the failure:\n",
2836 epktrcvd ? "s do" : " does"
2837 );
2838 #ifndef NOLOCAL
2839 if (local) {
2840 if (topcmd == XXGET)
2841 printf(" . Did you start a Kermit SERVER on the far end?\n");
2842 if (rpackets == 0) {
2843 if (topcmd != XXGET)
2844 printf(" . Did you start a Kermit SENDer on the far end?\n");
2845 } else {
2846 printf(
2847 " . Choose a different FLOW-CONTROL setting and try again.\n");
2848 }
2849 } else if (topcmd == XXGET)
2850 printf(" . Is the other Kermit in (or does it have) SERVER mode?\n");
2851 if (rpackets > 0 && urpsiz > 90)
2852 printf(" . Try smaller packets (SET RECEIVE PACKET-LENGTH).\n");
2853 if (rpackets > 0 && wslotr > 1 && !streamed)
2854 printf(" . Try a smaller window size (SET WINDOW).\n");
2855 if (!local && rpackets > 0) {
2856 if (flow == FLO_NONE)
2857 printf(" . Give me a SET FLOW XON/XOFF command and try again.\n");
2858 else
2859 printf(" . Give me a SET FLOW NONE command and try again.\n");
2860 }
2861 x++;
2862 #endif /* NOLOCAL */
2863 #ifdef STREAMING
2864 if (streamed) {
2865 printf(" . Try it again with: SET STREAMING OFF\n");
2866 x++;
2867 } else if (reliable && local) {
2868 printf(" . Try it again with: SET RELIABLE OFF\n");
2869 x++;
2870 } else
2871 #endif /* STREAMING */
2872 if (!parity) {
2873 printf(" . Try it again with: SET PARITY SPACE\n");
2874 x++;
2875 }
2876 printf((x > 0) ?
2877 " . As a last resort, give a ROBUST command and try again.\n" :
2878 " . Give a ROBUST command and try again.\n"
2879 );
2880 #endif /* COMMENT */
2881 printf("Also:\n");
2882 printf(" . Be sure the target directory has write permission.\n");
2883 printf(" . Be sure the target disk has sufficient space.\n");
2884 printf(" . Try telling the %s to SET PREFIXING ALL.\n",
2885 topcmd == XXGET ? "server" : "sender"
2886 );
2887 printf(" . Try giving a ROBUST command to the %s.\n",
2888 topcmd == XXGET ? "server" : "sender"
2889 );
2890 printf("(Use SET HINTS OFF to suppress hints.)\n");
2891 printf("*************************\n\n");
2892 }
2893 #endif /* NOHINTS */
2894 getcmd = 0;
2895 sndcmd = 0;
2896 interrupted = 0;
2897 #endif /* NOXFER */
2898
2899 while (sstate == 0) { /* Parse cmds until action requested */
2900 debug(F100,"parse top","",0);
2901 what = W_COMMAND; /* Now we're parsing commands. */
2902 rcdactive = 0; /* REMOTE CD not active */
2903 keepallchars = 0; /* MINPUT not active */
2904
2905 #ifdef OS2
2906 if (apcactive == APC_INACTIVE)
2907 WaitCommandModeSem(-1);
2908 #endif /* OS2 */
2909 #ifdef IKS_OPTION
2910 if ((local &&
2911 !xcmdsrc &&
2912 is_tn &&
2913 TELOPT_ME(TELOPT_KERMIT) &&
2914 TELOPT_SB(TELOPT_KERMIT).kermit.me_start) ||
2915 (!local &&
2916 !cmdadl &&
2917 TELOPT_ME(TELOPT_KERMIT) &&
2918 TELOPT_SB(TELOPT_KERMIT).kermit.me_start)
2919 ) {
2920 tn_siks(KERMIT_STOP);
2921 }
2922 #endif /* IKS_OPTION */
2923
2924 #ifndef NOXFER
2925 if (autopath) {
2926 fnrpath = PATH_AUTO;
2927 autopath = 0;
2928 }
2929 remfile = 0; /* Clear these in case REMOTE */
2930 remappd = 0; /* command was interrupted... */
2931 rempipe = 0;
2932 makestr(&snd_move,g_snd_move); /* Restore these */
2933 makestr(&rcv_move,g_rcv_move);
2934 makestr(&snd_rename,g_snd_rename);
2935 makestr(&rcv_rename,g_rcv_rename);
2936 #endif /* NOXFER */
2937
2938 /* Take requested action if there was an error in the previous command */
2939
2940 setint();
2941 debug(F101,"parser tlevel","",tlevel);
2942 debug(F101,"parser cmd_rows","",cmd_rows);
2943
2944 #ifndef NOLOCAL
2945 debug(F101,"parser wasclosed","",wasclosed);
2946 if (wasclosed) { /* If connection was just closed */
2947 #ifndef NOSPL
2948 int k;
2949 k = mlook(mactab,"on_close",nmac); /* Look up "on_close" */
2950 if (k >= 0) { /* If found, */
2951 /* printf("ON_CLOSE CMD LOOP\n"); */
2952 dodo(k,ckitoa(whyclosed),0); /* Set it up */
2953 }
2954 #endif /* NOSPL */
2955 whyclosed = WC_REMO;
2956 wasclosed = 0;
2957 }
2958 #endif /* NOLOCAL */
2959
2960 #ifndef NOSPL
2961 xxdot = 0; /* Clear this... */
2962
2963 debug(F101,"parser success","",success);
2964 if (success == 0) {
2965 if (cmdstk[cmdlvl].src == CMD_TF && takerr[cmdlvl]) {
2966 printf("Command file terminated by error.\n");
2967 popclvl();
2968 if (cmdlvl == 0) return(0);
2969 }
2970 if (cmdstk[cmdlvl].src == CMD_MD && merror[cmdlvl]) {
2971 printf("Command error: macro terminated.\n");
2972 popclvl();
2973 if (m && (cmdlvl < inlevel))
2974 return((int) sstate);
2975 }
2976 }
2977 nulcmd = (m == 2);
2978 debug(F101,"parser nulcmd","",nulcmd);
2979 #else
2980 if (success == 0 && tlevel > -1 && takerr[tlevel]) {
2981 printf("Command file terminated by error.\n");
2982 popclvl();
2983 cmini(ckxech); /* Clear the cmd buffer. */
2984 if (tlevel < 0) /* Just popped out of cmd files? */
2985 return(0); /* End of init file or whatever. */
2986 }
2987 #endif /* NOSPL */
2988
2989 #ifdef MAC
2990 /* Check for TAKE initiated by menu. */
2991 if ((tlevel == -1) && lfiles)
2992 startlfile();
2993 #endif /* MAC */
2994
2995 /* If in TAKE file, check for EOF */
2996 #ifndef NOSPL
2997 #ifdef MAC
2998 if
2999 #else
3000 while
3001 #endif /* MAC */
3002 ((cmdstk[cmdlvl].src == CMD_TF) /* If end of take file */
3003 && (tlevel > -1)
3004 && feof(tfile[tlevel])) {
3005 popclvl(); /* pop command level */
3006 cmini(ckxech); /* and clear the cmd buffer. */
3007 if (cmdlvl == 0) { /* Just popped out of all cmd files? */
3008 return(0); /* End of init file or whatever. */
3009 }
3010 }
3011 #ifdef MAC
3012 miniparser(1);
3013 if (sstate == 'a') { /* if cmd-. cancel */
3014 debug(F100, "parser: cancel take due to sstate", "", sstate);
3015 sstate = '\0';
3016 dostop();
3017 return(0); /* End of init file or whatever. */
3018 }
3019 #endif /* MAC */
3020
3021 #else /* NOSPL */
3022 if ((tlevel > -1) && feof(tfile[tlevel])) { /* If end of take */
3023 popclvl(); /* Pop up one level. */
3024 cmini(ckxech); /* and clear the cmd buffer. */
3025 if (tlevel < 0) /* Just popped out of cmd files? */
3026 return(0); /* End of init file or whatever. */
3027 }
3028 #endif /* NOSPL */
3029
3030
3031 #ifndef NOSPL
3032 debug(F101,"parser cmdlvl","",cmdlvl);
3033 debug(F101,"parser cmdsrc","",cmdstk[cmdlvl].src);
3034
3035 if (cmdstk[cmdlvl].src == CMD_MD) { /* Executing a macro? */
3036 debug(F100,"parser macro","",0);
3037 maclvl = cmdstk[cmdlvl].lvl; /* Get current level */
3038 debug(F101,"parser maclvl","",maclvl);
3039 cbp = cmdbuf; /* Copy next cmd to command buffer. */
3040 *cbp = NUL;
3041 if (*savbuf) { /* In case then-part of 'if' command */
3042 ckstrncpy(cbp,savbuf,CMDBL); /* was saved, restore it. */
3043 *savbuf = '\0';
3044 } else { /* Else get next cmd from macro def */
3045 if (getncm(cbp,CMDBL) < 0) {
3046 #ifdef DEBUG
3047 if (deblog) {
3048 debug(F101,"parser end of macro m","",m);
3049 debug(F101,"parser end of macro cmdlvl","",cmdlvl);
3050 debug(F101,"parser end of macro inlevel","",inlevel);
3051 }
3052 #endif /* DEBUG */
3053 if (m && (cmdlvl < inlevel))
3054 return((int) sstate);
3055 else /* if (!m) */ continue;
3056 }
3057 }
3058 debug(F010,"CMD(M)",cmdbuf,0);
3059
3060 } else if (cmdstk[cmdlvl].src == CMD_TF)
3061 #else
3062 if (tlevel > -1)
3063 #endif /* NOSPL */
3064 {
3065 #ifndef NOSPL
3066 debug(F111,"parser savbuf",savbuf,tlevel);
3067 if (*savbuf) { /* In case THEN-part of IF command */
3068 ckstrncpy(cmdbuf,savbuf,CMDBL); /* was saved, restore it. */
3069 *savbuf = '\0';
3070 } else
3071 #endif /* NOSPL */
3072
3073 /* Get next line from TAKE file */
3074
3075 if ((tfcode = getnct(cmdbuf,CMDBL,tfile[tlevel],0)) < 0) {
3076 debug(F111,"parser tfcode",tfile[tlevel],tfcode);
3077 if (tfcode < -1) { /* Error */
3078 printf("?Error in TAKE command file: %s\n",
3079 (tfcode == -2) ? "Memory allocation failure" :
3080 "Line too long or contains NUL characters"
3081 );
3082 dostop();
3083 }
3084 continue; /* -1 means EOF */
3085 }
3086
3087 /* If interactive, get next command from user. */
3088
3089 } else { /* User types it in. */
3090 if (pflag) prompt(xxstring);
3091 cmini(ckxech);
3092 }
3093
3094 /* Now we know where next command is coming from. Parse and execute it. */
3095
3096 repars = 1; /* 1 = command needs parsing */
3097 #ifndef NOXFER
3098 displa = 0; /* Assume no file transfer display */
3099 #endif /* NOXFER */
3100
3101 while (repars) { /* Parse this cmd until entered. */
3102
3103 debug(F101,"parser top of while loop","",0);
3104 xaskmore = saveask; /* Restore global more-prompting */
3105 diractive = 0; /* DIR command not active */
3106 cdactive = 0; /* CD command not active */
3107 #ifndef NOSPL
3108 askflag = 0; /* ASK command not active */
3109 echostars = 0; /* Nor ASKQ */
3110 debok = 1; /* Undisable debugging */
3111 #endif /* NOSPL */
3112
3113 #ifdef RECURSIVE
3114 /* In case of "send /recursive ./?<Ctrl-U>" etc */
3115 recursive = 0; /* This is never sticky */
3116 #endif /* RECURSIVE */
3117 xfiletype = -1; /* Reset this between each command */
3118 #ifndef NOMSEND
3119 addlist = 0;
3120 #endif /* NOMSEND */
3121 #ifdef CK_RECALL
3122 on_recall = 1;
3123 #endif /* CK_RECALL */
3124 /* This might have been changed by a switch */
3125 if (g_matchdot > -1) {
3126 matchdot = g_matchdot;
3127 g_matchdot = -1;
3128 }
3129 cmres(); /* Reset buffer pointers. */
3130
3131 #ifdef OS2
3132 #ifdef COMMENT
3133 /* we check to see if a macro is waiting to be executed */
3134 /* if so, we call domac on it */
3135 if (cmdmac) {
3136 ckstrncpy(cmdbuf, cmdmac, CMDBL);
3137 free(cmdmac);
3138 cmdmac = NULL;
3139 }
3140 #endif /* COMMENT */
3141 #endif /* OS2 */
3142 #ifndef NOXFER
3143 bye_active = 0;
3144 #endif /* NOXFER */
3145 havetoken = 0;
3146 xx = cmkey2(cmdtab,ncmd,"Command","",toktab,xxstring,1);
3147 debug(F101,"top-level cmkey2","",xx);
3148 if (xx == -5) {
3149 yy = chktok(toktab);
3150 debug(F101,"top-level cmkey token","",yy);
3151 #ifndef COMMENT
3152 /* Either way makes absolutely no difference */
3153 debug(F110,"NO UNGWORD",atmbuf,0);
3154 /* ungword(); */
3155 #else
3156 debug(F110,"TOKEN UNGWORD",atmbuf,0);
3157 ungword();
3158 #endif /* COMMENT */
3159 switch (yy) {
3160 case '#': xx = XXCOM; break; /* Comment */
3161 case ';': xx = XXCOM; break; /* Comment */
3162 #ifndef NOSPL
3163 case '.': xx = XXDEF; xxdot = 1; break; /* Assignment */
3164 case ':': xx = XXLBL; break; /* GOTO label */
3165 #endif /* NOSPL */
3166
3167 #ifndef NOPUSH
3168 #ifdef CK_REDIR
3169 case '<':
3170 #endif /* CK_REDIR */
3171 case '@':
3172 case '!':
3173 if (nopush) {
3174 char *s; int x;
3175 if ((x = cmtxt("Text to be ignored","",&s,NULL)) < 0)
3176 return(x);
3177 success = 0;
3178 xx = XXCOM;
3179 } else {
3180 switch(yy) {
3181 #ifdef CK_REDIR
3182 case '<': xx = XXFUN; break; /* REDIRECT */
3183 #endif /* CK_REDIR */
3184 case '@':
3185 case '!': xx = XXSHE; break; /* Shell escape */
3186 }
3187 }
3188 break;
3189 #endif /* NOPUSH */
3190 #ifdef CK_RECALL
3191 case '^': xx = XXREDO; break;
3192 #endif /* CK_RECALL */
3193 #ifndef NOSPL
3194 case '{': xx = XXMACRO; break;
3195 case '(': xx = XXSEXP; break;
3196 #endif /* NOSPL */
3197
3198 default:
3199 if (!quiet && !cmd_err) {
3200 printf("\n?Not a valid command or token - \"%s\"\n",
3201 cmddisplay((char *)cmdbuf,xx)
3202 );
3203 /* cmderr(); */ newerrmsg("");
3204 }
3205 xx = -2;
3206 }
3207 havetoken = 1;
3208 debug(F101,"HAVE TOKEN","",xx);
3209 }
3210 if (xx > -1) {
3211 topcmd = xx; /* Top-level command index */
3212 #ifndef NOSPL
3213 if (maclvl > -1)
3214 lastcmd[maclvl] = xx;
3215 #endif /* NOSPL */
3216 debug(F101,"topcmd","",topcmd);
3217 debug(F101,"cmflgs","",cmflgs);
3218 }
3219
3220 #ifndef NOSPL
3221 /* Special handling for IF..ELSE */
3222
3223 debug(F101,"cmdlvl","",cmdlvl);
3224 debug(F101,"ifcmd[cmdlvl]","",ifcmd[cmdlvl]);
3225
3226 if (ifcmd[cmdlvl]) /* Count stmts after IF */
3227 ifcmd[cmdlvl]++;
3228 if (ifcmd[cmdlvl] > 2 && xx != XXELS && xx != XXCOM)
3229 ifcmd[cmdlvl] = 0;
3230
3231 /* Execute the command and take action based on return code. */
3232
3233 if (nulcmd) { /* Ignoring this command? */
3234 xx = XXCOM; /* Make this command a comment. */
3235 }
3236 fnsuccess = 1; /* For catching \function() errors */
3237 #endif /* NOSPL */
3238
3239 debug(F101,"calling docmd()","",xx);
3240 zz = docmd(xx); /* Parse rest of command & execute. */
3241
3242 #ifndef NOSPL
3243 { /* For \v(lastcommand) */
3244 extern char * prevcmd;
3245 /* The exception list kind of a hack but let's try it... */
3246 if (ckstrcmp(cmdbuf,"_getarg",7,0) &&
3247 ckstrcmp(cmdbuf,"if ",3,0) &&
3248 ckstrcmp(cmdbuf,"xif ",4,0) &&
3249 ckstrcmp(cmdbuf,"do _if",6,0) &&
3250 ckstrcmp(cmdbuf,"_assign _if",11,0))
3251 ckstrncpy(prevcmd,cmdbuf,CMDBL);
3252 }
3253 #endif /* NOSPL */
3254
3255 #ifndef NOSPL
3256 if (fnerror && !fnsuccess)
3257 success = 0;
3258 #endif /* NOSPL */
3259 debug(F101,"docmd returns","",zz);
3260 /* debug(F011,"cmdbuf",cmdbuf,30); */
3261 /* debug(F011,"atmbuf",atmbuf,30); */
3262 #ifdef MAC
3263 if (tlevel > -1) {
3264 if (sstate == 'a') { /* if cmd-. cancel */
3265 debug(F110, "parser: cancel take, sstate:", "a", 0);
3266 sstate = '\0';
3267 dostop();
3268 return(0); /* End of init file or whatever. */
3269 }
3270 }
3271 #endif /* MAC */
3272
3273 switch (zz) {
3274 case -4: /* EOF (e.g. on redirected stdin) */
3275 doexit(GOOD_EXIT,xitsta); /* ...exit successfully */
3276 case -1: /* Reparse needed */
3277 repars = 1; /* Just set reparse flag and... */
3278 continue;
3279 #ifdef OS2
3280 case -7: /* They typed a disk letter */
3281 if (!zchdir((char *)cmdbuf)) {
3282 perror((char *)cmdbuf);
3283 success = 0;
3284 } else success = 1;
3285 repars = 0;
3286 continue;
3287
3288 #endif /* OS2 */
3289 /*
3290 Changed 2013-12-06 fdc: Previously the failing command was echoed only in
3291 the -6 and -9 cases. This made it difficult to know exactly which command
3292 had failed when a macro or command file was being executed and the failing
3293 command had already issued its own error message and returned -9. Now we
3294 include -9 in the caselist for this code, but we echo the failing command
3295 only if Kermit is not at top level. So now, even though the error message
3296 is imprecise about *where* the failing command was, at least it shows the
3297 failing command.
3298 */
3299 case -9: /* Bad, error message already done */
3300 case -6: /* Invalid command given w/no args */
3301 case -2: /* Invalid command given w/args */
3302 if (zz == -2 || zz == -6 || (zz == -9 && cmdlvl > 0)) {
3303 int x = 0;
3304 char * eol = "";
3305 x = strlen(cmdbuf); /* Avoid blank line */
3306 #ifdef COMMENT
3307 if (x > 0) {
3308 if (cmdbuf[x-1] != LF)
3309 eol = "\n";
3310 printf("?Invalid: %s%s",
3311 cmddisplay(cmdbuf,xx),eol
3312 );
3313 } else
3314 printf("?Invalid\n");
3315 #else
3316 if (x > 0)
3317 newerrmsg("Syntax error");
3318 #endif /* COMMENT */
3319 }
3320 success = 0;
3321 debug(F110,"top-level cmkey failed",cmdbuf,0);
3322 /* If in background w/ commands coming stdin, terminate */
3323 if (pflag == 0 && tlevel < 0)
3324 fatal("Kermit command error in background execution");
3325 /*
3326 Command retry feature, edit 190. If we're at interactive prompting level,
3327 reprompt the user with as much of the command as didn't fail.
3328 */
3329 #ifdef CK_RECALL
3330 if (cm_retry && !xcmdsrc) { /* If at top level */
3331 int len;
3332 char *p, *s;
3333 len = strlen(cmdbuf); /* Length of command buffer */
3334 p = malloc(len + 1); /* Allocate space for copy */
3335 if (p) { /* If we got the space copy */
3336 strcpy(p,cmdbuf); /* the command buffer (SAFE). */
3337 /* Chop off final field, the one that failed. */
3338 s = p + len - 1; /* Point to end */
3339 while (*s == SP && s > p) /* Trim blanks */
3340 s--;
3341 while (*s != SP && s > p) /* Trim last field */
3342 s--;
3343 if (s > p) /* Keep the space */
3344 s++; /* after last good field */
3345 if (s >= p) /* Cut off remainder */
3346 *s = NUL;
3347 cmini(ckxech); /* Reinitialize the parser */
3348 ckstrncpy(cmdbuf,p,CMDBL); /* Copy result back */
3349 free(p); /* Free temporary storage */
3350 p = NULL;
3351 prompt(xxstring); /* Reprint the prompt */
3352 printf("%s",cmdbuf); /* Reprint partial command */
3353 repars = 1; /* Force reparse */
3354 continue;
3355 }
3356 } else
3357 #endif /* CK_RECALL */
3358 /* cmderr(); */ newerrmsg("");
3359
3360 cmini(ckxech); /* (fall thru) */
3361
3362 case -3: /* Empty command OK at top level */
3363 repars = 0; /* Don't need to reparse. */
3364 continue; /* Go back and get another command. */
3365
3366 default: /* Command was successful. */
3367 #ifndef NOSPL
3368 debug(F101,"parser preparing to continue","",maclvl);
3369 #endif /* NOSPL */
3370 debug(F101,"parser success","",success);
3371 repars = 0; /* Don't need to reparse. */
3372 continue; /* Go back and get another command. */
3373 }
3374 }
3375 #ifndef NOSPL
3376 debug(F101,"parser breaks out of while loop","",maclvl);
3377 if (m && (cmdlvl < inlevel)) return((int) sstate);
3378 #endif /* NOSPL */
3379 }
3380
3381 /* Got an action command, return start state. */
3382
3383 return((int) sstate);
3384 }
3385
3386 #ifndef NOSPL
3387 /*
3388 OUTPUT command.
3389 Buffering and pacing added by L.I. Kirby, 5A(189), June 1993.
3390 */
3391 #define OBSIZE 80 /* Size of local character buffer */
3392
3393 static int obn; /* Buffer offset (high water mark) */
3394 static char obuf[OBSIZE+1]; /* OUTPUT buffer. */
3395 static char *obp; /* Pointer to output buffer. */
3396 _PROTOTYP( static int oboc, (char) );
3397 _PROTOTYP( static int xxout, (char *, int) );
3398
3399 static int
3400 #ifdef CK_ANSIC
xxout(char * obuf,int obsize)3401 xxout(char *obuf, int obsize)
3402 #else
3403 xxout(obuf, obsize) char *obuf; int obsize;
3404 #endif /* CK_ANSIC */
3405 /* xxout */ { /* OUTPUT command's output function */
3406 int i, rc;
3407
3408 debug(F101,"xxout obsize","",obsize);
3409 debug(F101,"xxout pacing","",pacing);
3410 debug(F111,"xxout string",obuf,strlen(obuf));
3411
3412 rc = 0; /* Initial return code. */
3413 if (!obuf || (obsize <= 0)) /* Nothing to output. */
3414 goto xxout_x; /* Return successfully */
3415
3416 rc = -1; /* Now assume failure */
3417 if (pacing == 0) { /* Is pacing enabled? */
3418 if ((local ? /* No, write entire string at once */
3419 ttol((CHAR *)obuf, obsize) : /* to communications device */
3420 conxo(obsize, obuf)) /* or to console */
3421 != obsize)
3422 goto xxout_x;
3423 } else {
3424 for (i = 0; i < obsize; i++) { /* Write individual chars */
3425 if ((local ? ttoc(obuf[i]) : conoc(obuf[i])) < 0)
3426 goto xxout_x;
3427 msleep(pacing);
3428 }
3429 }
3430 if (duplex) {
3431 #ifdef OS2
3432 if (inecho && local) {
3433 #ifndef NOLOCAL
3434 for (i = 0; i < obsize; i++) { /* Write to emulator */
3435 scriptwrtbuf((USHORT)obuf[i]); /* which also logs session */
3436 }
3437 #endif /* NOLOCAL */
3438 conxo(obsize,obuf);
3439 } else if (seslog) { /* or log session here */
3440 logstr((char *) obuf, obsize);
3441 }
3442 #else /* OS2 */
3443 if (seslog) {
3444 logstr((char *) obuf, obsize);
3445 }
3446 if (inecho && local) {
3447 conxo(obsize,obuf);
3448 }
3449 #endif /* OS2 */
3450 }
3451 rc = 0; /* Success */
3452 xxout_x:
3453 obn = 0; /* Reset count */
3454 obp = obuf; /* and pointers */
3455 return(rc); /* return our return code */
3456 }
3457
3458 #ifdef COMMENT
3459 /*
3460 Macros for OUTPUT command execution, to make it go faster.
3461 */
3462 #define obfls() ((xxout(obuf,obn)<0)?-1:0)
3463 #define oboc(c) ((*obp++=(char)(c)),*obp=0,(((++obn)>=OBSIZE)?obfls():0))
3464
3465 #else /* The macros cause some compilers to generate bad code. */
3466
3467 static int
3468 #ifdef CK_ANSIC
oboc(char c)3469 oboc(char c)
3470 #else
3471 oboc(c) char c;
3472 #endif /* CK_ANSIC */
3473 /* oboc */ { /* OUTPUT command's output function */
3474
3475 *obp++ = c; /* Deposit character */
3476 *obp = NUL; /* Flush buffer if it's now full */
3477
3478 return(((++obn) >= OBSIZE) ? xxout(obuf,obn) : 0);
3479 }
3480 #endif /* COMMENT */
3481
3482 /* Routines for handling local variables -- also see popclvl(). */
3483
3484 VOID
freelocal(m)3485 freelocal(m) int m; { /* Free local variables */
3486 struct localvar * v, * tv; /* at macro level m... */
3487 debug(F101,"freelocal level","",m);
3488 if (m < 0) return;
3489 v = localhead[m]; /* List head for level m */
3490 while (v) {
3491 if (v->lv_name) /* Variable name */
3492 free(v->lv_name);
3493 if (v->lv_value) /* Value */
3494 free(v->lv_value);
3495 tv = v; /* Save pointer to this node */
3496 v = v->lv_next; /* Get next one */
3497 if (tv) /* Free this one */
3498 free((char *)tv);
3499 }
3500 localhead[m] = (struct localvar *) NULL; /* Done, set list head to NULL */
3501 }
3502
3503 #define MAXLOCALVAR 64
3504
3505 /* Return a pointer to the definition of a user-defined variable */
3506
3507 static char *
vardef(s,isarray,x1,x2)3508 vardef(s,isarray,x1,x2) char * s; int * isarray, * x1, * x2; {
3509 char * p;
3510 char c;
3511 *isarray = 0;
3512 if (!s) return(NULL);
3513 if (!*s) return(NULL);
3514 p = s;
3515 if (*s == CMDQ) {
3516 p++;
3517 if (!*p)
3518 return(NULL);
3519 if ((c = *p) == '%') { /* Scalar variable. */
3520 c = *++p; /* Get ID character. */
3521 p = ""; /* Assume definition is empty */
3522 if (!c)
3523 return(NULL);
3524 if (c >= '0' && c <= '9') { /* Digit for macro arg */
3525 if (maclvl < 0) /* Digit variables are global */
3526 return(g_var[c]); /* if no macro is active */
3527 else /* otherwise */
3528 return(m_arg[maclvl][c - '0']); /* they're on the stack */
3529 } else if (isalpha(c)) {
3530 if (isupper(c)) c -= ('a'-'A');
3531 return(g_var[c]); /* Letter for global variable */
3532 } else
3533 return(NULL);
3534 } else if (c == '&') { /* Array reference. */
3535 int x, vbi, d;
3536 x = arraynam(p,&vbi,&d); /* Get name and subscript */
3537 if (x > -1 || d == -17) {
3538 *isarray = 1;
3539 *x1 = vbi;
3540 *x2 = (d == -17) ? 0 : d;
3541 }
3542 if (x < 0)
3543 return(NULL);
3544 if (chkarray(vbi,d) >= 0) { /* Array is declared? */
3545 vbi -= ARRAYBASE; /* Convert name to index */
3546 if (a_dim[vbi] >= d) { /* If subscript in range */
3547 char **ap;
3548 ap = a_ptr[vbi];
3549 return((ap) ? ap[d] : NULL);
3550 }
3551 }
3552 }
3553 return(NULL);
3554 } else {
3555 int k;
3556 k = mxlook(mactab,s,nmac);
3557 return((k > -1) ? mactab[k].mval : NULL);
3558 }
3559 }
3560
3561
3562 int
addlocal(p)3563 addlocal(p) char * p; {
3564 int x, z, isarray = 0;
3565 char * s;
3566 struct localvar * v, *prev = (struct localvar *)NULL;
3567 extern int tra_asg; int tra_tmp;
3568
3569 tra_tmp = tra_asg;
3570
3571 s = vardef(p,&isarray,&x,&z); /* Get definition of variable */
3572 if (isarray) { /* Arrays are handled specially */
3573 pusharray(x,z);
3574 return(0);
3575 }
3576 if (!s) s = "";
3577 if ((v = localhead[cmdlvl])) { /* Already have some at this level? */
3578 while (v) { /* Find end of list */
3579 prev = v;
3580 v = v->lv_next;
3581 }
3582 }
3583 v = (struct localvar *) malloc(sizeof(struct localvar));
3584 if (!v) {
3585 printf("?Failure to allocate storage for local variables");
3586 return(-9);
3587 }
3588 if (!localhead[cmdlvl]) /* If first, set list head */
3589 localhead[cmdlvl] = v;
3590 else /* Otherwise link previous to this */
3591 prev->lv_next = v;
3592 prev = v; /* And make this previous */
3593 v->lv_next = (struct localvar *) NULL; /* No next yet */
3594
3595 if (!(v->lv_name = (char *) malloc((int) strlen(p) + 1)))
3596 return(-1);
3597 strcpy(v->lv_name, p); /* Copy name into new node (SAFE) */
3598
3599 if (*s) {
3600 if (!(v->lv_value = (char *) malloc((int) strlen(s) + 1)))
3601 return(-1);
3602 strcpy(v->lv_value, s); /* Copy value into new node (SAFE) */
3603 } else
3604 v->lv_value = NULL;
3605
3606 tra_asg = 0;
3607 delmac(p,1); /* Delete the original macro */
3608 tra_asg = tra_tmp;
3609 return(0);
3610 }
3611
3612 int
dolocal()3613 dolocal() { /* Do the LOCAL command */
3614 int i, x;
3615 char * s;
3616 char * list[MAXLOCALVAR+2]; /* Up to 64 variables per line */
3617
3618 if ((x = cmtxt("Variable name(s)","",&s,NULL)) < 0)
3619 return(x);
3620
3621 xwords(s,MAXLOCALVAR,list,0); /* Break up line into "words" */
3622
3623 /* Note: Arrays do not use the localhead list, but have their own stack */
3624
3625 for (i = 1; i < MAXLOCALVAR && list[i]; i++) { /* Go through the list */
3626 if (addlocal(list[i]) < 0)
3627 goto localbad;
3628 }
3629 return(success = 1);
3630
3631 localbad:
3632 printf("?Failure to allocate storage for local variables");
3633 freelocal(cmdlvl);
3634 return(-9);
3635 }
3636
3637 /* D O O U T P U T -- Returns 0 on failure, 1 on success */
3638
3639 #ifndef NOKVERBS
3640 #define K_BUFLEN 30
3641 #define SEND_BUFLEN 255
3642 #define sendbufd(x) { osendbuf[sendndx++] = x;\
3643 if (sendndx == SEND_BUFLEN) {dooutput(s,cx); sendndx = 0;}}
3644 #endif /* NOKVERBS */
3645
3646 int outesc = 1; /* Process special OUTPUT escapes */
3647
3648 int
dooutput(s,cx)3649 dooutput(s, cx) char *s; int cx; {
3650 #ifdef SSHBUILTIN
3651 extern int ssh_cas;
3652 extern char * ssh_cmd;
3653 #endif /* SSHBUILTIN */
3654 int x, xx, y, quote; /* Workers */
3655 int is_tn = 0;
3656
3657 is_tn = (local && network && IS_TELNET()) ||
3658 (!local && sstelnet);
3659
3660 debug(F111,"dooutput s",s,(int)strlen(s));
3661
3662 if (local) { /* Condition external line */
3663 #ifdef NOLOCAL
3664 goto outerr;
3665 #else
3666 if (ttchk() < 0) {
3667 if (!network) {
3668 if (carrier != CAR_OFF) {
3669 int x;
3670 x = ttgmdm();
3671 if ((x > -1) && ((x & BM_DCD) == 0)) {
3672 printf(
3673 "?Carrier signal required but not present - Try SET CARRIER-WATCH OFF.\n"
3674 );
3675 return(0);
3676 }
3677 } else {
3678 printf(
3679 "?Problem with serial port or modem or cable - Try SHOW COMMUNICATIONS.\n"
3680 );
3681 return(0);
3682 }
3683 }
3684 printf("?Connection %s %s is not open or not functioning.\n",
3685 network ? "to" : "on",
3686 ttname
3687 );
3688 return(0);
3689 }
3690 if (ttvt(speed,flow) < 0) {
3691 printf("?OUTPUT initialization error\n");
3692 return(0);
3693 }
3694 #endif /* NOLOCAL */
3695 }
3696 #ifdef SSHBUILTIN
3697 if ( network && nettype == NET_SSH && ssh_cas && ssh_cmd &&
3698 !(strcmp(ssh_cmd,"kermit") && strcmp(ssh_cmd,"sftp"))) {
3699 if (!quiet)
3700 printf("?SSH Subsystem active: %s\n", ssh_cmd);
3701 return(0);
3702 }
3703 #endif /* SSHBUILTIN */
3704
3705 if (!cmdgquo()) { /* COMMAND QUOTING OFF */
3706 x = strlen(s); /* Just send the string literally */
3707 xx = local ? ttol((CHAR *)s,x) : conxo(x,s);
3708 return(success = (xx == x) ? 1 : 0);
3709 }
3710 quote = 0; /* Initialize backslash (\) quote */
3711 obn = 0; /* Reset count */
3712 obp = obuf; /* and pointers */
3713
3714 outagain:
3715 while ((x = *s++)) { /* Loop through the string */
3716 y = 0; /* Error code, 0 = no error. */
3717 debug(F000,"dooutput","",x);
3718 if (quote) { /* This character is quoted */
3719 #ifndef NOKVERBS
3720 if (x == 'k' || x == 'K') { /* \k or \K */
3721 extern struct keytab kverbs[];
3722 extern int nkverbs;
3723 extern char * keydefptr;
3724 extern int keymac;
3725 extern int keymacx;
3726 int x, y, brace = 0;
3727 int pause;
3728 char * p, * b;
3729 char kbuf[K_BUFLEN + 1]; /* Key verb name buffer */
3730 char osendbuf[SEND_BUFLEN +1];
3731 int sendndx = 0;
3732
3733 if (xxout(obuf,obn) < 0) /* Flush buffer */
3734 goto outerr;
3735 debug(F100,"OUTPUT KVERB","",0); /* Send a KVERB */
3736 { /* Have K verb? */
3737 if (!*s) {
3738 break;
3739 }
3740 /*
3741 We assume that the verb name is {braced}, or it extends to the end of the
3742 string, s, or it ends with a space, control character, or backslash.
3743 */
3744 p = kbuf; /* Copy verb name into local buffer */
3745 x = 0;
3746 while ((x++ < K_BUFLEN) && (*s > SP) && (*s != CMDQ)) {
3747 if (brace && *s == '}') {
3748 break;
3749 }
3750 *p++ = *s++;
3751 }
3752 if (*s && !brace) /* If we broke because of \, etc, */
3753 s--; /* back up so we get another look. */
3754 brace = 0;
3755 *p = NUL; /* Terminate. */
3756 p = kbuf; /* Point back to beginning */
3757 debug(F110,"dooutput kverb",p,0);
3758 y = xlookup(kverbs,p,nkverbs,&x); /* Look it up */
3759 debug(F101,"dooutput lookup",0,y);
3760 if (y > -1) {
3761 if (sendndx) {
3762 dooutput(osendbuf,cx);
3763 sendndx = 0;
3764 }
3765 dokverb(VCMD,y);
3766 #ifndef NOSPL
3767 } else { /* Is it a macro? */
3768 y = mxlook(mactab,p,nmac);
3769 if (y > -1) {
3770 cmpush();
3771 keymac = 1; /* Flag for key macro active */
3772 keymacx = y; /* Key macro index */
3773 keydefptr = s; /* Where to resume next time */
3774 debug(F111,"dooutput mxlook",keydefptr,y);
3775 parser(1);
3776 cmpop();
3777 }
3778 #endif /* NOSPL */
3779 }
3780 }
3781 quote = 0;
3782 continue;
3783 } else
3784 #endif /* NOKVERBS */
3785 if (outesc && (x == 'n' || x == 'N')) { /* \n or \N */
3786 if (xxout(obuf,obn) < 0) /* Flush buffer */
3787 goto outerr;
3788 debug(F100,"OUTPUT NUL","",0); /* Send a NUL */
3789 if (local)
3790 ttoc(NUL);
3791 else
3792 conoc(NUL);
3793 quote = 0;
3794 continue;
3795
3796 } else if (outesc && (x == 'b' || x == 'B')) { /* \b or \B */
3797
3798 if (xxout(obuf,obn) < 0) /* Flush buffer first */
3799 goto outerr;
3800 debug(F100,"OUTPUT BREAK","",0);
3801 #ifndef NOLOCAL
3802 ttsndb(); /* Send BREAK signal */
3803 #else
3804 if (local)
3805 ttoc(NUL);
3806 else
3807 conoc(NUL);
3808 #endif /* NOLOCAL */
3809 quote = 0; /* Turn off quote flag */
3810 continue; /* and not the b or B */
3811 #ifdef CK_LBRK
3812 } else if (outesc && (x == 'l' || x == 'L')) { /* \l or \L */
3813 if (xxout(obuf,obn) < 0) /* Flush buffer first */
3814 goto outerr;
3815 debug(F100,"OUTPUT Long BREAK","",0);
3816 #ifndef NOLOCAL
3817 ttsndlb(); /* Send Long BREAK signal */
3818 #else
3819 if (local)
3820 ttoc(NUL);
3821 else
3822 conoc(NUL);
3823 #endif /* NOLOCAL */
3824 quote = 0; /* Turn off quote flag */
3825 continue; /* and not the l or L */
3826 #endif /* CK_LBRK */
3827
3828 } else if (x == CMDQ) { /* Backslash itself */
3829 debug(F100,"OUTPUT CMDQ","",0);
3830 xx = oboc(dopar(CMDQ)); /* Output the backslash. */
3831 if (xx < 0)
3832 goto outerr;
3833 quote = 0;
3834 continue;
3835
3836 } else { /* if \ not followed by special esc */
3837 /* Note: Atari ST compiler won't allow macro call in "if ()" */
3838 xx = oboc(dopar(CMDQ)); /* Output the backslash. */
3839 if (xx < 0)
3840 goto outerr;
3841 quote = 0; /* Turn off quote flag */
3842 }
3843 } else if (x == CMDQ) { /* This is the quote character */
3844 quote = 1; /* Go back and get next character */
3845 continue; /* which is quoted */
3846 }
3847 xx = oboc(dopar((char)x)); /* Output this character */
3848 debug(F111,"dooutput",obuf,obn);
3849 if (xx < 0)
3850 goto outerr;
3851 #ifdef COMMENT
3852 if (seslog && duplex) { /* Log the character if log is on */
3853 logchar((char)x);
3854 }
3855 #endif /* COMMENT */
3856 if (x == '\015') { /* String contains carriage return */
3857 int stuff = -1, stuff2 = -1;
3858 if (tnlm) { /* TERMINAL NEWLINE ON */
3859 stuff = LF; /* Stuff LF */
3860 }
3861 #ifdef TNCODE
3862 /* TELNET NEWLINE ON/OFF/RAW */
3863 if (is_tn) {
3864 switch (TELOPT_ME(TELOPT_BINARY) ? /* NVT or BINARY */
3865 tn_b_nlm :
3866 tn_nlm
3867 ) {
3868 case TNL_CR:
3869 break;
3870 case TNL_CRNUL:
3871 stuff2 = stuff;
3872 stuff = NUL;
3873 break;
3874 case TNL_CRLF:
3875 stuff2 = stuff;
3876 stuff = LF;
3877 break;
3878 }
3879 }
3880 #endif /* TNCODE */
3881 if (stuff > -1) { /* Stuffing another character... */
3882 xx = oboc(dopar((CHAR)stuff));
3883 if (xx < 0)
3884 goto outerr;
3885 #ifdef COMMENT
3886 if (seslog && duplex) { /* Log stuffed char if appropriate */
3887 logchar((char)stuff);
3888 }
3889 #endif /* COMMENT */
3890 }
3891 if (stuff2 > -1) { /* Stuffing another character... */
3892 xx = oboc(dopar((CHAR)stuff2));
3893 if (xx < 0)
3894 goto outerr;
3895 #ifdef COMMENT
3896 if (seslog && duplex) { /* Log stuffed char if appropriate */
3897 logchar((char)stuff2);
3898 }
3899 #endif /* COMMENT */
3900 }
3901 if (xxout(obuf,obn) < 0) /* Flushing is required here! */
3902 goto outerr;
3903 }
3904 }
3905 if (cx == XXLNOUT) {
3906 s = "\015";
3907 cx = 0;
3908 goto outagain;
3909 }
3910 if (quote == 1) /* String ended with backslash */
3911 xx = oboc(dopar(CMDQ));
3912
3913 if (obn > 0) /* OUTPUT done */
3914 if (xxout(obuf,obn) < 0) /* Flush the buffer if necessary. */
3915 goto outerr;
3916 return(1);
3917
3918 outerr: /* OUTPUT command error handler */
3919 if (msgflg) printf("?OUTPUT execution error\n");
3920 return(0);
3921
3922 /* Remove "local" OUTPUT macro defininitions */
3923
3924 #ifdef COMMENT
3925 /* No more macros ... */
3926 #undef oboc
3927 #undef obfls
3928 #endif /* COMMENT */
3929 }
3930 #endif /* NOSPL */
3931
3932 /* Display version herald and initial prompt */
3933
3934 VOID
herald()3935 herald() {
3936 int x = 0, i;
3937 extern int srvcdmsg;
3938 extern char * cdmsgfile[];
3939 char * ssl;
3940 char * krb4;
3941 char * krb5;
3942
3943 #ifndef NOCMDL
3944 extern char * bannerfile;
3945 debug(F110,"herald bannerfile",bannerfile,0);
3946 if (bannerfile) {
3947 concb((char)escape);
3948 if (dotype(bannerfile,1,0,0,NULL,0,NULL,0,0,NULL,0) > 0) {
3949 debug(F111,"herald","srvcdmsg",srvcdmsg);
3950 if (srvcdmsg) {
3951 for (i = 0; i < 8; i++) {
3952 debug(F111,"herald cdmsgfile[i]",cdmsgfile[i],i);
3953 if (zchki(cdmsgfile[i]) > -1) {
3954 printf("\n");
3955 dotype(cdmsgfile[i],
3956 xaskmore,0,0,NULL,0,NULL,0,0,NULL,0);
3957 break;
3958 }
3959 }
3960 }
3961 return;
3962 }
3963 }
3964 #endif /* NOCMDL */
3965
3966 #ifdef COMMENT
3967 /* The following generates bad code in SCO compilers. */
3968 /* Observed in both OSR5 and Unixware 2 -- after executing this */
3969 /* statement when all conditions are false, x has a value of -32. */
3970 if (noherald || quiet || bgset > 0 || (bgset != 0 && backgrd != 0))
3971 x = 1;
3972 #else
3973 x = 0;
3974 if (noherald || quiet)
3975 x = 1;
3976 else if (bgset > 0)
3977 x = 1;
3978 else if (bgset < 0 && backgrd > 0)
3979 x = 1;
3980 #endif /* COMMENT */
3981
3982 ssl = "";
3983 krb4 = "";
3984 krb5 = "";
3985 #ifdef CK_AUTHENTICATION
3986 #ifdef CK_SSL
3987 ssl = "+SSL";
3988 #endif /* CK_SSL */
3989 #ifdef KRB4
3990 krb4 = "+KRB4";
3991 #endif /* KRB4 */
3992 #ifdef KRB5
3993 krb5 = "+KRB5";
3994 #endif /* KRB5 */
3995 #endif /* CK_AUTHENTICATION */
3996
3997 if (x == 0) {
3998 #ifdef datageneral
3999 printf("%s, for%s\n",versio,ckxsys);
4000 #else
4001 #ifdef OSK
4002 printf("%s, for%s\n",versio,ckxsys);
4003 #else
4004 #ifdef CK_64BIT
4005 printf("%s, for%s%s%s%s (64-bit)\n\r",versio,ckxsys,ssl,krb4,krb5);
4006 #else
4007 printf("%s, for%s%s%s%s\n\r",versio,ckxsys,ssl,krb4,krb5);
4008 #endif/* CK_64BIT */
4009 #endif /* OSK */
4010 #endif /* datageneral */
4011 printf(" Copyright (C) 1985, %s,\n", ck_cryear);
4012 printf(" Trustees of Columbia University in the City of New York.\n");
4013 #ifdef COMMENT
4014 #ifdef OS2
4015 shoreg();
4016 #endif /* OS2 */
4017 #endif /* COMMENT */
4018
4019 if (!quiet && !backgrd) {
4020 #ifdef COMMENT
4021 /* "Default file-transfer mode is AUTOMATIC" is useless information... */
4022 char * s;
4023 extern int xfermode;
4024 #ifdef VMS
4025 s = "AUTOMATIC";
4026 #else
4027 if (xfermode == XMODE_A) {
4028 s = "AUTOMATIC";
4029 } else {
4030 s = gfmode(binary,1);
4031 }
4032 if (!s) s = "";
4033 #endif /* VMS */
4034 if (*s)
4035 printf("Default file-transfer mode is %s\n", s);
4036 #endif /* COMMENT */
4037
4038 debug(F111,"herald","srvcdmsg",srvcdmsg);
4039 if (srvcdmsg) {
4040 for (i = 0; i < 8; i++) {
4041 debug(F111,"herald cdmsgfile[i]",cdmsgfile[i],i);
4042 if (zchki(cdmsgfile[i]) > -1) {
4043 printf("\n");
4044 dotype(cdmsgfile[i],
4045 xaskmore,0,0,NULL,0,NULL,0,0,NULL,0);
4046 break;
4047 }
4048 }
4049 }
4050 printf("Type ? or HELP for help.\n");
4051 }
4052 }
4053 }
4054
4055 /* G F M O D E -- Get File (transfer) Mode */
4056
4057 char *
gfmode(binary,upcase)4058 gfmode(binary,upcase) int binary, upcase; {
4059 char * s;
4060 switch (binary) {
4061 case XYFT_T: s = upcase ? "TEXT" : "text"; break;
4062 #ifdef VMS
4063 case XYFT_B: s = upcase ? "BINARY FIXED" : "binary fixed"; break;
4064 case XYFT_I: s = upcase ? "IMAGE" : "image"; break;
4065 case XYFT_L: s = upcase ? "LABELED" : "labeled"; break;
4066 case XYFT_U: s = upcase ? "BINARY UNDEF" : "binary undef"; break;
4067 #else
4068 #ifdef MAC
4069 case XYFT_B: s = upcase ? "BINARY" : "binary"; break;
4070 case XYFT_M: s = upcase ? "MACBINARY" : "macbinary"; break;
4071 #else
4072 case XYFT_B: s = upcase ? "BINARY" : "binary"; break;
4073 #ifdef CK_LABELED
4074 case XYFT_L: s = upcase ? "LABELED" : "labeled"; break;
4075 #endif /* CK_LABELED */
4076 #endif /* MAC */
4077 #endif /* VMS */
4078 case XYFT_X: s = upcase ? "TENEX" : "tenex"; break;
4079 default: s = "";
4080 }
4081 return(s);
4082 }
4083
4084 #ifndef NOSPL
4085 static int
isaa(s)4086 isaa(s) char * s; { /* Is associative array */
4087 char c;
4088 int x;
4089 if (!s) s = "";
4090 if (!*s) return(0);
4091 s++;
4092 while ((c = *s++)) {
4093 if (c == '<') {
4094 x = strlen(s);
4095 return ((*(s+x-1) == '>') ? 1 : 0);
4096 }
4097 }
4098 return(0);
4099 }
4100
4101 /* M L O O K -- Lookup the macro name in the macro table */
4102
4103 /*
4104 Call this way: v = mlook(table,word,n);
4105
4106 table - a 'struct mtab' table.
4107 word - the target string to look up in the table.
4108 n - the number of elements in the table.
4109
4110 The keyword table must be arranged in ascending alphabetical order, and
4111 all letters must be lowercase.
4112
4113 Returns the table index, 0 or greater, if the name was found, or:
4114
4115 -3 if nothing to look up (target was null),
4116 -2 if ambiguous,
4117 -1 if not found.
4118
4119 A match is successful if the target matches a keyword exactly, or if
4120 the target is a prefix of exactly one keyword. It is ambiguous if the
4121 target matches two or more keywords from the table.
4122 */
4123 int
mlook(table,cmd,n)4124 mlook(table,cmd,n) struct mtab table[]; char *cmd; int n; {
4125 register int i;
4126 int v, w, cmdlen = 0;
4127 char c = 0, c1, * s;
4128 if (!cmd) cmd = "";
4129
4130 for (s = cmd; *s; s++) cmdlen++; /* (instead of strlen) */
4131 debug(F111,"MLOOK",cmd,cmdlen);
4132
4133 c1 = *cmd;
4134 if (isupper(c1))
4135 c1 = tolower(c1);
4136 if (cmdlen < 1)
4137 return(-3);
4138
4139 /* Not null, look it up */
4140
4141 if (n < 12) { /* Not worth it for small tables */
4142 i = 0;
4143 } else { /* Binary search for where to start */
4144 int lo = 0;
4145 int hi = n;
4146 int count = 0;
4147 while (lo+2 < hi && ++count < 12) {
4148 i = lo + ((hi - lo) / 2);
4149 c = *(table[i].kwd);
4150 if (isupper(c)) c = tolower(c);
4151 if (c < c1) {
4152 lo = i;
4153 } else {
4154 hi = i;
4155 }
4156 }
4157 i = (c < c1) ? lo+1 : lo;
4158 }
4159 for ( ; i < n-1; i++) {
4160 s = table[i].kwd;
4161 if (!s) s = "";
4162 if (!*s) continue; /* Empty table entry */
4163 c = *s;
4164 if (isupper(c)) c = tolower(c);
4165 if (c1 != c) continue; /* First char doesn't match */
4166 if (!ckstrcmp(s,cmd,-1,0)) /* Have exact match? */
4167 return(i);
4168 v = !ckstrcmp(s,cmd,cmdlen,0);
4169 w = ckstrcmp(table[i+1].kwd,cmd,cmdlen,0);
4170 if (v && w) /* Have abbreviated match? */
4171 return(i);
4172 if (v) /* Ambiguous? */
4173 return(-2);
4174 if (w > 0) /* Past our alphabetic area? */
4175 return(-1);
4176 }
4177
4178 /* Last (or only) element */
4179
4180 if (!ckstrcmp(table[n-1].kwd,cmd,cmdlen,0))
4181 return(n-1);
4182
4183 return(-1);
4184 }
4185
4186 /* mxlook is like mlook, but an exact full-length match is required */
4187
4188 int
mxlook(table,cmd,n)4189 mxlook(table,cmd,n) char *cmd; struct mtab table[]; int n; {
4190 register int i;
4191 int w, cmdlen = 0, one = 0;
4192 register char c = 0, c1, * s;
4193
4194 if (!cmd) cmd = ""; /* Check args */
4195
4196 for (s = cmd; *s; s++) cmdlen++; /* (instead of strlen) */
4197 debug(F111,"MXLOOK",cmd,cmdlen);
4198
4199 c1 = *cmd; /* First char of string to look up */
4200 if (isupper(c1))
4201 c1 = tolower(c1);
4202 if (!*(cmd+1)) /* Special handling for 1-char names */
4203 one = 1;
4204
4205 if (cmdlen < 1) /* Nothing to look up */
4206 return(-3);
4207
4208 if (n < 12) { /* Not worth it for small tables */
4209 i = 0;
4210 } else { /* Binary search for where to start */
4211 int lo = 0;
4212 int hi = n;
4213 int count = 0;
4214 while (lo+2 < hi && ++count < 12) {
4215 i = lo + ((hi - lo) / 2);
4216 c = *(table[i].kwd);
4217 if (isupper(c)) c = tolower(c);
4218 if (c < c1) {
4219 lo = i;
4220 } else {
4221 hi = i;
4222 }
4223 }
4224 i = (c < c1) ? lo+1 : lo;
4225 }
4226 for ( ; i < n; i++) { /* Look thru table */
4227 s = table[i].kwd; /* This entry */
4228 if (!s) s = "";
4229 if (!*s) continue; /* Empty table entry */
4230 c = *s;
4231 if (isupper(c)) c = tolower(c);
4232 if (c1 != c) continue; /* First char doesn't match */
4233 if (one) { /* Name is one char long */
4234 if (!*(s+1))
4235 return(i); /* So is table entry */
4236 }
4237 #ifdef COMMENT
4238 if (((int)strlen(s) == cmdlen) &&
4239 (!ckstrcmp(s,cmd,cmdlen,0))) return(i);
4240 #else
4241 w = ckstrcmp(s,cmd,-1,0);
4242 if (!w) {
4243 debug(F111,"MXLOOK",mactab[i].mval,i);
4244 return(i);
4245 }
4246 if (w > 0) return(-1);
4247 #endif /* COMMENT */
4248 }
4249 return(-1);
4250 }
4251
4252 /* mxxlook is like mxlook, but case-sensitive */
4253
4254 int
mxxlook(table,cmd,n)4255 mxxlook(table,cmd,n) char *cmd; struct mtab table[]; int n; {
4256 int i, cmdlen;
4257 if (!cmd) cmd = "";
4258 if (((cmdlen = strlen(cmd)) < 1) || (n < 1)) return(-3);
4259 /* debug(F111,"mxxlook target",cmd,n); */
4260 for (i = 0; i < n; i++) {
4261 if (((int)strlen(table[i].kwd) == cmdlen) &&
4262 (!strncmp(table[i].kwd,cmd,cmdlen)))
4263 return(i);
4264 }
4265 return(-1);
4266 }
4267
4268 static int
traceval(nam,val)4269 traceval(nam, val) char * nam, * val; { /* For TRACE command */
4270 if (val)
4271 printf(">>> %s: \"%s\"\n", nam, val);
4272 else
4273 printf(">>> %s: (undef)\n", nam);
4274 return(0);
4275 }
4276
4277 #ifdef USE_VARLEN /* Not used */
4278
4279 /* V A R L E N -- Get length of variable's value.
4280
4281 Given a variable name, return the length of its definition or 0 if the
4282 variable is not defined. If it is defined, set argument s to point to its
4283 definition. Otherwise set s to NULL.
4284 */
4285 int
varlen(nam,s)4286 varlen(nam,s) char *nam; char **s; { /* Length of value of variable */
4287 int x, z;
4288 char *p = NULL, c;
4289
4290 *s = NULL;
4291 if (!nam) return(0); /* Watch out for null pointer */
4292 if (*nam == CMDQ) {
4293 nam++;
4294 if (*nam == '%') { /* If it's a variable name */
4295 if (!(c = *(nam+1))) return(0); /* Get letter or digit */
4296 p = (char *)0; /* Initialize value pointer */
4297 if (maclvl > -1 && c >= '0' && c <= '9') { /* Digit? */
4298 p = m_arg[maclvl][c - '0']; /* Pointer from macro-arg table */
4299 } else { /* It's a global variable */
4300 if (c < 33 || c > GVARS) return(0);
4301 p = g_var[c]; /* Get pointer from global-var table */
4302 }
4303 } else if (*nam == '&') { /* An array reference? */
4304 char **q;
4305 if (arraynam(nam,&x,&z) < 0) /* If syntax is bad */
4306 return(-1); /* return -1. */
4307 x -= ARRAYBASE; /* Convert name to number. */
4308 if ((q = a_ptr[x]) == NULL) /* If array not declared, */
4309 return(0); /* return -2. */
4310 if (z > a_dim[x]) /* If subscript out of range, */
4311 return(0); /* return -3. */
4312 p = q[z];
4313 }
4314 } else { /* Macro */
4315 z = isaa(nam);
4316 x = z ? mxxlook(mactab,nam,nmac) : mlook(mactab,nam,nmac);
4317 if (x < 0)
4318 return(0);
4319 p = mactab[x].mval;
4320 }
4321 if (p)
4322 *s = p;
4323 else
4324 p = "";
4325 return((int)strlen(p));
4326 }
4327 #endif /* USE_VARLEN */
4328
4329 /*
4330 This routine is for the benefit of those compilers that can't handle
4331 long string constants or continued lines within them. Long predefined
4332 macros like FOR, WHILE, and XIF have their contents broken up into
4333 arrays of string pointers. This routine concatenates them back into a
4334 single string again, and then calls the real addmac() routine to enter
4335 the definition into the macro table.
4336 */
4337 int
addmmac(nam,s)4338 addmmac(nam,s) char *nam, *s[]; { /* Add a multiline macro definition */
4339 int i, x, y; char *p;
4340 x = 0; /* Length counter */
4341 for (i = 0; (y = (int)strlen(s[i])) > 0; i++) { /* Add up total length */
4342 debug(F111,"addmmac line",s[i],y);
4343 x += y;
4344 }
4345 debug(F101,"addmmac lines","",i);
4346 debug(F101,"addmmac loop exit","",y);
4347 debug(F111,"addmmac length",nam,x);
4348 if (x < 0) return(-1);
4349
4350 p = malloc(x+1); /* Allocate space for all of it. */
4351 if (!p) {
4352 printf("?addmmac malloc error: %s\n",nam);
4353 debug(F110,"addmmac malloc error",nam,0);
4354 return(-1);
4355 }
4356 *p = '\0'; /* Start off with null string. */
4357 for (i = 0; *s[i]; i++) /* Concatenate them all together. */
4358 ckstrncat(p,s[i],x+1);
4359 y = (int)strlen(p); /* Final precaution. */
4360 debug(F111,"addmmac constructed string",p,y);
4361 if (y == x) {
4362 y = addmac(nam,p); /* Add result to the macro table. */
4363 } else {
4364 debug(F100,"addmmac length mismatch","",0);
4365 printf("\n!addmmac internal error!\n");
4366 y = -1;
4367 }
4368 free(p); /* Free the temporary copy. */
4369 return(y);
4370 }
4371
4372 static char evalmacrobuf[TMPBUFSIZ];
4373 VOID
evalmacroarg(p)4374 evalmacroarg(p) char **p; {
4375 char * s = evalmacrobuf;
4376 int t = TMPBUFSIZ;
4377 (VOID) zzstring(*p,&s,&t);
4378 *p = evalmacrobuf;
4379 }
4380
4381 /* Here is the real addmac routine. */
4382
4383 /* Returns -1 on failure, macro table index >= 0 on success. */
4384
4385 int mtchanged = 0;
4386
4387 int
addmac(nam,def)4388 addmac(nam,def) char *nam, *def; { /* Add a macro to the macro table */
4389 int i, x, y, z, namlen, deflen, flag = 0;
4390 int replacing = 0, deleting = 0;
4391 char * p = NULL, c, *s;
4392 extern int tra_asg; int tra_tmp;
4393
4394 if (!nam) return(-1);
4395 if (!*nam) return(-1);
4396
4397 #ifdef IKSD
4398 if (inserver &&
4399 #ifdef IKSDCONF
4400 iksdcf
4401 #else /* IKSDCONF */
4402 1
4403 #endif /* IKSDCONF */
4404 ) {
4405 if (!ckstrcmp("on_exit",nam,-1,0) ||
4406 !ckstrcmp("on_logout",nam,-1,0))
4407 return(-1);
4408 }
4409 #endif /* IKSD */
4410
4411 namlen = 0;
4412 p = nam;
4413 while (*p++) namlen++; /* (instead of strlen) */
4414
4415 tra_tmp = tra_asg; /* trace... */
4416 debug(F111,"addmac nam",nam,namlen);
4417 if (!def) { /* Watch out for null pointer */
4418 deflen = 0;
4419 debug(F111,"addmac def","(null pointer)",deflen);
4420 } else {
4421 deflen = 0;
4422 p = def;
4423 while (*p++) deflen++; /* (instead of strlen) */
4424 debug(F010,"addmac def",def,0);
4425 }
4426 #ifdef USE_VARLEN /* NOT USED */
4427 /* This does not boost performance much because varlen() does a lot */
4428 x = varlen(nam,&s);
4429 if (x > 0 && x >= deflen) {
4430 strcpy(s,def); /* NOT USED */
4431 flag = 1;
4432 p = s;
4433 }
4434 #endif /* USE_VARLEN */
4435
4436 if (*nam == CMDQ) nam++; /* Backslash quote? */
4437 if (*nam == '%') { /* Yes, if it's a variable name, */
4438 if (!(c = *(nam + 1))) return(-1); /* Variable name letter or digit */
4439 if (!flag) {
4440 tra_asg = 0;
4441 delmac(nam,0); /* Delete any old value. */
4442 tra_asg = tra_tmp;
4443 }
4444 if (deflen < 1) { /* Null definition */
4445 p = NULL; /* Better not malloc or strcpy! */
4446 } else if (!flag) { /* A substantial definition */
4447 p = malloc(deflen + 1); /* Allocate space for it */
4448 if (!p) {
4449 printf("?addmac malloc error 2\n");
4450 return(-1);
4451 } else strcpy(p,def); /* Copy def into new space (SAFE) */
4452 }
4453
4454 /* Now p points to the definition, or is a null pointer */
4455
4456 if (c >= '0' && c <= '9') { /* \%0-9 variable */
4457 if (maclvl < 0) { /* Are we calling or in a macro? */
4458 g_var[c] = p; /* No, it's top level one */
4459 makestr(&(toparg[c - '0']),p); /* Take care \&_[] too */
4460 } else { /* Yes, it's a macro argument */
4461 m_arg[maclvl][c - '0'] = p; /* Assign the value */
4462 makestr(&(m_xarg[maclvl][c - '0']),p); /* And a copy here */
4463 }
4464 } else { /* It's a \%a-z variable */
4465 if (c < 33 || (unsigned int)c > GVARS) return(-1);
4466 if (isupper(c)) c = (char) tolower(c);
4467 g_var[c] = p; /* Put pointer in global-var table */
4468 }
4469 if (tra_asg) traceval(nam,p);
4470 return(0);
4471 } else if (*nam == '&') { /* An array reference? */
4472 char **q = NULL;
4473 int rc = 0;
4474 if ((y = arraynam(nam,&x,&z)) < 0) /* If syntax is bad */
4475 return(-1); /* return -1. */
4476 if (chkarray(x,z) < 0) /* If array not declared or */
4477 rc = -2; /* subscript out of range, ret -2 */
4478 if (!flag) {
4479 tra_asg = 0;
4480 delmac(nam,0); /* Delete any old value. */
4481 tra_asg = tra_tmp;
4482 }
4483 x -= ARRAYBASE; /* Convert name letter to index. */
4484 if (x > 'z' - ARRAYBASE + 1)
4485 rc = -1;
4486 if (rc != -1) {
4487 if ((q = a_ptr[x]) == NULL) /* If array not declared, */
4488 return(-3); /* return -3. */
4489 }
4490 if (rc < 0)
4491 return(rc);
4492 if (!flag) {
4493 if (deflen > 0) {
4494 if ((p = malloc(deflen+1)) == NULL) { /* Allocate space */
4495 printf("addmac macro error 7: %s\n",nam);
4496 return(-4); /* for new def, return -4 on fail. */
4497 }
4498 strcpy(p,def); /* Copy def into new space (SAFE). */
4499 } else p = NULL;
4500 }
4501 q[z] = p; /* Store pointer to it. */
4502 if (x == 0) { /* Arg vector array */
4503 if (z >= 0 && z <= 9) { /* Copy values to corresponding */
4504 if (maclvl < 0) { /* \%1..9 variables. */
4505 makestr(&(toparg[z]),p);
4506 } else {
4507 makestr(&(m_arg[maclvl][z]),p);
4508 }
4509 }
4510 }
4511 if (tra_asg) traceval(nam,p);
4512 return(0); /* Done. */
4513 }
4514 /* Not a macro argument or a variable, so it's a macro definition */
4515
4516 #ifdef USE_VARLEN
4517 if (flag) {
4518 if (tra_asg) traceval(nam,p);
4519 return(0);
4520 }
4521 #endif /* USE_VARLEN */
4522 x = isaa(nam) ? /* If it's an associative array */
4523 mxxlook(mactab,nam,nmac) : /* look it up this way */
4524 mxlook(mactab,nam,nmac); /* otherwise this way. */
4525 if (x > -1) { /* If found... */
4526 if (deflen > 0) /* and a new definition was given */
4527 replacing = 1; /* we're replacing */
4528 else /* otherwise */
4529 deleting = 1; /* we're deleting */
4530 }
4531 if (deleting) { /* Deleting... */
4532 if (delmac(nam,0) < 0)
4533 return(-1);
4534 mtchanged++;
4535 if (tra_asg) traceval(nam,p);
4536 return(0);
4537 } else if (deflen < 1) /* New macro with no definition */
4538 return(0); /* Nothing to do. */
4539
4540 if (replacing) { /* Replacing an existing macro */
4541 if (mactab[x].mval) { /* If it currently has a definition, */
4542 free(mactab[x].mval); /* free it. */
4543 mactab[x].mval = NULL;
4544 }
4545 mtchanged++;
4546 y = x; /* Replacement index. */
4547
4548 } else { /* Adding a new macro... */
4549 char c1, c2; /* Use fast lookup to find the */
4550 c1 = *nam; /* alphabetical slot. */
4551 if (isupper(c1)) c1 = (char) tolower(c1);
4552
4553 if (nmac < 5) { /* Not worth it for small tables */
4554 y = 0;
4555 } else { /* First binary search to find */
4556 int lo = 0; /* where to start */
4557 int hi = nmac;
4558 int count = 0;
4559 char c = 0;
4560 while (lo+2 < hi && ++count < 12) {
4561 y = lo + ((hi - lo) / 2);
4562 c = *(mactab[y].kwd);
4563 if (isupper(c)) c = (char) tolower(c);
4564 if (c < c1) {
4565 lo = y;
4566 } else {
4567 hi = y;
4568 }
4569 }
4570 y = (c < c1) ? lo+1 : lo;
4571 }
4572
4573 /* Now search linearly from starting location */
4574 for ( ; y < MAC_MAX && mactab[y].kwd != NULL; y++) {
4575 c2 = *(mactab[y].kwd);
4576 if (isupper(c2)) c2 = (char) tolower(c2);
4577 if (c1 > c2)
4578 continue;
4579 if (c1 < c2)
4580 break;
4581 if (ckstrcmp(nam,mactab[y].kwd,-1,0) <= 0)
4582 break;
4583 }
4584 if (y == MAC_MAX) { /* Macro table is full. */
4585 debug(F101,"addmac table overflow","",y);
4586 printf("?Macro table overflow\n");
4587 return(-1);
4588 }
4589 if (mactab[y].kwd != NULL) { /* Must insert */
4590 for (i = nmac; i > y; i--) { /* Move the rest down one slot */
4591 mactab[i].kwd = mactab[i-1].kwd;
4592 mactab[i].mval = mactab[i-1].mval;
4593 mactab[i].flgs = mactab[i-1].flgs;
4594 }
4595 }
4596 mtchanged++;
4597 p = malloc(namlen + 1); /* Allocate space for name */
4598 if (!p) {
4599 printf("?Addmac: Out of memory - \"%s\"\n",nam);
4600 return(-1);
4601 }
4602 strcpy(p,nam); /* Copy name into new space (SAFE) */
4603 mactab[y].kwd = p; /* Add pointer to table */
4604 }
4605 if (deflen > 0) { /* If we have a definition */
4606 p = malloc(deflen + 1); /* Get space */
4607 if (p == NULL) {
4608 printf("?Space exhausted - \"%s\"\n", nam);
4609 if (mactab[y].kwd) {
4610 free(mactab[y].kwd);
4611 mactab[y].kwd = NULL;
4612 }
4613 return(-1);
4614 } else {
4615 strcpy(p,def); /* Copy the definition (SAFE) */
4616 }
4617 } else { /* definition is empty */
4618 p = NULL;
4619 }
4620 mactab[y].mval = p; /* Macro points to definition */
4621 mactab[y].flgs = 0; /* No flags */
4622 if (!replacing) /* If new macro */
4623 nmac++; /* count it */
4624 if (tra_asg) traceval(nam,p);
4625 return(y);
4626 }
4627
4628 int
xdelmac(x)4629 xdelmac(x) int x; { /* Delete a macro given its index */
4630 int i;
4631 extern int tra_asg;
4632 if (x < 0) return(x);
4633 if (tra_asg)
4634 traceval(mactab[x].kwd,NULL);
4635
4636 if (mactab[x].kwd) { /* Free the storage for the name */
4637 free(mactab[x].kwd);
4638 mactab[x].kwd = NULL;
4639 }
4640 if (mactab[x].mval) { /* and for the definition */
4641 free(mactab[x].mval);
4642 mactab[x].mval = NULL;
4643 }
4644 for (i = x; i < nmac; i++) { /* Now move up the others. */
4645 mactab[i].kwd = mactab[i+1].kwd;
4646 mactab[i].mval = mactab[i+1].mval;
4647 mactab[i].flgs = mactab[i+1].flgs;
4648 }
4649 nmac--; /* One less macro */
4650
4651 mactab[nmac].kwd = NULL; /* Delete last item from table */
4652 mactab[nmac].mval = NULL;
4653 mactab[nmac].flgs = 0;
4654 mtchanged++;
4655 return(0);
4656 }
4657
4658 int
delmac(nam,exact)4659 delmac(nam,exact) char *nam; int exact; { /* Delete the named macro */
4660 int x, z;
4661 char *p, c;
4662 extern int tra_asg;
4663
4664 if (!nam) return(0); /* Watch out for null pointer */
4665 debug(F110,"delmac nam",nam,0);
4666 #ifdef IKSD
4667 if ( inserver &&
4668 #ifdef IKSDCONF
4669 iksdcf
4670 #else /* IKSDCONF */
4671 1
4672 #endif /* IKSDCONF */
4673 ) {
4674 if (!ckstrcmp("on_exit",nam,-1,0) ||
4675 !ckstrcmp("on_logout",nam,-1,0))
4676 return(-1);
4677 }
4678 #endif /* IKSD */
4679
4680 if (*nam == CMDQ) nam++;
4681 if (*nam == '%') { /* If it's a variable name */
4682 if (!(c = *(nam+1))) return(0); /* Get variable name letter or digit */
4683 p = (char *)0; /* Initialize value pointer */
4684 if (maclvl < 0 && c >= '0' && c <= '9') { /* Top-level digit? */
4685 p = toparg[c - '0'];
4686 if (p) if (p != g_var[c]) {
4687 free(p);
4688 toparg[c - '0'] = NULL;
4689 }
4690 p = g_var[c];
4691 g_var[c] = NULL; /* Zero the table entry */
4692 } else if (maclvl > -1 && c >= '0' && c <= '9') { /* Digit? */
4693 p = m_xarg[maclvl][c - '0'];
4694 if (p) if (p != g_var[c]) {
4695 free(p);
4696 m_xarg[maclvl][c - '0'] = NULL;
4697 }
4698 p = m_arg[maclvl][c - '0']; /* Get pointer from macro-arg table */
4699 m_arg[maclvl][c - '0'] = NULL; /* Zero the table pointer */
4700 } else { /* It's a global variable */
4701 if (c < 33 || (unsigned int)c > GVARS) return(0);
4702 p = g_var[c]; /* Get pointer from global-var table */
4703 g_var[c] = NULL; /* Zero the table entry */
4704 }
4705 if (p) {
4706 debug(F010,"delmac def",p,0);
4707 free(p); /* Free the storage */
4708 p = NULL;
4709 } else debug(F110,"delmac def","(null pointer)",0);
4710 if (tra_asg) traceval(nam,NULL);
4711 return(0);
4712 }
4713 if (*nam == '&') { /* An array reference? */
4714 char **q;
4715 if (arraynam(nam,&x,&z) < 0) /* If syntax is bad */
4716 return(-1); /* return -1. */
4717 x -= ARRAYBASE; /* Convert name to number. */
4718 if ((q = a_ptr[x]) == NULL) /* If array not declared, */
4719 return(-2); /* return -2. */
4720 if (z > a_dim[x]) /* If subscript out of range, */
4721 return(-3); /* return -3. */
4722 if (q[z]) { /* If there is an old value, */
4723 debug(F010,"delmac def",q[z],0);
4724 if (x != 0) /* Macro arg vector is just a copy */
4725 free(q[z]); /* Others are real so free them */
4726 q[z] = NULL;
4727 if (x == 0) { /* Arg vector array */
4728 if (z >= 0 && z <= 9) { /* Copy values to corresponding */
4729 if (maclvl < 0) { /* \%1..9 variables. */
4730 makestr(&(toparg[z]),NULL);
4731 } else {
4732 makestr(&(m_arg[maclvl][z]),NULL);
4733 }
4734 }
4735 }
4736 if (tra_asg) traceval(nam,NULL);
4737 } else debug(F010,"delmac def","(null pointer)",0);
4738 }
4739
4740 /* Not a variable or an array, so it must be a macro. */
4741
4742 z = isaa(nam);
4743 debug(F111,"delmac isaa",nam,z);
4744 debug(F111,"delmac exact",nam,exact);
4745 x = z ? mxxlook(mactab,nam,nmac) :
4746 exact ? mxlook(mactab,nam,nmac) :
4747 mlook(mactab,nam,nmac);
4748 if (x < 0) {
4749 debug(F111,"delmac mlook",nam,x);
4750 return(x);
4751 }
4752 return(xdelmac(x));
4753 }
4754
4755 VOID
initmac()4756 initmac() { /* Init macro & variable tables */
4757 int i, j, x;
4758
4759 nmac = 0; /* No macros */
4760 for (i = 0; i < MAC_MAX; i++) { /* Initialize the macro table */
4761 mactab[i].kwd = NULL;
4762 mactab[i].mval = NULL;
4763 mactab[i].flgs = 0;
4764 }
4765 mtchanged++;
4766 x = (MAXARGLIST + 1) * sizeof(char **);
4767 for (i = 0; i < MACLEVEL; i++) { /* Init the macro argument tables */
4768 m_xarg[i] = (char **) malloc(x);
4769 mrval[i] = NULL; /* Macro return value */
4770 /* Pointer to entire argument vector, level i, for \&_[] array */
4771 for (j = 0; j <= MAXARGLIST; j++) { /* Macro argument list */
4772 if (j < 10) /* For the \%0..\%9 variables */
4773 m_arg[i][j] = NULL; /* Pointer to arg j, level i. */
4774 if (m_xarg[i]) /* For \&_[] - all args. */
4775 m_xarg[i][j] = NULL;
4776 }
4777 }
4778 for (i = 0; i < GVARS; i++) { /* And the global variables table */
4779 g_var[i] = NULL;
4780 }
4781 /* And the table of arrays */
4782 for (i = 0; i < (int) 'z' - ARRAYBASE + 1; i++) {
4783 a_ptr[i] = (char **) NULL; /* Null pointer for each */
4784 a_dim[i] = 0; /* and a dimension of zero */
4785 a_link[i] = -1;
4786 for (j = 0; j < CMDSTKL; j++) {
4787 aa_ptr[j][i] = (char **) NULL;
4788 aa_dim[j][i] = 0;
4789 }
4790 }
4791 }
4792
4793 int
popclvl()4794 popclvl() { /* Pop command level, return cmdlvl */
4795 extern int tra_cmd;
4796 struct localvar * v;
4797 int i, topcmd;
4798 debug(F101,"popclvl cmdlvl","",cmdlvl);
4799 if (cmdlvl > 0) {
4800 if ((v = localhead[cmdlvl])) { /* Did we save any variables? */
4801 while (v) { /* Yes */
4802 if (v->lv_value) /* Copy old ones back */
4803 addmac(v->lv_name,v->lv_value);
4804 else
4805 delmac(v->lv_name,1);
4806 v = v->lv_next;
4807 }
4808 freelocal(cmdlvl); /* Free local storage */
4809 }
4810 /* Automatic arrays do not use the localhead list */
4811
4812 for (i = 0; i < 28; i++) { /* Free any local arrays */
4813 if (aa_ptr[cmdlvl][i]) { /* Does this one exist? */
4814 dclarray((char)(i+ARRAYBASE),-1); /* Destroy global one */
4815 a_ptr[i] = aa_ptr[cmdlvl][i];
4816 a_dim[i] = aa_dim[cmdlvl][i];
4817 aa_ptr[cmdlvl][i] = (char **)NULL;
4818 aa_dim[cmdlvl][i] = 0;
4819 } else if (aa_dim[cmdlvl][i] == -23) { /* Secret code */
4820 /*
4821 A local array declared at this level when there was no
4822 array of the same name at any higher level. See comment
4823 in pusharray().
4824 */
4825 dclarray((char)(i+ARRAYBASE),-1);
4826 a_ptr[i] = (char **)NULL; /* Delete top-level array */
4827 a_dim[i] = 0; /* created by pusharray - Feb 2016 */
4828 aa_ptr[cmdlvl][i] = (char **)NULL;
4829 aa_dim[cmdlvl][i] = 0;
4830 }
4831 /* Otherwise do nothing - it is a local array that was declared */
4832 /* at a level above this one so leave it alone. */
4833 }
4834 }
4835 if (cmdlvl < 1) { /* If we're already at top level */
4836 cmdlvl = 0; /* just make sure all the */
4837 tlevel = -1; /* stack pointers are set right */
4838 maclvl = -1; /* and return */
4839 } else if (cmdstk[cmdlvl].src == CMD_TF) { /* Reading from TAKE file? */
4840 debug(F101,"popclvl tlevel","",tlevel);
4841 if (tlevel > -1) { /* Yes, */
4842 fclose(tfile[tlevel]); /* close it */
4843
4844 if (tra_cmd)
4845 printf("[%d] -F: \"%s\"\n",cmdlvl,tfnam[tlevel]);
4846 debug(F111,"CMD -F",tfnam[tlevel],cmdlvl);
4847 if (tfnam[tlevel]) { /* free storage for name */
4848 free(tfnam[tlevel]);
4849 tfnam[tlevel] = NULL;
4850 }
4851 tlevel--; /* and pop take level */
4852 cmdlvl--; /* and command level */
4853 quiet = xquiet[cmdlvl];
4854 vareval = xvarev[cmdlvl];
4855 } else
4856 tlevel = -1;
4857 } else if (cmdstk[cmdlvl].src == CMD_MD) { /* In a macro? */
4858 topcmd = lastcmd[maclvl];
4859 debug(F101,"popclvl maclvl","",maclvl);
4860 if (maclvl > -1) { /* Yes, */
4861 #ifdef COMMENT
4862 int i;
4863 char **q;
4864 #endif /* COMMENT */
4865 macp[maclvl] = ""; /* set macro pointer to null string */
4866 *cmdbuf = '\0'; /* clear the command buffer */
4867
4868 if ((maclvl > 0) && /* 2 May 1999 */
4869 (m_arg[maclvl-1][0]) &&
4870 (!strncmp(m_arg[maclvl-1][0],"_xif",4) ||
4871 !strncmp(m_arg[maclvl-1][0],"_for",4) ||
4872 !strncmp(m_arg[maclvl-1][0],"_swi",4) ||
4873 !strncmp(m_arg[maclvl-1][0],"_whi",4)) &&
4874 mrval[maclvl+1]) {
4875 makestr(&(mrval[maclvl-1]),mrval[maclvl+1]);
4876 }
4877 if (maclvl+1 < MACLEVEL) {
4878 if (mrval[maclvl+1]) { /* Free any deeper return values. */
4879 free(mrval[maclvl+1]);
4880 mrval[maclvl+1] = NULL;
4881 }
4882 }
4883 if (tra_cmd)
4884 printf("[%d] -M: \"%s\"\n",cmdlvl,m_arg[cmdstk[cmdlvl].lvl][0]);
4885 debug(F111,"CMD -M",m_arg[cmdstk[cmdlvl].lvl][0],cmdlvl);
4886
4887 maclvl--; /* Pop macro level */
4888 cmdlvl--; /* and command level */
4889 debug(F101,"popclvl mac new maclvl","",maclvl);
4890 debug(F010,"popclvl mac mrval[maclvl+1]",mrval[maclvl+2],0);
4891
4892 quiet = xquiet[cmdlvl];
4893 vareval = xvarev[cmdlvl];
4894 if (maclvl > -1) {
4895 a_ptr[0] = m_xarg[maclvl];
4896 a_dim[0] = n_xarg[maclvl] - 1;
4897 debug(F111,"a_dim[0]","B",a_dim[0]);
4898 } else {
4899 a_ptr[0] = topxarg;
4900 a_dim[0] = topargc - 1;
4901 debug(F111,"a_dim[0]","C",a_dim[0]);
4902 }
4903 } else {
4904 maclvl = -1;
4905 }
4906 #ifndef NOSEXP
4907 debug(F101,"popclvl topcmd","",topcmd);
4908 if (topcmd == XXSEXP) {
4909 extern char * sexpval;
4910 makestr(&(mrval[maclvl+1]),sexpval);
4911 }
4912 #endif /* NOSEXP */
4913 } else {
4914 cmdlvl--;
4915 }
4916 debug(F101,"popclvl cmdlvl","",cmdlvl);
4917 if (prstring[cmdlvl]) {
4918 cmsetp(prstring[cmdlvl]);
4919 makestr(&(prstring[cmdlvl]),NULL);
4920 }
4921 #ifndef MAC
4922 if (cmdlvl < 1 || xcmdsrc == CMD_KB) { /* If at prompt */
4923 setint();
4924 concb((char)escape); /* Go into cbreak mode */
4925 }
4926 #endif /* MAC */
4927 xcmdsrc = cmdstk[cmdlvl].src;
4928 debug(F101,"popclvl xcmdsrc","",xcmdsrc);
4929 debug(F101,"popclvl tlevel","",tlevel);
4930 return(cmdlvl < 1 ? 0 : cmdlvl); /* Return command level */
4931 }
4932 #else /* No script programming language */
popclvl()4933 int popclvl() { /* Just close current take file. */
4934 if (tlevel > -1) { /* if any... */
4935 if (tfnam[tlevel]) {
4936 free(tfnam[tlevel]);
4937 tfnam[tlevel] = NULL;
4938 }
4939 fclose(tfile[tlevel--]);
4940 }
4941 if (tlevel == -1) { /* And if back at top level */
4942 setint();
4943 concb((char)escape); /* and go back into cbreak mode. */
4944 }
4945 xcmdsrc = tlevel > -1 ? CMD_TF : 0;
4946 return(tlevel + 1);
4947 }
4948 #endif /* NOSPL */
4949
4950
4951 #ifndef NOSPL
4952 static int
iseom(m)4953 iseom(m) char * m; { /* Test if at end of macro def */
4954 if (!m)
4955 m = "";
4956 debug(F111,"iseom",m,maclvl);
4957 while (*m) {
4958 /* Anything but Space and Comma means more macro is left */
4959 if ((*m > SP) && (*m != ',')) {
4960 debug(F111,"iseom return",m,0);
4961 return(0);
4962 }
4963 m++;
4964 }
4965 debug(F111,"iseom return",m,1);
4966 return(1); /* Nothing left */
4967 }
4968 #endif /* NOSPL */
4969
4970 /* Pop all command levels that can be popped */
4971
4972 int
prepop()4973 prepop() {
4974 if (cmdlvl > 0) { /* If command level is > 0 and... */
4975 while (
4976 #ifndef NOSPL
4977 ((cmdstk[cmdlvl].src == CMD_TF) && /* Command source is file */
4978 #endif /* NOSPL */
4979 (tlevel > -1) &&
4980 feof(tfile[tlevel])) /* And at end of file... */
4981 #ifndef NOSPL
4982 /* Or command source is macro... */
4983 || ((cmdstk[cmdlvl].src == CMD_MD) &&
4984 (maclvl > -1) &&
4985 iseom(macp[maclvl]))) /* and at end of macro, then... */
4986 #endif /* NOSPL */
4987 {
4988 popclvl(); /* pop command level. */
4989 }
4990 }
4991 return(cmdlvl < 1 ? 0 : cmdlvl); /* Return command level */
4992 }
4993
4994 /* STOP - get back to C-Kermit prompt, no matter where from. */
4995
4996 int
dostop()4997 dostop() {
4998 extern int cmddep;
4999 while (popclvl()) ; /* Pop all macros & take files */
5000 #ifndef NOSPL
5001 if (cmddep > -1) /* And all recursive cmd pkg invocations */
5002 while (cmpop() > -1) ;
5003 #endif /* NOSPL */
5004 cmini(ckxech); /* Clear the command buffer. */
5005 return(0);
5006 }
5007
5008 /* Close the given log */
5009
5010 int
doclslog(x)5011 doclslog(x) int x; {
5012 int y;
5013 switch (x) {
5014 #ifdef DEBUG
5015 case LOGD:
5016 if (deblog <= 0) {
5017 printf("?Debugging log wasn't open\n");
5018 return(0);
5019 }
5020 debug(F100,"Debug Log Closed","",0L);
5021 *debfil = '\0';
5022 deblog = 0;
5023 return(zclose(ZDFILE));
5024 #endif /* DEBUG */
5025
5026 #ifndef NOXFER
5027 case LOGP:
5028 if (pktlog <= 0) {
5029 printf("?Packet log wasn't open\n");
5030 return(0);
5031 }
5032 *pktfil = '\0';
5033 pktlog = 0;
5034 return(zclose(ZPFILE));
5035 #endif /* NOXFER */
5036
5037 #ifndef NOLOCAL
5038 case LOGS:
5039 if (seslog <= 0) {
5040 printf("?Session log wasn't open\n");
5041 return(0);
5042 }
5043 *sesfil = '\0';
5044 setseslog(0);
5045 return(zclose(ZSFILE));
5046 #endif /* NOLOCAL */
5047
5048 #ifdef TLOG
5049 case LOGT: {
5050 #ifdef IKSD
5051 extern int iklogopen, xferlog;
5052 #endif /* IKSD */
5053 if (tralog <= 0
5054 #ifdef IKSD
5055 && !iklogopen
5056 #endif /* IKSD */
5057 ) {
5058 if (msgflg)
5059 printf("?Transaction log wasn't open\n");
5060 return(0);
5061 }
5062 #ifdef IKSD
5063 if (iklogopen && !inserver) {
5064 close(xferlog);
5065 iklogopen = 0;
5066 }
5067 #endif /* IKSD */
5068 if (tralog) {
5069 tlog(F100,"Transaction Log Closed","",0L);
5070 zclose(ZTFILE);
5071 }
5072 *trafil = '\0';
5073 tralog = 0;
5074 return(1);
5075 }
5076 #endif /* TLOG */
5077
5078 #ifdef CKLOGDIAL
5079 case LOGM:
5080 if (dialog <= 0) {
5081 if (msgflg) printf("?Connection log wasn't open\n");
5082 return(0);
5083 }
5084 *diafil = '\0';
5085 dialog = 0;
5086 return(zclose(ZDIFIL));
5087 #endif /* CKLOGDIAL */
5088
5089 #ifndef NOSPL
5090 case LOGW: /* WRITE file */
5091 case LOGR: /* READ file */
5092 y = (x == LOGR) ? ZRFILE : ZWFILE;
5093 if (chkfn(y) < 1) /* If no file to close */
5094 return(1); /* succeed silently. */
5095 return(zclose(y)); /* Otherwise, close the file. */
5096 #endif /* NOSPL */
5097
5098 default:
5099 printf("\n?Unexpected log designator - %d\n", x);
5100 return(0);
5101 }
5102 }
5103
5104 static int slc = 0; /* Screen line count */
5105
5106 char *
showstring(s)5107 showstring(s) char * s; {
5108 return(s ? s : "(null)");
5109 }
5110
5111 char *
showoff(x)5112 showoff(x) int x; {
5113 return(x ? "on" : "off");
5114 }
5115
5116 char *
showooa(x)5117 showooa(x) int x; {
5118 switch (x) {
5119 case SET_OFF: return("off");
5120 case SET_ON: return("on");
5121 case SET_AUTO: return("automatic");
5122 default: return("(unknown)");
5123 }
5124 }
5125
5126 #ifdef GEMDOS
isxdigit(c)5127 isxdigit(c) int c; {
5128 return(isdigit(c) ||
5129 (c >= 'a' && c <= 'f') ||
5130 (c >= 'A' && c <= 'F'));
5131 }
5132 #endif /* GEMDOS */
5133
5134 #ifndef NOSETKEY
5135 #ifdef OS2
5136 static struct keytab shokeytab[] = { /* SHOW KEY modes */
5137 "all", 1, 0,
5138 "one", 0, 0
5139 };
5140 static int nshokey = (sizeof(shokeytab) / sizeof(struct keytab));
5141
5142 #define SHKEYDEF TT_MAX+5
5143 struct keytab shokeymtab[] = {
5144 "aaa", TT_AAA, CM_INV, /* AnnArbor */
5145 "adm3a", TT_ADM3A, 0, /* LSI ADM-3A */
5146 "adm5", TT_ADM5, 0, /* LSI ADM-5 */
5147 "aixterm", TT_AIXTERM, 0, /* IBM AIXterm */
5148 "annarbor", TT_AAA, 0, /* AnnArbor */
5149 "ansi-bbs", TT_ANSI, 0, /* ANSI.SYS (BBS) */
5150 "at386", TT_AT386, 0, /* Unixware ANSI */
5151 "avatar/0+", TT_ANSI, 0, /* AVATAR/0+ */
5152 "ba80", TT_BA80, 0, /* Nixdorf BA80 */
5153 "be", TT_BEOS, CM_INV|CM_ABR,
5154 "beos-ansi", TT_BEOS, CM_INV, /* BeOS ANSI */
5155 "beterm", TT_BEOS, 0, /* BeOS Console */
5156 "d200", TT_DG200, CM_INV|CM_ABR, /* Data General DASHER 200 */
5157 "d210", TT_DG210, CM_INV|CM_ABR, /* Data General DASHER 210 */
5158 "d217", TT_DG217, CM_INV|CM_ABR, /* Data General DASHER 217 */
5159 "default", SHKEYDEF, 0,
5160 "dg200", TT_DG200, 0, /* Data General DASHER 200 */
5161 "dg210", TT_DG210, 0, /* Data General DASHER 210 */
5162 "dg217", TT_DG217, 0, /* Data General DASHER 217 */
5163 "emacs", TT_KBM_EMACS, 0, /* Emacs mode */
5164 "h19", TT_H19, CM_INV, /* Heath-19 */
5165 "heath19", TT_H19, 0, /* Heath-19 */
5166 "hebrew", TT_KBM_HEBREW, 0, /* Hebrew mode */
5167 "hft", TT_HFT, 0, /* IBM HFT */
5168 "hp2621a", TT_HP2621, 0, /* HP 2621A */
5169 "hpterm", TT_HPTERM, 0, /* HP TERM */
5170 "hz1500", TT_HZL1500, 0, /* Hazeltine 1500 */
5171 "ibm3151", TT_IBM31, 0, /* IBM 3101-xx,3161 */
5172 "linux", TT_LINUX, 0, /* Linux */
5173 "qansi", TT_QANSI, 0, /* QNX ANSI */
5174 "qnx", TT_QNX, 0, /* QNX */
5175 "russian", TT_KBM_RUSSIAN, 0, /* Russian mode */
5176 "scoansi", TT_SCOANSI, 0, /* SCO ANSI */
5177 "sni-97801", TT_97801, 0, /* Sinix 97801 */
5178 "sun", TT_SUN, 0, /* Sun Console */
5179 #ifdef OS2PM
5180 #ifdef COMMENT
5181 "tek4014", TT_TEK40, 0,
5182 #endif /* COMMENT */
5183 #endif /* OS2PM */
5184 "tty", TT_NONE, 0,
5185 "tvi910+", TT_TVI910, 0,
5186 "tvi925", TT_TVI925, 0,
5187 "tvi950", TT_TVI950, 0,
5188 "vc404", TT_VC4404, 0,
5189 "vc4404", TT_VC4404, CM_INV,
5190 "vip7809", TT_VIP7809, 0,
5191 "vt100", TT_VT100, 0,
5192 "vt102", TT_VT102, 0,
5193 "vt220", TT_VT220, 0,
5194 "vt220pc", TT_VT220PC, 0,
5195 "vt320", TT_VT320, 0,
5196 "vt320pc", TT_VT320PC, 0,
5197 "vt52", TT_VT52, 0,
5198 "wp", TT_KBM_WP, 0,
5199 "wy160", TT_WY160, 0,
5200 "wy30", TT_WY30, 0,
5201 "wy370", TT_WY370, 0,
5202 "wy50", TT_WY50, 0,
5203 "wy60", TT_WY60, 0,
5204 "wyse30", TT_WY30, CM_INV,
5205 "wyse370", TT_WY370, CM_INV,
5206 "wyse50", TT_WY50, CM_INV,
5207 "wyse60", TT_WY60, CM_INV
5208 };
5209 int nshokeym = (sizeof(shokeymtab) / sizeof(struct keytab));
5210 #endif /* OS2 */
5211
5212 VOID
5213 #ifdef OS2
shokeycode(c,m)5214 shokeycode(c,m) int c, m;
5215 #else
5216 shokeycode(c) int c;
5217 #endif
5218 /* shokeycode */ {
5219 KEY ch;
5220 CHAR *s;
5221 #ifdef OS2
5222 int i;
5223 con_event km;
5224 #else /* OS2 */
5225 int km;
5226 #endif /* OS2 */
5227
5228 #ifdef OS2
5229 extern int mskkeys;
5230 char * mstr = "";
5231
5232 if (c >= KMSIZE) {
5233 bleep(BP_FAIL);
5234 return;
5235 }
5236 #else /* OS2 */
5237 printf(" Key code \\%d => ", c);
5238 #endif /* OS2 */
5239
5240 #ifndef OS2
5241 km = mapkey(c);
5242
5243 #ifndef NOKVERBS
5244 if (IS_KVERB(km)) { /* \Kverb? */
5245 int i, kv;
5246 kv = km & ~(F_KVERB);
5247 printf("Verb: ");
5248 for (i = 0; i < nkverbs; i++)
5249 if (kverbs[i].kwval == kv) {
5250 printf("\\K%s",kverbs[i].kwd);
5251 break;
5252 }
5253 printf("\n");
5254 } else
5255 #endif /* NOKVERBS */
5256 if (IS_CSI(km)) {
5257 int xkm = km & 0xFF;
5258 if (xkm <= 32 || xkm >= 127)
5259 printf("String: \\{27}[\\{%d}\n",xkm);
5260 else
5261 printf("String: \\{27}[%c\n",xkm);
5262 } else if (IS_ESC(km)) {
5263 int xkm = km & 0xFF;
5264 if (xkm <= 32 || xkm >= 127)
5265 printf("String: \\{27}\\{%d}\n",xkm);
5266 else
5267 printf("String: \\{27}%c\n",xkm);
5268 } else if (macrotab[c]) { /* See if there's a macro */
5269 printf("String: "); /* If so, display its definition */
5270 s = macrotab[c];
5271 shostrdef(s);
5272 printf("\n");
5273 #ifndef NOKVERBS
5274 } else if (km >= 0x100) { /* This means "undefined" */
5275 printf("Undefined\n");
5276 #endif /* NOKVERBS */
5277 } else { /* No macro, show single character */
5278 printf("Character: ");
5279 ch = km;
5280 if (ch < 32 || ch == 127
5281 #ifdef OS2
5282 || ch > 255
5283 #endif /* OS2 */
5284 #ifndef NEXT
5285 #ifndef AUX
5286 #ifndef XENIX
5287 #ifndef OS2
5288 || (ch > 127 && ch < 160)
5289 #endif /* OS2 */
5290 #endif /* XENIX */
5291 #endif /* AUX */
5292 #endif /* NEXT */
5293 )
5294 /*
5295 These used to be %d, but gcc 1.93 & later complain about type mismatches.
5296 %u is supposed to be totally portable.
5297 */
5298 printf("\\%u",(unsigned int) ch);
5299 else printf("%c \\%u",(CHAR) (ch & 0xff),(unsigned int) ch);
5300 if (ch == (KEY) c)
5301 printf(" (self, no translation)\n");
5302 else
5303 printf("\n");
5304 }
5305 #else /* OS2 */
5306 if (m < 0) {
5307 km = mapkey(c);
5308 mstr = "default";
5309 } else {
5310 km = maptermkey(c,m);
5311 for (i = 0; i < nshokeym; i++) {
5312 if (m == shokeymtab[i].kwval) {
5313 mstr = shokeymtab[i].kwd;
5314 break;
5315 }
5316 }
5317 }
5318 s = keyname(c);
5319 debug(F111,"shokeycode mstr",mstr,m);
5320 debug(F111,"shokeycode keyname",s,c);
5321 printf(" %sKey code \\%d %s (%s) => ",
5322 mskkeys ? "mskermit " : "",
5323 mskkeys ? cktomsk(c) : c,
5324 s == NULL ? "" : s, mstr);
5325
5326 switch (km.type) {
5327 #ifndef NOKVERBS
5328 case kverb: {
5329 int i, kv;
5330 kv = km.kverb.id & ~(F_KVERB);
5331 printf("Verb: ");
5332 for (i = 0; i < nkverbs; i++) {
5333 if (kverbs[i].kwval == kv) {
5334 printf("\\K%s",kverbs[i].kwd);
5335 break;
5336 }
5337 }
5338 printf("\n");
5339 break;
5340 }
5341 #endif /* NOKVERBS */
5342 case csi: {
5343 int xkm = km.csi.key & 0xFF;
5344 if (xkm <= 32 || xkm >= 127)
5345 printf("String: \\{27}[\\{%d}\n",xkm);
5346 else
5347 printf("String: \\{27}[%c\n",xkm);
5348 break;
5349 }
5350 case esc: {
5351 int xkm = km.esc.key & 0xFF;
5352 if (xkm <= 32 || xkm >= 127)
5353 printf("String: \\{%d}\\{%d}\n",ISDG200(tt_type)?30:27,xkm);
5354 else
5355 printf("String: \\{%d}%c\n",ISDG200(tt_type)?30:27,xkm);
5356 break;
5357 }
5358 case macro: {
5359 printf("String: "); /* Macro, display its definition */
5360 shostrdef(km.macro.string);
5361 printf("\n");
5362 break;
5363 }
5364 case literal: {
5365 printf("Literal string: "); /* Literal, display its definition */
5366 shostrdef(km.literal.string);
5367 printf("\n");
5368 break;
5369 }
5370 case error: {
5371 if (c >= 0x100) {
5372 printf("Undefined\n");
5373 } else {
5374 printf("Character: ");
5375 ch = c;
5376 if (ch < 32 || ch == 127 || ch > 255
5377 #ifndef NEXT
5378 #ifndef AUX
5379 #ifndef XENIX
5380 #ifndef OS2
5381 || (ch > 127 && ch < 160)
5382 #endif /* OS2 */
5383 #endif /* XENIX */
5384 #endif /* AUX */
5385 #endif /* NEXT */
5386 )
5387 /*
5388 These used to be %d, but gcc 1.93 & later complain about type mismatches.
5389 %u is supposed to be totally portable.
5390 */
5391 printf("\\%u",(unsigned int) ch);
5392 else printf("%c \\%u",(CHAR) (ch & 0xff),(unsigned int) ch);
5393 printf(" (self, no translation)\n");
5394 }
5395 break;
5396 }
5397 case key: {
5398 printf("Character: ");
5399 ch = km.key.scancode;
5400 if (ch < 32 || ch == 127 || ch > 255
5401 #ifndef NEXT
5402 #ifndef AUX
5403 #ifndef XENIX
5404 #ifndef OS2
5405 || (ch > 127 && ch < 160)
5406 #else
5407 || (ch > 127)
5408 #endif /* OS2 */
5409 #endif /* XENIX */
5410 #endif /* AUX */
5411 #endif /* NEXT */
5412 )
5413 /*
5414 These used to be %d, but gcc 1.93 & later complain about type mismatches.
5415 %u is supposed to be totally portable.
5416 */
5417 printf("\\%u",(unsigned int) ch);
5418 else printf("%c \\%u",(CHAR) (ch & 0xff),(unsigned int) ch);
5419 if (ch == (KEY) c)
5420 printf(" (self, no translation)\n");
5421 else
5422 printf("\n");
5423 break;
5424 }
5425 }
5426 #endif /* OS2 */
5427 }
5428 #endif /* NOSETKEY */
5429
5430 VOID
shostrdef(s)5431 shostrdef(s) CHAR * s; {
5432 CHAR ch;
5433 if (!s) s = (CHAR *)"";
5434 while ((ch = *s++)) {
5435 if (ch < 32 || ch == 127 || ch == 255
5436 /*
5437 Systems whose native character sets have graphic characters in C1...
5438 */
5439 #ifndef NEXT /* NeXT */
5440 #ifndef AUX /* Macintosh */
5441 #ifndef XENIX /* IBM PC */
5442 #ifdef OS2
5443 /*
5444 It doesn't matter whether the local host can display 8-bit characters;
5445 they are not portable among character-sets and fonts. Who knows what
5446 would be displayed...
5447 */
5448 || (ch > 127)
5449 #else /* OS2 */
5450 || (ch > 127 && ch < 160)
5451 #endif /* OS2 */
5452 #endif /* XENIX */
5453 #endif /* AUX */
5454 #endif /* NEXT */
5455 )
5456 printf("\\{%d}",ch); /* Display control characters */
5457 else putchar((char) ch); /* in backslash notation */
5458 }
5459 }
5460
5461 #define xxdiff(v,sys) strncmp(v,sys,strlen(sys))
5462
5463 #ifndef NOSHOW
5464 VOID
shover()5465 shover() {
5466 #ifdef OS2
5467 extern char ckxsystem[];
5468 #endif /* OS2 */
5469 extern char *ck_patch, * cklibv;
5470 printf("\nVersions:\n %s\n",versio);
5471 printf(" Numeric: %ld\n",vernum);
5472 #ifdef OS2
5473 printf(" Operating System: %s\n", ckxsystem);
5474 #else /* OS2 */
5475 printf(" Built for: %s\n", ckxsys);
5476 #ifdef CK_UTSNAME
5477 if (unm_nam[0])
5478 printf(" Running on: %s %s %s %s\n", unm_nam,unm_ver,unm_rel,unm_mch);
5479 #endif /* CK_UTSNAME */
5480 printf(" Patches: %s\n", *ck_patch ? ck_patch : "(none)");
5481 #endif /* OS2 */
5482 if (xxdiff(ckxv,ckxsys))
5483 printf(" %s for%s\n",ckxv,ckxsys);
5484 else
5485 printf(" %s\n",ckxv);
5486 if (xxdiff(ckzv,ckzsys))
5487 printf(" %s for%s\n",ckzv,ckzsys);
5488 else
5489 printf(" %s\n",ckzv);
5490 printf(" %s\n",cklibv);
5491 printf(" %s\n",protv);
5492 printf(" %s\n",fnsv);
5493 printf(" %s\n %s\n",cmdv,userv);
5494 #ifndef NOCSETS
5495 printf(" %s\n",xlav);
5496 #endif /* NOCSETS */
5497 #ifndef MAC
5498 #ifndef NOLOCAL
5499 printf(" %s\n",connv);
5500 #ifdef OS2
5501 printf(" %s\n",ckyv);
5502 #endif /* OS2 */
5503 #endif /* NOLOCAL */
5504 #endif /* MAC */
5505 #ifndef NODIAL
5506 printf(" %s\n",dialv);
5507 #endif /* NODIAL */
5508 #ifndef NOSCRIPT
5509 printf(" %s\n",loginv);
5510 #endif /* NOSCRIPT */
5511 #ifdef NETCONN
5512 printf(" %s\n",cknetv);
5513 #ifdef OS2
5514 printf(" %s\n",ckonetv);
5515 #ifdef CK_NETBIOS
5516 printf(" %s\n",ckonbiv);
5517 #endif /* CK_NETBIOS */
5518 #endif /* OS2 */
5519 #endif /* NETCONN */
5520 #ifdef TNCODE
5521 printf(" %s\n",cktelv);
5522 #endif /* TNCODE */
5523 #ifdef SSHBUILTIN
5524 printf(" %s\n",cksshv);
5525 #ifdef SFTP_BUILTIN
5526 printf(" %s\n",cksftpv);
5527 #endif /* SFTP_BUILTIN */
5528 #endif /* SSHBUILTIN */
5529 #ifdef OS2
5530 #ifdef OS2MOUSE
5531 printf(" %s\n",ckomouv);
5532 #endif /* OS2MOUSE */
5533 #endif /* OS2 */
5534 #ifdef NEWFTP
5535 printf(" %s\n",ckftpv);
5536 #endif /* NEWFTP */
5537 #ifdef CK_AUTHENTICATION
5538 printf(" %s\n",ckathv);
5539 #endif /* CK_AUTHENTICATION */
5540 #ifdef CK_ENCRYPTION
5541 #ifdef CRYPT_DLL
5542 printf(" %s\n",ck_crypt_dll_version());
5543 #else /* CRYPT_DLL */
5544 printf(" %s\n",ckcrpv);
5545 #endif /* CRYPT_DLL */
5546 #endif /* CK_ENCRYPTION */
5547 #ifdef CK_SSL
5548 printf(" %s\n",cksslv);
5549 #endif /* CK_SSL */
5550 printf("\n");
5551 }
5552
5553 #ifdef CK_LABELED
5554 VOID
sholbl()5555 sholbl() {
5556 #ifdef VMS
5557 printf("VMS Labeled File Features:\n");
5558 printf(" acl %s (ACL info %s)\n",
5559 showoff(lf_opts & LBL_ACL),
5560 lf_opts & LBL_ACL ? "preserved" : "discarded");
5561 printf(" backup-date %s (backup date/time %s)\n",
5562 showoff(lf_opts & LBL_BCK),
5563 lf_opts & LBL_BCK ? "preserved" : "discarded");
5564 printf(" name %s (original filename %s)\n",
5565 showoff(lf_opts & LBL_NAM),
5566 lf_opts & LBL_NAM ? "preserved" : "discarded");
5567 printf(" owner %s (original file owner id %s)\n",
5568 showoff(lf_opts & LBL_OWN),
5569 lf_opts & LBL_OWN ? "preserved" : "discarded");
5570 printf(" path %s (original file's disk:[directory] %s)\n",
5571 showoff(lf_opts & LBL_PTH),
5572 lf_opts & LBL_PTH ? "preserved" : "discarded");
5573 #else
5574 #ifdef OS2
5575 printf("OS/2 Labeled File features (attributes):\n");
5576 printf(" archive: %s\n", showoff(lf_opts & LBL_ARC));
5577 printf(" extended: %s\n", showoff(lf_opts & LBL_EXT));
5578 printf(" hidden: %s\n", showoff(lf_opts & LBL_HID));
5579 printf(" read-only: %s\n", showoff(lf_opts & LBL_RO ));
5580 printf(" system: %s\n", showoff(lf_opts & LBL_SYS));
5581 #endif /* OS2 */
5582 #endif /* VMS */
5583 }
5584 #endif /* CK_LABELED */
5585
5586 VOID
shotcs(csl,csr)5587 shotcs(csl,csr) int csl, csr; { /* Show terminal character set */
5588 #ifndef NOCSETS
5589 #ifdef OS2
5590 #ifndef NOTERM
5591 extern struct _vtG G[4], *GL, *GR;
5592 extern int decnrcm, sni_chcode;
5593 extern int tt_utf8, dec_nrc, dec_kbd, dec_lang;
5594 extern prncs;
5595
5596 printf(" Terminal character-sets:\n");
5597 if (IS97801(tt_type_mode)) {
5598 if (cmask == 0377)
5599 printf(" Mode: 8-bit Mode\n");
5600 else
5601 printf(" Mode: 7-bit Mode\n");
5602 printf(" CH.CODE is %s\n",sni_chcode?"On":"Off");
5603 } else if (ISVT100(tt_type_mode)) {
5604 if (decnrcm)
5605 printf(" Mode: 7-bit National Mode\n");
5606 else
5607 printf(" Mode: 8-bit Multinational Mode\n");
5608 }
5609 if ( isunicode() )
5610 printf(" Local: Unicode display / %s input\n",
5611 csl == TX_TRANSP ? "transparent" :
5612 csl == TX_UNDEF ? "undefined" : txrinfo[csl]->keywd);
5613 else
5614 printf(" Local: %s\n",
5615 csl == TX_TRANSP ? "transparent" :
5616 csl == TX_UNDEF ? "undefined" : txrinfo[csl]->keywd);
5617
5618 if ( tt_utf8 ) {
5619 printf(" Remote: UTF-8\n");
5620 } else {
5621 printf(" Remote: %sG0: %s (%s)\n",
5622 GL == &G[0] ? "GL->" : GR == &G[0] ? "GR->" : " ",
5623 txrinfo[G[0].designation]->keywd,
5624 G[0].designation == TX_TRANSP ? "" :
5625 G[0].size == cs94 ? "94 chars" :
5626 G[0].size == cs96 ? "96 chars" : "multi-byte");
5627 printf(" %sG1: %s (%s)\n",
5628 GL == &G[1] ? "GL->" : GR == &G[1] ? "GR->" : " ",
5629 txrinfo[G[1].designation]->keywd,
5630 G[1].designation == TX_TRANSP ? "" :
5631 G[1].size == cs94 ? "94 chars" :
5632 G[1].size == cs96 ? "96 chars" : "multi-byte");
5633 printf(" %sG2: %s (%s)\n",
5634 GL == &G[2] ? "GL->" : GR == &G[2] ? "GR->" : " ",
5635 txrinfo[G[2].designation]->keywd,
5636 G[2].designation == TX_TRANSP ? "" :
5637 G[2].size == cs94 ? "94 chars" :
5638 G[2].size == cs96 ? "96 chars" : "multi-byte");
5639 printf(" %sG3: %s (%s)\n",
5640 GL == &G[3] ? "GL->" : GR == &G[3] ? "GR->" : " ",
5641 txrinfo[G[3].designation]->keywd,
5642 G[3].designation == TX_TRANSP ? "" :
5643 G[3].size == cs94 ? "94 chars" :
5644 G[3].size == cs96 ? "96 chars" : "multi-byte");
5645 }
5646 printf("\n");
5647 printf(" Keyboard character-sets:\n");
5648 printf(" Multinational: %s\n",txrinfo[dec_kbd]->keywd);
5649 printf(" National: %s\n",txrinfo[dec_nrc]->keywd);
5650 printf("\n");
5651 printf(" Printer character-set: %s\n",txrinfo[prncs]->keywd);
5652 #endif /* NOTERM */
5653 #else /* OS2 */
5654 #ifndef MAC
5655 char *s;
5656
5657 debug(F101,"TERM LOCAL CSET","",csl);
5658 debug(F101,"TERM REMOTE CSET","",csr);
5659 printf(" Terminal character-set: ");
5660 if (tcs_transp) { /* No translation */
5661 printf("transparent\n");
5662 } else { /* Translation */
5663 printf("%s (remote) %s (local)\n",
5664 fcsinfo[csr].keyword,fcsinfo[csl].keyword);
5665 if (csr != csl) {
5666 switch(gettcs(csr,csl)) {
5667 case TC_USASCII: s = "ascii"; break;
5668 case TC_1LATIN: s = "latin1-iso"; break;
5669 case TC_2LATIN: s = "latin2-iso"; break;
5670 case TC_CYRILL: s = "cyrillic-iso"; break;
5671 case TC_JEUC: s = "japanese-euc"; break;
5672 case TC_HEBREW: s = "hebrew-iso"; break;
5673 case TC_GREEK: s = "greek-iso"; break;
5674 case TC_9LATIN: s = "latin9-iso"; break;
5675 default: s = "transparent"; break;
5676 }
5677 if (strcmp(s,fcsinfo[csl].keyword) &&
5678 strcmp(s,fcsinfo[csr].keyword))
5679 printf(" (via %s)\n",s);
5680 }
5681 }
5682 #endif /* MAC */
5683 #endif /* OS2 */
5684 #endif /* NOCSETS */
5685 }
5686
5687 #ifndef NOLOCAL
5688 #ifdef OS2
5689 extern char htab[];
5690 VOID
shotabs()5691 shotabs() {
5692 int i,j,k,n;
5693
5694 printf("Tab Stops:\n\n");
5695 for (i = 0, j = 1, k = VscrnGetWidth(VCMD); i < MAXTERMCOL; ) {
5696 do {
5697 printf("%c",htab[++i]=='T'?'T':'-');
5698 } while (i % k && i < MAXTERMCOL);
5699 printf("\n");
5700 for ( ; j <= i; j++) {
5701 switch ( j%10 ) {
5702 case 1:
5703 printf("%c",j == 1 ? '1' : '.');
5704 break;
5705 case 2:
5706 case 3:
5707 case 4:
5708 case 5:
5709 case 6:
5710 case 7:
5711 printf("%c",'.');
5712 break;
5713 case 8:
5714 n = (j+2)/100;
5715 if (n)
5716 printf("%d",n);
5717 else
5718 printf("%c",'.');
5719 break;
5720 case 9:
5721 n = (j+1)%100/10;
5722 if (n)
5723 printf("%d",n);
5724 else if (j>90)
5725 printf("0");
5726 else
5727 printf("%c",'.');
5728 break;
5729 case 0:
5730 printf("0");
5731 break;
5732 }
5733 }
5734 printf("\n");
5735 }
5736 #ifdef COMMENT
5737 for (i = 1; i <= 70; i++)
5738 printf("%c",htab[i]=='T'?'T':'-');
5739 printf("\n1.......10........20........30........40........50........60\
5740 ........70\n\n");
5741 for (; i <= 140; i++)
5742 printf("%c",htab[i]=='T'?'T':'-');
5743 printf("\n........80........90.......100.......110.......120.......130\
5744 .......140\n\n");
5745 for (; i <= 210; i++)
5746 printf("%c",htab[i]=='T'?'T':'-');
5747 printf("\n.......150.......160.......170.......180.......190.......200\
5748 .......210\n\n");
5749 for (; i <= 255; i++)
5750 printf("%c",htab[i]=='T'?'T':'-');
5751 printf("\n.......220.......230.......240.......250..255\n");
5752 #endif
5753
5754 }
5755 #endif /* OS2 */
5756 #endif /* NOLOCAL */
5757
5758 #ifdef OS2MOUSE
5759 VOID
shomou()5760 shomou() {
5761 int button, event, id, i;
5762 char * name = "";
5763
5764 printf("Mouse settings:\n");
5765 printf(" Button Count: %d\n",mousebuttoncount());
5766 printf(" Active: %s\n\n",showoff(tt_mouse));
5767
5768 for (button = 0; button < MMBUTTONMAX; button++)
5769 for (event = 0; event < MMEVENTSIZE; event++)
5770 if (mousemap[button][event].type != error)
5771 switch (mousemap[button][event].type) {
5772 case key:
5773 printf(" %s = Character: %c \\%d\n",
5774 mousename(button,event),
5775 mousemap[button][event].key.scancode,
5776 mousemap[button][event].key.scancode );
5777 break;
5778 case kverb:
5779 id = mousemap[button][event].kverb.id & ~(F_KVERB);
5780 if (id != K_IGNORE) {
5781 for (i = 0; i< nkverbs; i++)
5782 if (id == kverbs[i].kwval) {
5783 name = kverbs[i].kwd;
5784 break;
5785 }
5786 printf(" %s = Kverb: \\K%s\n",
5787 mousename(button,event),
5788 name
5789 );
5790 }
5791 break;
5792 case macro:
5793 printf(" %s = Macro: ",
5794 mousename(button,event) );
5795 shostrdef(mousemap[button][event].macro.string);
5796 printf("\n");
5797 break;
5798 }
5799 }
5800 #endif /* OS2MOUSE */
5801
5802 #ifndef NOLOCAL
5803 VOID
shotrm()5804 shotrm() {
5805 char *s;
5806 extern char * getiact();
5807 extern int tt_print, adl_err;
5808 #ifndef NOTRIGGER
5809 extern char * tt_trigger[];
5810 #endif /* NOTRIGGER */
5811 #ifdef CKTIDLE
5812 extern char * tt_idlesnd_str;
5813 extern int tt_idlesnd_tmo;
5814 extern int tt_idlelimit, tt_idleact;
5815 #endif /* CKTIDLE */
5816 #ifdef OS2
5817 extern int wy_autopage, autoscroll, sgrcolors, colorreset, user_erasemode,
5818 decscnm, decscnm_usr, tt_diff_upd, tt_senddata,
5819 wy_blockend, marginbell, marginbellcol, tt_modechg, dgunix;
5820 int lines = 0;
5821 #ifdef KUI
5822 extern CKFLOAT tt_linespacing[];
5823 extern tt_cursor_blink;
5824 #endif /* KUI */
5825 #ifdef PCFONTS
5826 int i;
5827 char *font;
5828
5829 if (IsOS2FullScreen()) { /* Determine the font name */
5830 if (!os2LoadPCFonts()) {
5831 for (i = 0; i < ntermfont; i++) {
5832 if (tt_font == term_font[i].kwval) {
5833 font = term_font[i].kwd;
5834 break;
5835 }
5836 }
5837 } else {
5838 font = "(DLL not available)";
5839 }
5840 } else {
5841 font = "(full screen only)";
5842 }
5843 #endif /* PCFONTS */
5844 #ifdef KUI
5845 char font[64] = "(unknown)";
5846 if ( ntermfont > 0 ) {
5847 int i;
5848 for (i = 0; i < ntermfont; i++) {
5849 if (tt_font == term_font[i].kwval) {
5850 ckstrncpy(font,term_font[i].kwd,59);
5851 ckstrncat(font," ",64);
5852 ckstrncat(font,ckitoa(tt_font_size/2),64);
5853 if ( tt_font_size % 2 )
5854 ckstrncat(font,".5",64);
5855 break;
5856 }
5857 }
5858 }
5859 #endif /* KUI */
5860
5861 printf("Terminal parameters:\n");
5862 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5863 printf(" %19s: %1d%-12s %13s: %1d%-14s\n",
5864 "Bytesize: Command",
5865 (cmdmsk == 0377) ? 8 : 7,
5866 " bits","Terminal",
5867 (cmask == 0377) ? 8 : 7," bits");
5868 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5869 printf(" %19s: %-13s","Type",
5870 (tt_type >= 0 && tt_type <= max_tt) ?
5871 tt_info[tt_type].x_name :
5872 "unknown" );
5873 if (tt_type >= 0 && tt_type <= max_tt)
5874 if (strlen(tt_info[tt_type].x_id))
5875 printf(" %13s: <ESC>%s","ID",tt_info[tt_type].x_id);
5876 printf("\n");
5877 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5878 printf(" %19s: %-13s %13s: %-15s\n","Echo",
5879 duplex ? "local" : "remote","Locking-shift",showoff(sosi));
5880 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5881 printf(" %19s: %-13s %13s: %-15s\n","Newline-mode", showoff(tnlm),
5882 "Cr-display",tt_crd ? "crlf" : "normal");
5883 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5884 printf(" %19s: %-13s %13s: %-15s\n","Cursor",
5885 #ifdef KUI
5886 (tt_cursor == 2) ? (tt_cursor_blink ?
5887 "full (*)" : "full (.)") :
5888 (tt_cursor == 1) ? (tt_cursor_blink ?
5889 "half (*)" : "half (.)") :
5890 (tt_cursor_blink ? "underline (*)" : "underline (.)"),
5891 #else /* KUI */
5892 (tt_cursor == 2) ? "full" :
5893 (tt_cursor == 1) ? "half" : "underline",
5894 #endif /* KUI */
5895 #ifdef CK_AUTODL
5896 "autodownload",autodl == TAD_ON ?
5897 (adl_err ? "on, error stop" : "on, error continue") :
5898 autodl == TAD_ASK ?
5899 (adl_err ? "ask, error stop" : "ask, error continue") :
5900 "off"
5901 #else /* CK_AUTODL */
5902 "", ""
5903 #endif /* CK_AUTODL */
5904 );
5905 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5906 printf(" %19s: %-13s %13s: %-15s\n","Arrow-keys",
5907 tt_arrow ? "application" : "cursor",
5908 "Keypad-mode", tt_keypad ? "application" : "numeric"
5909 );
5910
5911 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5912
5913 /* Just to make sure we are using current info */
5914 updanswerbk();
5915
5916 /*
5917 This line doesn't end with '\n' because the answerback string
5918 is terminated with a newline
5919 */
5920 printf(" %19s: %-13s %13s: %-15s","Answerback",
5921 showoff(tt_answer),"response",answerback);
5922 switch (tt_bell) {
5923 case XYB_NONE:
5924 s = "none";
5925 break;
5926 case XYB_VIS:
5927 s= "visible";
5928 break;
5929 case XYB_AUD | XYB_BEEP:
5930 s="beep";
5931 break;
5932 case XYB_AUD | XYB_SYS:
5933 s="system sounds";
5934 break;
5935 default:
5936 s="(unknown)";
5937 }
5938 printf(" %19s: %-13s %13s: %-15s\n","Bell",s,
5939 "Wrap",showoff(tt_wrap));
5940 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5941 printf(" %19s: %-13s %13s: %-15s\n","Autopage",showoff(wy_autopage),
5942 "Autoscroll",showoff(autoscroll));
5943 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5944 printf(" %19s: %-13s %13s: %-15s\n","SGR Colors",showoff(sgrcolors),
5945 "ESC[0m color",colorreset?"default-color":"current-color");
5946 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5947 printf(" %19s: %-13s %13s: %-15s\n",
5948 "Erase color",user_erasemode?"default-color":"current-color",
5949 "Screen mode",decscnm?"reverse":"normal");
5950 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5951
5952 printf(" %19s: %-13d %13s: %-15d\n","Transmit-timeout",tt_ctstmo,
5953 "Output-pacing",tt_pacing);
5954 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5955
5956 printf(" %19s: %-13d %13s: %s\n","Idle-timeout",tt_idlelimit,
5957 "Idle-action", getiact());
5958
5959 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5960 printf(" %19s: %-13s %13s: %-15s\n","Send data",
5961 showoff(tt_senddata),"End of Block", wy_blockend?"crlf/etx":"us/cr");
5962 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5963 #ifndef NOTRIGGER
5964 printf(" %19s: %-13s %13s: %d seconds\n","Auto-exit trigger",
5965 tt_trigger[0],"Output pacing",tt_pacing );
5966 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5967 #endif /* NOTRIGGER */
5968 printf(" %19s: %-13s %13s: %-15d\n","Margin bell",
5969 showoff(marginbell),"at column", marginbellcol);
5970 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5971 switch (tt_modechg) {
5972 case TVC_DIS: s = "disabled"; break;
5973 case TVC_ENA: s = "enabled"; break;
5974 case TVC_W95: s = "win95-restricted"; break;
5975 default: s = "(unknown)";
5976 }
5977 printf(" %19s: %-13s %13s: %-15s\n","DG Unix mode",
5978 showoff(dgunix),"Video change", s);
5979 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
5980
5981 #ifdef CK_APC
5982 if (apcstatus == APC_ON) s = "on";
5983 else if (apcstatus == APC_OFF) s = "off";
5984 else if (apcstatus == APC_ON|APC_UNCH) s = "unchecked";
5985 else if (apcstatus == APC_ON|APC_NOINP) s = "no-input";
5986 else if (apcstatus == APC_ON|APC_UNCH|APC_NOINP) s = "unchecked-no-input";
5987 printf(" %19s: %-13s %13s: %-15s\n",
5988 "APC", s,
5989 #ifdef PCFONTS
5990 "Font (VGA)",font
5991 #else /* PCFONTS */
5992 #ifdef KUI
5993 "Font",font
5994 #else
5995 "Font","(not supported)"
5996 #endif /* KUI */
5997 #endif /* PCFONTS */
5998
5999 );
6000 #endif /* CK_APC */
6001 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
6002
6003 #ifdef CK_TTGWSIZ /* Console terminal screen size */
6004 if (tt_cols[VTERM] < 0 || tt_rows[VTERM] < 0)
6005 ttgwsiz(); /* Try to get latest size */
6006 #endif /* CK_TTGWSIZ */
6007 printf(" %19s: %-13d %13s: %-15d\n","Height",tt_rows[VTERM],
6008 "Width",tt_cols[VTERM]);
6009 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
6010 #ifdef KUI
6011 printf(" %19s: %-12f %14s: %-15d\n","Line spacing",tt_linespacing[VTERM],
6012 "Display Height",VscrnGetDisplayHeight(VTERM));
6013 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
6014 #endif /* KUI */
6015 printf(" %19s: %-13s %13s: %d lines\n","Roll-mode",
6016 tt_roll[VTERM]?"insert":"overwrite","Scrollback", tt_scrsize[VTERM]);
6017 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
6018
6019 if (updmode == tt_updmode)
6020 if (updmode == TTU_FAST)
6021 s = "fast (fast)";
6022 else
6023 s = "smooth (smooth)";
6024 else
6025 if (updmode == TTU_FAST)
6026 s = "fast (smooth)";
6027 else
6028 s = "smooth (fast)";
6029
6030 printf(" %19s: %-13s %13s: %d ms\n","Screen-update: mode",s,
6031 "interval",tt_update);
6032 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
6033 printf(" %19s: %-13s %13s: %-15s\n",
6034 "Screen-optimization",showoff(tt_diff_upd),
6035 "Status line",showoff(tt_status[VTERM]));
6036 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
6037 printf(" %19s: %-13s %13s: %-15s\n","Debug",
6038 showoff(debses),"Session log", seslog? sesfil : "(none)" );
6039 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
6040
6041 /* Display colors (should become SHOW COLORS) */
6042 {
6043 USHORT row, col;
6044 char * colors[16] = {
6045 "black","blue","green","cyan","red","magenta","brown","lgray",
6046 "dgray","lblue","lgreen","lcyan","lred","lmagent","yellow","white"
6047 };
6048 printf("\n");
6049 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
6050
6051 printf(" Color:");
6052 #ifndef ONETERMUPD
6053 GetCurPos(&row, &col);
6054 WrtCharStrAtt("border", 6, row, 9, &colorborder );
6055 WrtCharStrAtt("debug", 5, row, 17, &colordebug );
6056 WrtCharStrAtt("helptext", 8, row, 25, &colorhelp );
6057 WrtCharStrAtt("reverse", 7, row, 34, &colorreverse );
6058 WrtCharStrAtt("select", 6, row, 42, &colorselect );
6059 WrtCharStrAtt("status", 6, row, 50, &colorstatus );
6060 WrtCharStrAtt("terminal", 8, row, 58, &colornormal );
6061 WrtCharStrAtt("underline", 9, row, 67, &colorunderline );
6062 #endif /* ONETERMUPD */
6063 row = VscrnGetCurPos(VCMD)->y+1;
6064 VscrnWrtCharStrAtt(VCMD, "border", 6, row, 9, &colorborder );
6065 VscrnWrtCharStrAtt(VCMD, "debug", 5, row, 17, &colordebug );
6066 VscrnWrtCharStrAtt(VCMD, "helptext", 8, row, 25, &colorhelp );
6067 VscrnWrtCharStrAtt(VCMD, "reverse", 7, row, 34, &colorreverse );
6068 VscrnWrtCharStrAtt(VCMD, "select", 6, row, 42, &colorselect );
6069 VscrnWrtCharStrAtt(VCMD, "status", 6, row, 50, &colorstatus );
6070 VscrnWrtCharStrAtt(VCMD, "terminal", 8, row, 58, &colornormal );
6071 VscrnWrtCharStrAtt(VCMD, "underline", 9, row, 67, &colorunderline );
6072 printf("\n");
6073 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
6074
6075 /* Foreground color names */
6076 printf("%6s: %-8s%-8s%-9s%-8s%-8s%-8s%-9s%-9s\n","fore",
6077 "",
6078 colors[colordebug&0x0F],
6079 colors[colorhelp&0x0F],
6080 colors[colorreverse&0x0F],
6081 colors[colorselect&0x0F],
6082 colors[colorstatus&0x0F],
6083 colors[colornormal&0x0F],
6084 colors[colorunderline&0x0F]);
6085 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
6086
6087 /* Background color names */
6088 printf("%6s: %-8s%-8s%-9s%-8s%-8s%-8s%-9s%-9s\n","back",
6089 colors[colorborder],
6090 colors[colordebug>>4],
6091 colors[colorhelp>>4],
6092 colors[colorreverse>>4],
6093 colors[colorselect>>4],
6094 colors[colorstatus>>4],
6095 colors[colornormal>>4],
6096 colors[colorunderline>>4] );
6097 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
6098 printf("\n");
6099 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
6100 printf(" Color:");
6101 #ifndef ONETERMUPD
6102 GetCurPos(&row, &col);
6103 WrtCharStrAtt("graphic", 7, row, 9, &colorgraphic );
6104 WrtCharStrAtt("command", 7, row, 17, &colorcmd );
6105 WrtCharStrAtt("italic", 6, row, 26, &coloritalic );
6106 #endif /* ONETERMUPD */
6107 row = VscrnGetCurPos(VCMD)->y+1;
6108 VscrnWrtCharStrAtt(VCMD, "graphic", 7, row, 9, &colorgraphic );
6109 VscrnWrtCharStrAtt(VCMD, "command", 7, row, 17, &colorcmd );
6110 VscrnWrtCharStrAtt(VCMD, "italic", 6, row, 26, &coloritalic );
6111 printf("\n");
6112 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
6113
6114 /* Foreground color names */
6115 printf("%6s: %-8s%-8s%-8s\n","fore",
6116 colors[colorgraphic&0x0F],
6117 colors[colorcmd&0x0F],
6118 colors[coloritalic&0x0F]);
6119 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
6120
6121 /* Background color names */
6122 printf("%6s: %-8s%-8s%-8s\n","back",
6123 colors[colorgraphic>>4],
6124 colors[colorcmd>>4],
6125 colors[coloritalic>>4]);
6126 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
6127 }
6128 printf("\n");
6129 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
6130 {
6131 extern int trueblink, truedim, truereverse, trueunderline, trueitalic;
6132 printf(
6133 " Attribute: \
6134 blink: %-3s dim: %-3s italic: %-3s reverse: %-3s underline: %-3s\n",
6135 trueblink?"on":"off", truedim?"on":"off", trueitalic?"on":"off",
6136 truereverse?"on":"off", trueunderline?"on":"off");
6137 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
6138 }
6139 {
6140 extern vtattrib WPattrib;
6141 printf(" ASCII Protected chars: %s%s%s%s%s%s%s\n",
6142 WPattrib.blinking?"blink ":"",
6143 WPattrib.italic?"italic ":"",
6144 WPattrib.reversed?"reverse ":"",
6145 WPattrib.underlined?"underline ":"",
6146 WPattrib.bold?"bold ":"",
6147 WPattrib.dim?"dim ":"",
6148 WPattrib.invisible?"invisible ":"");
6149 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
6150 }
6151
6152 printf("\n");
6153 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
6154 (VOID) shoesc(escape);
6155 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
6156 printf(" See SHOW CHARACTER-SETS for character-set info\n");
6157 if (++lines > cmd_rows - 3) { if (!askmore()) return; else lines = 0; }
6158
6159 #else /* OS2 */ /* Beginning of new non-OS2 version */
6160
6161 printf("\n");
6162 printf("Terminal parameters:\n");
6163 printf(" %19s: %1d%-12s %13s: %1d%-14s\n",
6164 "Bytesize: Command",
6165 (cmdmsk == 0377) ? 8 : 7,
6166 " bits","Terminal",
6167 (cmask == 0377) ? 8 : 7," bits");
6168 s = getenv("TERM");
6169 #ifdef XPRINT
6170 printf(" %19s: %-13s %13s: %-15s\n",
6171 "Type",
6172 s ? s : "(unknown)",
6173 "Print",
6174 showoff(tt_print)
6175 );
6176 #else
6177 printf(" %19s: %-13s\n","Type", s ? s : "(unknown)");
6178 #endif /* XPRINT */
6179 printf(" %19s: %-13s %13s: %-15s\n","Echo",
6180 duplex ? "local" : "remote","Locking-shift",showoff(sosi));
6181 printf(" %19s: %-13s %13s: %-15s\n","Newline-mode",
6182 showoff(tnlm),"Cr-display",tt_crd ? "crlf" : "normal");
6183
6184 #ifdef CK_APC
6185 if (apcstatus == APC_ON) s = "on";
6186 else if (apcstatus == APC_OFF) s = "off";
6187 else if (apcstatus == (APC_ON|APC_UNCH)) s = "unchecked";
6188 else if (apcstatus == (APC_ON|APC_NOINP)) s = "no-input";
6189 else if (apcstatus == (APC_ON|APC_UNCH|APC_NOINP))
6190 s = "unchecked-no-input";
6191 printf(" %19s: %-13s %13s: %-15s\n",
6192 "APC", s,
6193 #ifdef CK_AUTODL
6194 "Autodownload", autodl ?
6195 (adl_err ? "on, error stop" : "on, error continue") : "off"
6196 #else
6197 "",""
6198 #endif /* CK_AUTODL */
6199 );
6200 #endif /* CK_APC */
6201
6202 #ifdef CK_TTGWSIZ /* Console terminal screen size */
6203 ttgwsiz(); /* Try to get latest size */
6204 printf(" %19s: %-13d %13s: %-15d\n","Height",tt_rows, "Width", tt_cols);
6205 #endif /* CK_TTGWSIZ */
6206
6207 printf(" %19s: %-13s %13s: %-15s\n","Debug",
6208 showoff(debses),"Session log", seslog? sesfil : "(none)" );
6209
6210 #ifdef CKTIDLE
6211 printf(" %19s: %-13d %13s: %s\n","Idle-timeout",tt_idlelimit,
6212 "Idle-action", getiact());
6213 #endif /* CKTIDLE */
6214
6215 printf(" %19s: %-13s ","Lf-display", tt_lfd ? "crlf" : "normal");
6216 #ifdef UNIX
6217 #ifndef NOJC
6218 printf("%13s: %-15s","Suspend", showoff(xsuspend));
6219 #endif /* NOJC */
6220 #endif /* UNIX */
6221 printf("\n");
6222
6223 #ifndef NOTRIGGER
6224 printf(" %19s: %-13s\n","Trigger",
6225 tt_trigger[0] ? tt_trigger[0] : "(none)");
6226 #endif /* NOTRIGGER */
6227 printf("\n");
6228
6229 (VOID) shoesc(escape);
6230 #ifndef NOCSETS
6231 shotcs(tcsl,tcsr); /* Show terminal character sets */
6232 #endif /* NOCSETS */
6233
6234 #endif /* OS2 */
6235 }
6236
6237 VOID
shmdmlin()6238 shmdmlin() { /* Briefly show modem & line */
6239 #ifndef NODIAL
6240 #ifndef MINIDIAL
6241 #ifdef OLDTBCODE
6242 extern int tbmodel;
6243 _PROTOTYP( char * gtbmodel, (void) );
6244 #endif /* OLDTBCODE */
6245 #endif /* MINIDIAL */
6246 #endif /* NODIAL */
6247 if (local)
6248 #ifdef OS2
6249 printf(" Port: %s, Modem type: ",ttname);
6250 #else
6251 printf(" Line: %s, Modem type: ",ttname);
6252 #endif /* OS2 */
6253 else
6254 printf(
6255 #ifdef OS2
6256 " Communication device not yet selected with SET PORT\n Modem type: "
6257 #else
6258 " Communication device not yet selected with SET LINE\n Modem type: "
6259 #endif /* OS2 */
6260 );
6261 #ifndef NODIAL
6262 printf("%s",gmdmtyp());
6263 #ifndef MINIDIAL
6264 #ifdef OLDTBCODE
6265 if (tbmodel) printf(" (%s)",gtbmodel()); /* Telebit model info */
6266 #endif /* OLDTBCODE */
6267 #endif /* MINIDIAL */
6268 #else
6269 printf("(disabled)");
6270 #endif /* NODIAL */
6271 }
6272
6273 #ifdef CK_TAPI
6274 void
shotapi(int option)6275 shotapi(int option) {
6276 int rc=0,k ;
6277 char *s=NULL;
6278 LPDEVCFG lpDevCfg = NULL;
6279 LPCOMMCONFIG lpCommConfig = NULL;
6280 LPMODEMSETTINGS lpModemSettings = NULL;
6281 DCB * lpDCB = NULL;
6282 extern struct keytab * tapiloctab; /* Microsoft TAPI Locations */
6283 extern int ntapiloc;
6284 extern struct keytab * tapilinetab; /* Microsoft TAPI Line Devices */
6285 extern int ntapiline;
6286 extern int tttapi; /* TAPI in use */
6287 extern int tapipass; /* TAPI Passthrough mode */
6288 extern int tapiconv; /* TAPI Conversion mode */
6289 extern int tapilights;
6290 extern int tapipreterm;
6291 extern int tapipostterm;
6292 extern int tapimanual;
6293 extern int tapiinactivity;
6294 extern int tapibong;
6295 extern int tapiusecfg;
6296 extern char tapiloc[];
6297 extern int tapilocid;
6298 extern int TAPIAvail;
6299
6300 if (!TAPIAvail) {
6301 printf("TAPI Support not enabled\r\n");
6302 return;
6303 }
6304 switch (option) {
6305 case 0:
6306 printf("TAPI Settings:\n");
6307 printf(" Line: %s\n",
6308 tttapi ? ttname : "(none in use)");
6309
6310 cktapiBuildLocationTable(&tapiloctab, &ntapiloc);
6311 if (tapilocid == -1)
6312 tapilocid = cktapiGetCurrentLocationID();
6313
6314 /* Find the current tapiloc entry */
6315 /* and use it as the default. */
6316 for (k = 0; k < ntapiloc; k++) {
6317 if (tapiloctab[k].kwval == tapilocid)
6318 break;
6319 }
6320 if (k >= 0 && k < ntapiloc)
6321 s = tapiloctab[k].kwd;
6322 else
6323 s = "(unknown)";
6324 printf(" Location: %s\n",s);
6325 printf(" Modem-dialing: %s\n",tapipass?"off":"on");
6326 printf(" Phone-number-conversions: %s\n",
6327 tapiconv==CK_ON?"on":tapiconv==CK_AUTO?"auto":"off");
6328 printf(" Modem-lights: %s %s\n",tapilights?"on ":"off",
6329 tapipass?"(n/a)":"");
6330 printf(" Predial-terminal: %s %s\n",tapipreterm?"on ":"off",
6331 tapipass?"(n/a)":"");
6332 printf(" Postdial-terminal: %s %s\n",tapipostterm?"on ":"off",
6333 tapipass?"(n/a)":"");
6334 printf(" Manual-dial: %s %s\n",tapimanual?"on ":"off",
6335 tapipass?"(n/a)":"");
6336 printf(" Inactivity-timeout: %d seconds %s\n",tapiinactivity,
6337 tapipass?"(n/a)":"");
6338 printf(" Wait-for-bong: %d seconds %s\n",tapibong,
6339 tapipass?"(n/a)":"");
6340 printf(" Use-windows-configuration: %s %s\n",
6341 tapiusecfg?"on ":"off", tapipass?"(n/a)":"");
6342 printf("\n");
6343
6344 #ifdef BETATEST
6345 if (tapipass) {
6346 printf("K-95 uses the TAPI Line in an exclusive mode. Other applications\n");
6347 printf("may open the device but may not place calls nor answer calls.\n");
6348 printf("Dialing is performed using the K-95 dialing procedures. SET MODEM\n");
6349 printf("TYPE TAPI after the SET TAPI LINE command to activate the modem\n");
6350 printf("definition associated with the active TAPI LINE device.\n\n");
6351
6352 } else {
6353
6354 printf("K-95 uses the TAPI Line in a cooperative mode. Other applications\n");
6355 printf("may open the device, place and answer calls. Dialing is performed\n");
6356 printf("by TAPI. K-95 SET MODEM commands are not used.\n\n");
6357 }
6358
6359 if (tapiconv == CK_ON ||
6360 tapiconv == CK_AUTO && !tapipass) {
6361 printf(
6362 "Phone numbers are converted from canonical to dialable form by TAPI\n");
6363 printf("using the dialing rules specified in the TAPI Dialing Properties\n");
6364 printf("dialog.\n\n");
6365
6366 } else {
6367
6368 printf(
6369 "Phone numbers are converted from canonical to dialable form by K-95\n");
6370 printf(
6371 "using the dialing rules specified with the SET DIAL commands. TAPI\n");
6372 printf(
6373 "Dialing Properties are imported automaticly upon startup and whenever\n");
6374 printf("the TAPI Dialing Properties are altered or when the TAPI Location\n");
6375 printf("is changed.\n\n");
6376 }
6377 #endif /* BETATEST */
6378
6379 if (tapipass) {
6380 printf("Type SHOW MODEM to see MODEM configuration.\n");
6381 if (tapiconv == CK_ON)
6382 printf("Type SHOW DIAL to see DIAL-related items.\n");
6383 } else {
6384 if (tapiconv == CK_ON || tapiconv == CK_AUTO)
6385 printf("Type SHOW DIAL to see DIAL-related items.\n");
6386 }
6387 break;
6388 case 1:
6389 cktapiDisplayTapiLocationInfo();
6390 break;
6391 case 2:
6392 rc = cktapiGetModemSettings(&lpDevCfg,&lpModemSettings,
6393 &lpCommConfig,&lpDCB);
6394 if (rc) {
6395 cktapiDisplayModemSettings(lpDevCfg,lpModemSettings,
6396 lpCommConfig,lpDCB);
6397 } else {
6398 printf("?Unable to retrieve Modem Settings\n");
6399 }
6400 break;
6401 case 3: {
6402 HANDLE hModem = GetModemHandleFromLine((HLINE)0);
6403 if (hModem)
6404 DisplayCommProperties(hModem);
6405 else
6406 printf("?Unable to retrieve a valid Modem Handle\n");
6407 CloseHandle(hModem);
6408 break;
6409 }
6410 }
6411 printf("\n");
6412 }
6413 #endif /* CK_TAPI */
6414 #endif /* NOLOCAL */
6415
6416 #ifdef PATTERNS
6417 static VOID
shopat()6418 shopat() {
6419 extern char * binpatterns[], * txtpatterns[];
6420 extern int patterns, filepeek;
6421 char **p, *s;
6422 int i, j, k, n, flag, width;
6423 #ifdef CK_TTGWSIZ
6424 ttgwsiz(); /* Try to get latest size */
6425 #ifdef OS2
6426 width = tt_cols[VCMD];
6427 #else /* OS2 */
6428 width = tt_cols;
6429 #endif /* OS2 */
6430 if (width < 1)
6431 #endif /* CK_TTGWSIZ */
6432 width = 80;
6433 printf("\n");
6434 printf(" Set file type: %s\n",gfmode(binary,1));
6435 printf(" Set file patterns: %s", showooa(patterns));
6436 #ifdef CK_LABELED
6437 if (binary == XYFT_L)
6438 printf(" (but SET FILE TYPE LABELED overrides)\n");
6439 else
6440 #endif /* CK_LABELED */
6441 #ifdef VMS
6442 if (binary == XYFT_I)
6443 printf(" (but SET FILE TYPE IMAGE overrides)\n");
6444 else
6445 #endif /* VMS */
6446 if (filepeek)
6447 printf(" (but SET FILE SCAN ON overrides)\n");
6448 else
6449 printf("\n");
6450 printf(" Maximum patterns allowed: %d\n", FTPATTERNS);
6451 for (k = 0; k < 2; k++) { /* For each kind of patter */
6452 printf("\n");
6453 if (k == 0) { /* binary... */
6454 printf(" File binary-patterns: ");
6455 p = binpatterns;
6456 } else { /* text... */
6457 printf(" File text-patterns: ");
6458 p = txtpatterns;
6459 }
6460 if (!p[0]) {
6461 printf("(none)\n");
6462 } else {
6463 printf("\n ");
6464 n = 2;
6465 for (i = 0; i < FTPATTERNS; i++) { /* For each pattern */
6466 if (!p[i]) /* Done */
6467 break;
6468 s = p[i]; /* Look for embedded space */
6469 for (j = 0, flag = 1; *s; s++, j++) /* and also get length */
6470 if (*s == SP)
6471 flag = 3;
6472 n += j + flag; /* Length of this line */
6473 if (n >= width - 1) {
6474 printf("\n ");
6475 n = j+2;
6476 }
6477 printf(flag == 3 ? " {%s}" : " %s", p[i]);
6478 }
6479 if (n > 2)
6480 printf("\n");
6481 }
6482 }
6483 printf("\n");
6484 }
6485 #endif /* PATTERNS */
6486
6487 #ifndef NOSPL
6488 static VOID
shooutput()6489 shooutput() {
6490 printf(" Output pacing: %d (milliseconds)\n",pacing);
6491 printf(" Output special-escapes: %s\n", showoff(outesc));
6492 }
6493
6494 static VOID
shoinput()6495 shoinput() {
6496 #ifdef CKFLOAT
6497 extern char * inpscale;
6498 #endif /* CKFLOAT */
6499
6500 #ifdef CK_AUTODL
6501 printf(" Input autodownload: %s\n", showoff(inautodl));
6502 #endif /* CK_AUTODL */
6503 printf(" Input cancellation: %s\n", showoff(inintr));
6504 printf(" Input case: %s\n", inpcas[cmdlvl] ?
6505 "observe" : "ignore");
6506 printf(" Input buffer-length: %d\n", inbufsize);
6507 printf(" Input echo: %s\n", showoff(inecho));
6508 printf(" Input silence: %d (seconds)\n", insilence);
6509 #ifdef OS2
6510 printf(" Input terminal: %s\n", showoff(interm));
6511 #endif /* OS2 */
6512 printf(" Input timeout: %s\n", intime[cmdlvl] ?
6513 "quit" : "proceed");
6514 #ifdef CKFLOAT
6515 printf(" Input scale-factor: %s\n", inpscale ? inpscale : "1.0");
6516 #endif /* CKFLOAT */
6517
6518 if (instatus < 0)
6519 printf(" Last INPUT: -1 (INPUT command not yet given)\n");
6520 else
6521 printf(" Last INPUT: %d (%s)\n", instatus,i_text[instatus]);
6522 }
6523 #endif /* NOSPL */
6524
6525 #ifndef NOSPL
6526 int
showarray()6527 showarray() {
6528 #ifdef COMMENT
6529 char * p, * q, ** ap;
6530 int i;
6531 #endif /* COMMENT */
6532 char *s; int x = 0, y;
6533 int range[2];
6534
6535 if ((y = cmfld("Array name","",&s,NULL)) < 0)
6536 if (y != -3)
6537 return(y);
6538 ckstrncpy(line,s,LINBUFSIZ);
6539 s = line;
6540 if ((y = cmcfm()) < 0)
6541 return(y);
6542 if (*s) {
6543 char ** ap;
6544 if ((x = arraybounds(s,&(range[0]),&(range[1]))) < 0) {
6545 printf("?Bad array: %s\n",s);
6546 return(-9);
6547 }
6548 ap = a_ptr[x];
6549 if (!ap) {
6550 printf("Array not declared: %s\n", s);
6551 return(success = 1);
6552 } else {
6553 int i, n, max;
6554 max = (range[1] > 0) ?
6555 range[1] :
6556 ((range[0] > 0) ? range[0] : a_dim[x]);
6557 if (range[0] < 0)
6558 range[0] = 0;
6559 if (max > a_dim[x])
6560 max = a_dim[x];
6561 n = 1;
6562 printf("\\&%c[]: Dimension = %d",arrayitoa(x),a_dim[x]);
6563 if (a_link[x] > -1)
6564 printf(" (Link to \\&%c[])",arrayitoa(a_link[x]));
6565 printf("\n");
6566 for (i = range[0]; i <= max; i++) {
6567 if (ap[i]) {
6568 printf("%3d. %s\n",i,ap[i]);
6569 if (xaskmore) {
6570 if (cmd_cols > 0) {
6571 x = strlen(ap[i]) + 5;
6572 y = (x % cmd_cols) ? 1 : 0;
6573 n += (x / cmd_cols) + y;
6574 } else {
6575 n++;
6576 }
6577 if (n > (cmd_rows - 3)) {
6578 if (!askmore())
6579 break;
6580 else
6581 n = 0;
6582 }
6583 }
6584 }
6585 }
6586 }
6587 return(1);
6588 }
6589
6590 /* All arrays - just show name and dimension */
6591
6592 for (y = 0; y < (int) 'z' - ARRAYBASE + 1; y++) {
6593 if (a_ptr[y]) {
6594 if (x == 0) printf("Declared arrays:\n");
6595 x = 1;
6596 printf(" \\&%c[%d]",
6597 (y == 1) ? 64 : y + ARRAYBASE, a_dim[y]);
6598 if (a_link[y] > -1)
6599 printf(" => \\&%c[]",arrayitoa(a_link[y]));
6600 printf("\n");
6601 }
6602 if (!x) printf(" No arrays declared\n");
6603 }
6604 return(1);
6605 }
6606 #endif /* NOSPL */
6607
6608 int
doshow(x)6609 doshow(x) int x; {
6610 int y, z, i; long zz;
6611 extern int optlines;
6612 char *s;
6613 #ifdef OS2
6614 extern int os2gks;
6615 extern int tt_kb_mode;
6616 #endif /* OS2 */
6617 extern int srvcdmsg;
6618 extern char * cdmsgstr, * ckcdpath;
6619 char fnbuf[100];
6620
6621 #ifndef NOSETKEY
6622 if (x == SHKEY) { /* SHOW KEY */
6623 int c;
6624 #ifdef OS2
6625 if ((x = cmkey(shokeytab,nshokey,"How many keys should be shown?",
6626 "one",xxstring)) < 0) return(x);
6627 switch (tt_kb_mode) {
6628 case KBM_EM:
6629 s = "emacs";
6630 break;
6631 case KBM_HE:
6632 s = "hebrew";
6633 break;
6634 case KBM_RU:
6635 s = "russian";
6636 break;
6637 case KBM_EN:
6638 default:
6639 s = "default";
6640 break;
6641 }
6642 if ((z = cmkey(shokeymtab,nshokeym,"Which definition should be shown?",
6643 s,xxstring)) < 0) return(z);
6644 if (z == SHKEYDEF)
6645 z = -1;
6646 #endif /* OS2 */
6647
6648 if ((y = cmcfm()) < 0) return(y);
6649
6650 #ifdef IKSD
6651 if (inserver) {
6652 printf("Sorry, command disabled.\r\n");
6653 return(success = 0);
6654 }
6655 #endif /* IKSD */
6656
6657 #ifdef MAC
6658 printf("Not implemented\n");
6659 return(0);
6660 #else /* Not MAC */
6661 #ifdef OS2
6662 if (x) {
6663 con_event evt;
6664 for (c = 0; c < KMSIZE; c++) {
6665 evt = (z < 0) ? mapkey(c) : maptermkey(c,z);
6666 if (evt.type != error) {
6667 shokeycode(c,z);
6668 }
6669 }
6670 } else {
6671 #endif /* OS2 */
6672 printf(" Press key: ");
6673 #ifdef UNIX
6674 #ifdef NOSETBUF
6675 fflush(stdout);
6676 #endif /* NOSETBUF */
6677 #endif /* UNIX */
6678 conbin((char)escape); /* Put terminal in binary mode */
6679 #ifdef OS2
6680 os2gks = 0; /* Raw scancode processing */
6681 #endif /* OS2 */
6682 c = congks(0); /* Get character or scan code */
6683 #ifdef OS2
6684 os2gks = 1; /* Cooked scancode processing */
6685 #endif /* OS2 */
6686 concb((char)escape); /* Restore terminal to cbreak mode */
6687 if (c < 0) { /* Check for error */
6688 printf("?Error reading key\n");
6689 return(0);
6690 }
6691 #ifndef OS2
6692 /*
6693 Do NOT mask when it can be a raw scan code, perhaps > 255
6694 */
6695 c &= cmdmsk; /* Apply command mask */
6696 #endif /* OS2 */
6697 printf("\n");
6698 #ifdef OS2
6699 shokeycode(c,z);
6700 #else /* OS2 */
6701 shokeycode(c);
6702 #endif /* OS2 */
6703 #ifdef OS2
6704 }
6705 #endif /* OS2 */
6706 return(1);
6707 #endif /* MAC */
6708 }
6709 #ifndef NOKVERBS
6710 if (x == SHKVB) { /* SHOW KVERBS */
6711 if ((y = cmcfm()) < 0) return(y);
6712 #ifdef IKSD
6713 if (inserver) {
6714 printf("Sorry, command disabled.\r\n");
6715 return(success = 0);
6716 }
6717 #endif /* IKSD */
6718 printf("\nThe following %d keyboard verbs are available:\n\n",nkverbs);
6719 kwdhelp(kverbs,nkverbs,"","\\K","",3,0);
6720 printf("\n");
6721 return(1);
6722 }
6723 #ifdef OS2
6724 if (x == SHUDK) { /* SHOW UDKs */
6725 extern void showudk(void);
6726 if ((y = cmcfm()) < 0) return(y);
6727 #ifdef IKSD
6728 if (inserver) {
6729 printf("Sorry, command disabled.\r\n");
6730 return(success = 0);
6731 }
6732 #endif /* IKSD */
6733 showudk();
6734 return(1);
6735 }
6736 #endif /* OS2 */
6737 #endif /* NOKVERBS */
6738 #endif /* NOSETKEY */
6739
6740 #ifndef NOSPL
6741 if (x == SHMAC) { /* SHOW MACRO */
6742 struct FDB kw, fl, cm;
6743 int i, k, n = 0, left, flag, confirmed = 0;
6744 char * p, *q[64];
6745 for (i = 0; i < nmac; i++) { /* copy the macro table */
6746 mackey[i].kwd = mactab[i].kwd; /* into a regular keyword table */
6747 mackey[i].kwval = i; /* with value = pointer to macro tbl */
6748 mackey[i].flgs = mactab[i].flgs;
6749 }
6750 p = line;
6751 left = LINBUFSIZ;
6752 while (!confirmed && n < 64) {
6753 cmfdbi(&kw, /* First FDB - macro table */
6754 _CMKEY, /* fcode */
6755 "Macro name", /* hlpmsg */
6756 "", /* default */
6757 "", /* addtl string data */
6758 nmac, /* addtl numeric data 1: tbl size */
6759 0, /* addtl numeric data 2: 4 = cmswi */
6760 xxstring, /* Processing function */
6761 mackey, /* Keyword table */
6762 &fl /* Pointer to next FDB */
6763 );
6764 cmfdbi(&fl, /* 2nd FDB - something not in mactab */
6765 _CMFLD, /* fcode */
6766 "", /* hlpmsg */
6767 "", /* default */
6768 "", /* addtl string data */
6769 0, /* addtl numeric data 1 */
6770 0, /* addtl numeric data 2 */
6771 xxstring,
6772 NULL,
6773 &cm
6774 );
6775 cmfdbi(&cm, /* 3rd FDB - Confirmation */
6776 _CMCFM, /* fcode */
6777 "", /* hlpmsg */
6778 "", /* default */
6779 "", /* addtl string data */
6780 0, /* addtl numeric data 1 */
6781 0, /* addtl numeric data 2 */
6782 NULL,
6783 NULL,
6784 NULL
6785 );
6786 x = cmfdb(&kw); /* Parse something */
6787 if (x < 0)
6788 return(x);
6789 s = atmbuf; /* What the user typed */
6790 switch (cmresult.fcode) {
6791 case _CMKEY: /* If it was a keyword */
6792 y = mlook(mactab,atmbuf,nmac); /* get full name */
6793 if (y > -1)
6794 s = mactab[y].kwd; /* (fall thru on purpose...) */
6795 case _CMFLD:
6796 k = ckstrncpy(p,s,left) + 1; /* Copy result to list */
6797 left -= k;
6798 if (left <= 0) {
6799 *p = NUL;
6800 break;
6801 }
6802 q[n++] = p; /* Point to this item */
6803 p += k; /* Move buffer pointer past it */
6804 break;
6805 case _CMCFM: /* End of command */
6806 confirmed++;
6807 default:
6808 break;
6809 }
6810 }
6811 if (n == 0) {
6812 printf("Macros:\n");
6813 slc = 1;
6814 for (y = 0; y < nmac; y++)
6815 if (shomac(mactab[y].kwd,mactab[y].mval) < 0) break;
6816 return(1);
6817 }
6818 slc = 0;
6819 for (i = 0; i < n; i++) {
6820 flag = 0;
6821 s = q[i];
6822 if (!s) s = "";
6823 if (!*s) continue;
6824 if (iswild(s)) { /* Pattern match */
6825 for (k = 0, x = 0; x < nmac; x++) {
6826 if (ckmatch(s,mactab[x].kwd,0,1)) {
6827 shomac(mactab[x].kwd,mactab[x].mval);
6828 k++;
6829 }
6830 }
6831 if (!k)
6832 x = -1;
6833 else
6834 continue;
6835 } else { /* Exact match */
6836 x = mxlook(mactab,s,nmac);
6837 flag = 1;
6838 }
6839 if (flag && x == -1)
6840 x = mlook(mactab,s,nmac);
6841 switch (x) {
6842 case -3: /* Nothing to look up */
6843 case -1: /* Not found */
6844 printf("%s - (not defined)\n",s);
6845 break;
6846 case -2: /* Ambiguous, matches more than one */
6847 printf("%s - ambiguous\n",s);
6848 break;
6849 default: /* Matches one exactly */
6850 shomac(mactab[x].kwd,mactab[x].mval);
6851 break;
6852 }
6853 }
6854 return(1);
6855 }
6856 #endif /* NOSPL */
6857
6858 /*
6859 Other SHOW commands only have two fields. Get command confirmation here,
6860 then handle with big switch() statement.
6861 */
6862 #ifndef NOSPL
6863 if (x != SHBUI && x != SHARR)
6864 #endif /* NOSPL */
6865 if (x == SHFUN) { /* For SHOW FUNCTIONS */
6866 int y;
6867 if ((y = cmtxt("Match string for function names","",&s,NULL)) < 0)
6868 return(y);
6869 fnbuf[0] = NUL;
6870 if (!s) s = "";
6871 if (*s) ckstrncpy(fnbuf,s,100);
6872 } else {
6873 if ((y = cmcfm()) < 0)
6874 return(y);
6875 }
6876 #ifdef COMMENT
6877 /* This restriction is too general. */
6878 #ifdef IKSD
6879 if (inserver &&
6880 #ifdef CK_LOGIN
6881 isguest
6882 #else
6883 0
6884 #endif /* CK_LOGIN */
6885 ) {
6886 printf("Sorry, command disabled.\r\n");
6887 return(success = 0);
6888 }
6889 #endif /* IKSD */
6890 #endif /* COMMENT */
6891
6892 switch (x) {
6893
6894 #ifdef ANYX25
6895 #ifndef IBMX25
6896 case SHPAD:
6897 shopad(0);
6898 break;
6899 #endif /* IBMX25 */
6900 #endif /* ANYX25 */
6901
6902 case SHNET:
6903 #ifdef NOLOCAL
6904 printf(" No network support in this version of C-Kermit.\n");
6905 #else
6906 #ifndef NETCONN
6907 printf(" No network support in this version of C-Kermit.\n");
6908 #else
6909 shonet();
6910 #endif /* NETCONN */
6911 #endif /* NOLOCAL */
6912 break;
6913
6914 case SHPAR:
6915 shopar();
6916 break;
6917
6918 #ifndef NOXFER
6919 case SHATT:
6920 shoatt();
6921 break;
6922 #endif /* NOXFER */
6923
6924 #ifndef NOSPL
6925 case SHCOU:
6926 printf(" %d\n",count[cmdlvl]);
6927 break;
6928 #endif /* NOSPL */
6929
6930 #ifndef NOSERVER
6931 case SHSER: /* Show Server */
6932 i = 0;
6933 #ifndef NOFRILLS
6934 printf("Function: Status:\n");
6935 i++;
6936 printf(" GET %s\n",nm[en_get]);
6937 i++;
6938 printf(" SEND %s\n",nm[en_sen]);
6939 i++;
6940 printf(" MAIL %s\n",nm[inserver ? 0 : en_mai]);
6941 i++;
6942 printf(" PRINT %s\n",nm[inserver ? 0 : en_pri]);
6943 i++;
6944 #ifndef NOSPL
6945 printf(" REMOTE ASSIGN %s\n",nm[en_asg]);
6946 i++;
6947 #endif /* NOSPL */
6948 printf(" REMOTE CD/CWD %s\n",nm[en_cwd]);
6949 i++;
6950 #ifdef ZCOPY
6951 printf(" REMOTE COPY %s\n",nm[en_cpy]);
6952 i++;
6953 #endif /* ZCOPY */
6954 printf(" REMOTE DELETE %s\n",nm[en_del]);
6955 printf(" REMOTE DIRECTORY %s\n",nm[en_dir]);
6956 printf(" REMOTE HOST %s\n",nm[inserver ? 0 : en_hos]);
6957 i += 3;
6958 #ifndef NOSPL
6959 printf(" REMOTE QUERY %s\n",nm[en_que]);
6960 i++;
6961 #endif /* NOSPL */
6962 printf(" REMOTE MKDIR %s\n",nm[en_mkd]);
6963 printf(" REMOTE RMDIR %s\n",nm[en_rmd]);
6964 printf(" REMOTE RENAME %s\n",nm[en_ren]);
6965 printf(" REMOTE SET %s\n",nm[en_set]);
6966 printf(" REMOTE SPACE %s\n",nm[en_spa]);
6967 printf(" REMOTE TYPE %s\n",nm[en_typ]);
6968 printf(" REMOTE WHO %s\n",nm[inserver ? 0 : en_who]);
6969 printf(" BYE %s\n",nm[en_bye]);
6970 printf(" FINISH %s\n",nm[en_fin]);
6971 printf(" EXIT %s\n",nm[en_xit]);
6972 printf(" ENABLE %s\n",nm[en_ena]);
6973 i += 11;
6974 #endif /* NOFRILLS */
6975 if (i > cmd_rows - 3) { if (!askmore()) return(1); else i = 0; }
6976 printf("Server timeout: %d\n",srvtim);
6977 if (++i > cmd_rows - 3) { if (!askmore()) return(1); else i = 0; }
6978 printf("Server idle-timeout: %d\n",srvidl);
6979 if (++i > cmd_rows - 3) { if (!askmore()) return(1); else i = 0; }
6980 printf("Server keepalive %s\n", showoff(srvping));
6981 if (++i > cmd_rows - 3) { if (!askmore()) return(1); else i = 0; }
6982 printf("Server cd-message %s\n", showoff(srvcdmsg));
6983 if (srvcdmsg && cdmsgstr)
6984 printf("Server cd-message %s\n", cdmsgstr);
6985 if (++i > cmd_rows - 3) { if (!askmore()) return(1); else i = 0; }
6986 printf("Server display: %s\n", showoff(srvdis));
6987 if (++i > cmd_rows - 3) { if (!askmore()) return(1); else i = 0; }
6988 printf("Server login: ");
6989 if (!x_user) {
6990 printf("(none)\n");
6991 } else {
6992 printf("\"%s\", \"%s\", \"%s\"\n",
6993 x_user,
6994 x_passwd ? x_passwd : "",
6995 x_acct ? x_acct : ""
6996 );
6997 }
6998 if (++i > cmd_rows - 3) { if (!askmore()) return(1); else i = 0; }
6999 printf("Server get-path: ");
7000 if (ngetpath == 0) {
7001 printf(" (none)\n");
7002 } else {
7003 printf("\n");
7004 i += 3;
7005 for (x = 0; x < ngetpath; x++) {
7006 if (getpath[x]) printf(" %d. %s\n", x, getpath[x]);
7007 if (++i > (cmd_rows - 3)) { /* More than a screenful... */
7008 if (!askmore())
7009 break;
7010 else
7011 i = 0;
7012 }
7013 }
7014 }
7015 break;
7016 #endif /* NOSERVER */
7017
7018 case SHSTA: /* Status of last command */
7019 printf(" %s\n", success ? "SUCCESS" : "FAILURE");
7020 return(0); /* Don't change it */
7021
7022 case SHSTK: { /* Stack for MAC debugging */
7023 #ifdef MAC
7024 long sp;
7025 sp = -1;
7026 loadA0 ((char *)&sp); /* set destination address */
7027 SPtoaA0(); /* move SP to destination */
7028 printf("Stack at 0x%x\n", sp);
7029 show_queue(); /* more debugging */
7030 break;
7031 #else
7032 shostack();
7033 #endif /* MAC */
7034 break;
7035 }
7036
7037
7038 #ifndef NOLOCAL
7039 #ifdef OS2
7040 case SHTAB: /* SHOW TABS */
7041 #ifdef IKSD
7042 if (inserver) {
7043 printf("Sorry, command disabled.\r\n");
7044 return(success = 0);
7045 }
7046 #endif /* IKSD */
7047 shotabs();
7048 break;
7049 #endif /* OS2 */
7050
7051 case SHTER: /* SHOW TERMINAL */
7052 #ifdef IKSD
7053 if (inserver) {
7054 printf("Sorry, command disabled.\r\n");
7055 return(success = 0);
7056 }
7057 #endif /* IKSD */
7058 shotrm();
7059 break;
7060
7061 #ifdef OS2
7062 case SHVSCRN: /* SHOW Virtual Screen - for debug */
7063 shovscrn();
7064 break;
7065 #endif /* OS2 */
7066 #endif /* NOLOCAL */
7067
7068 #ifdef OS2MOUSE
7069 case SHMOU: /* SHOW MOUSE */
7070 #ifdef IKSD
7071 if (inserver) {
7072 printf("Sorry, command disabled.\r\n");
7073 return(success = 0);
7074 }
7075 #endif /* IKSD */
7076 shomou();
7077 break;
7078 #endif /* OS2MOUSE */
7079
7080 #ifndef NOFRILLS
7081 case SHVER:
7082 shover();
7083 break;
7084 #endif /* NOFRILLS */
7085
7086 #ifndef NOSPL
7087 case SHBUI: /* Built-in variables */
7088 line[0] = NUL;
7089 if ((y = cmtxt("Variable name or pattern","",&s,xxstring)) < 0)
7090 return(y);
7091 ckstrncpy(line,s,LINBUFSIZ);
7092 /* if (line[0]) ckstrncat(line,"*",LINBUFSIZ); */
7093
7094 case SHFUN: /* or built-in functions */
7095 #ifdef CK_TTGWSIZ
7096 #ifdef OS2
7097 if (tt_cols[VTERM] < 0 || tt_rows[VTERM] < 0)
7098 ttgwsiz();
7099 #else /* OS2 */
7100 if (ttgwsiz() > 0) { /* Get current screen size */
7101 if (tt_rows > 0 && tt_cols > 0) {
7102 cmd_rows = tt_rows;
7103 cmd_cols = tt_cols;
7104 }
7105 }
7106 #endif /* OS2 */
7107 #endif /* CK_TTGWSIZ */
7108
7109 if (x == SHFUN) { /* Functions */
7110 printf("\nThe following functions are available:\n\n");
7111 kwdhelp(fnctab,nfuncs,(char *)fnbuf,"\\F","()",3,8);
7112 printf("\n");
7113 #ifndef NOHELP
7114 printf(
7115 "HELP FUNCTION <name> gives the calling conventions of the given function.\n\n"
7116 );
7117 #endif /* NOHELP */
7118 break;
7119 } else { /* Variables */
7120 int j, flag = 0, havearg = 0;
7121 struct stringarray * q = NULL;
7122 char ** pp;
7123 if (line[0]) { /* Have something to search for */
7124 havearg = 1; /* Maybe a list of things */
7125 q = cksplit(1,0,line,NULL,"_-^$*?[]{}",0,0,0,0);
7126 if (!q) break;
7127 pp = q->a_head;
7128 }
7129 i = 0;
7130 for (y = 0; y < nvars; y++) {
7131 if ((vartab[y].flgs & CM_INV))
7132 continue;
7133 if (havearg) { /* If I have something to match */
7134 char * s2;
7135 for (flag = 0, j = 1; j <= q->a_size && !flag; j++) {
7136 s2 = pp[j] ? pp[j] : "";
7137 #ifdef COMMENT
7138 /* This is not needed because it's what the 4 arg does in ckmatch() */
7139 len = strlen(s2);
7140 if (len > 0) {
7141 if (s2[len-1] != '$') {/* To allow anchors */
7142 ckmakmsg(line,LINBUFSIZ,pp[j],"*",NULL,NULL);
7143 s2 = line;
7144 }
7145 }
7146 #endif /* COMMENT */
7147 if (ckmatch(s2,vartab[y].kwd,0,4) > 0) {
7148 flag = 1; /* Matches */
7149 break;
7150 }
7151 }
7152 if (!flag) /* Doesn't match */
7153 continue;
7154 }
7155 s = nvlook(vartab[y].kwd);
7156 printf(" \\v(%s) = ",vartab[y].kwd);
7157 if (vartab[y].kwval == VN_NEWL) { /* \v(newline) */
7158 while (*s) /* Show control chars symbolically */
7159 printf("\\{%d}",*s++);
7160 printf("\n");
7161 } else if (vartab[y].kwval == VN_IBUF || /* \v(input) */
7162 vartab[y].kwval == VN_QUE || /* \v(query) */
7163 #ifdef OS2
7164 vartab[y].kwval == VN_SELCT || /* \v(select) */
7165 #endif /* OS2 */
7166 (vartab[y].kwval >= VN_M_AAA && /* modem ones */
7167 vartab[y].kwval <= VN_M_ZZZ)
7168 ) {
7169 int r = 12; /* This one can wrap around */
7170 char buf[10];
7171 while (*s) {
7172 if (isprint(*s)) {
7173 buf[0] = *s;
7174 buf[1] = NUL;
7175 r++;
7176 } else {
7177 sprintf(buf,"\\{%d}",*s); /* SAFE */
7178 r += (int) strlen(buf);
7179 }
7180 if (r >= cmd_cols - 1) {
7181 printf("\n");
7182 r = 0;
7183 i++;
7184 }
7185 printf("%s",buf);
7186 s++;
7187 }
7188 printf("\n");
7189 } else
7190 printf("%s\n",s);
7191 if (++i > (cmd_rows - 3)) { /* More than a screenful... */
7192 if ((y >= nvars - 1) || !askmore())
7193 break;
7194 else
7195 i = 0;
7196 }
7197 }
7198 }
7199 break;
7200
7201 case SHVAR: /* Global variables */
7202 x = 0; /* Variable count */
7203 slc = 1; /* Screen line count for "more?" */
7204 for (y = 33; y < GVARS; y++)
7205 if (g_var[y]) {
7206 if (x++ == 0) printf("Global variables:\n");
7207 sprintf(line," \\%%%c",y); /* SAFE */
7208 if (shomac(line,g_var[y]) < 0) break;
7209 }
7210 if (!x) printf(" No variables defined\n");
7211 break;
7212
7213 case SHARG: { /* Args */
7214 char * s, * s1, * s2, * tmpbufp;
7215 int t;
7216 if (maclvl > -1) {
7217 printf("Macro arguments at level %d (\\v(argc) = %d):\n",
7218 maclvl,
7219 macargc[maclvl]
7220 );
7221 for (y = 0; y < macargc[maclvl]; y++) {
7222 s1 = m_arg[maclvl][y];
7223 if (!s1) s1 = "(NULL)";
7224 s2 = m_xarg[maclvl][y];
7225 if (!s2) s2 = "(NULL)";
7226 #ifdef COMMENT
7227 if (y < 10)
7228 printf(" \\%%%d = %s\n",y,s1);
7229 else
7230 printf(" \\&_[%d] = %s\n",y,s2);
7231 #else
7232 printf(" \\&_[%d] = %s\n",y,s2);
7233 #endif /* COMMENT */
7234 }
7235 } else {
7236 printf("Top-level arguments (\\v(argc) = %d):\n", topargc);
7237 for (y = 0; y < topargc; y++) {
7238 s1 = g_var[y + '0'];
7239 if (!s1) s1 = "(NULL)";
7240 s2 = toparg[y];
7241 if (!s2) s2 = "(NULL)";
7242 if (y < 10 && g_var[y])
7243 printf(" \\%%%d = %s\n",y,s1);
7244 if (toparg[y])
7245 printf(" \\&_[%d] = %s\n",y,s2);
7246 }
7247 }
7248 }
7249 break;
7250
7251 case SHARR: /* Arrays */
7252 return(showarray());
7253 #endif /* NOSPL */
7254
7255 #ifndef NOXFER
7256 case SHPRO: /* Protocol parameters */
7257 shoparp();
7258 printf("\n");
7259 break;
7260 #endif /* NOXFER */
7261
7262 #ifndef NOLOCAL
7263 case SHCOM: /* Communication parameters */
7264 printf("\n");
7265 shoparc();
7266 #ifdef OS2
7267 {
7268 int i;
7269 char *s = "(unknown)";
7270 for (i = 0; i < nprty; i++)
7271 if (prtytab[i].kwval == priority) {
7272 s = prtytab[i].kwd;
7273 break;
7274 }
7275 printf(" Priority: %s\n", s );
7276 }
7277 #endif /* OS2 */
7278
7279 printf("\n");
7280 #ifdef NETCONN
7281 if (!network
7282 #ifdef IKSD
7283 && !inserver
7284 #endif /* IKSD */
7285 ) {
7286 #endif /* NETCONN */
7287 shomdm();
7288 printf("\n");
7289 #ifdef NETCONN
7290 }
7291 #endif /* NETCONN */
7292
7293 #ifndef NODIAL
7294 #ifdef IKSD
7295 if ( !inserver )
7296 #endif /* IKSD */
7297 {
7298 printf("Type SHOW DIAL to see DIAL-related items.\n");
7299 printf("Type SHOW MODEM to see modem-related items.\n");
7300 #ifdef CK_TAPI
7301 printf("Type SHOW TAPI to see TAPI-related items.\n");
7302 #endif /* CK_TAPI */
7303 printf("\n");
7304 }
7305 #endif /* NODIAL */
7306 break;
7307 #endif /* NOLOCAL */
7308
7309 case SHFIL: /* File parameters */
7310 shofil();
7311 /* printf("\n"); */ /* (out o' space) */
7312 break;
7313
7314 #ifndef NOCSETS
7315 case SHLNG: /* Languages */
7316 shoparl();
7317 break;
7318 #endif /* NOCSETS */
7319
7320 #ifndef NOSPL
7321 case SHSCR: /* Scripts */
7322 printf(" Command quoting: %s\n", showoff(cmdgquo()));
7323 printf(" Take echo: %s\n", showoff(techo));
7324 printf(" Take error: %s\n", showoff(takerr[cmdlvl]));
7325 printf(" Macro echo: %s\n", showoff(mecho));
7326 printf(" Macro error: %s\n", showoff(merror[cmdlvl]));
7327 printf(" Quiet: %s\n", showoff(quiet));
7328 printf(" Variable evaluation: %s [\\%%x and \\&x[] variables]\n",
7329 vareval ? "recursive" : "simple");
7330 printf(" Function diagnostics: %s\n", showoff(fndiags));
7331 printf(" Function error: %s\n", showoff(fnerror));
7332 #ifdef CKLEARN
7333 {
7334 extern char * learnfile;
7335 extern int learning;
7336 if (learnfile) {
7337 printf(" LEARN file: %s (%s)\n",
7338 learnfile,
7339 learning ? "ON" : "OFF"
7340 );
7341 } else
7342 printf(" LEARN file: (none)\n");
7343 }
7344 #endif /* CKLEARN */
7345 shoinput();
7346 shooutput();
7347 #ifndef NOSCRIPT
7348 printf(" Script echo: %s\n", showoff(secho));
7349 #endif /* NOSCRIPT */
7350 printf(" Command buffer length: %d\n", CMDBL);
7351 printf(" Atom buffer length: %d\n", ATMBL);
7352 break;
7353 #endif /* NOSPL */
7354
7355 #ifndef NOXMIT
7356 case SHXMI:
7357 printf("\n");
7358 printf(" File type: %s\n",
7359 binary ? "binary" : "text");
7360 #ifndef NOCSETS
7361 printf(" File character-set: %s\n",
7362 fcsinfo[fcharset].keyword);
7363 #ifdef OS2
7364 if ( isunicode() ) {
7365 printf(" Terminal Character (remote): %s\n",
7366 tt_utf8 ? "utf-8" : tcsr == TX_TRANSP ? "transparent" :
7367 tcsr == TX_UNDEF ? "undefined" : txrinfo[tcsr]->keywd);
7368 printf(" Terminal Character (local): %s\n",
7369 tcsl == TX_TRANSP ? "transparent" :
7370 tcsl == TX_UNDEF ? "undefined" : txrinfo[tcsl]->keywd);
7371 } else {
7372 printf(" Terminal Character (remote): %s\n",
7373 tt_utf8 ? "utf-8" : tcsr == TX_TRANSP ? "transparent" :
7374 tcsr == TX_UNDEF ? "undefined" : txrinfo[tcsr]->keywd);
7375 printf(" Terminal Character (local): %s\n",
7376 tcsl == TX_TRANSP ? "transparent" :
7377 tcsl == TX_UNDEF ? "undefined" : txrinfo[tcsl]->keywd);
7378 }
7379 #else /* OS2 */
7380 printf(" Terminal character-set (remote): %s\n",
7381 fcsinfo[tcsr].keyword);
7382 printf(" Terminal character-set (local): %s\n",
7383 fcsinfo[tcsl].keyword);
7384 #endif /* OS2 */
7385 #endif /* NOCSETS */
7386 printf(" Terminal bytesize: %d\n",
7387 (cmask == 0xff) ? 8 : 7);
7388 printf(" Terminal echo: %s\n",
7389 duplex ? "local" : "remote");
7390 printf(" Transmit EOF: ");
7391 if (*xmitbuf == NUL) {
7392 printf("(none)\n");
7393 } else {
7394 char *p;
7395 p = xmitbuf;
7396 while (*p) {
7397 if (*p < SP)
7398 printf("^%c",ctl(*p));
7399 else
7400 printf("%c",*p);
7401 p++;
7402 }
7403 printf("\n");
7404 }
7405 if (xmitf)
7406 printf(" Transmit Fill: %d\n", xmitf);
7407 else
7408 printf(" Transmit Fill: (none)\n");
7409 printf(" Transmit Linefeed: %s\n",showoff(xmitl));
7410 if (xmitp)
7411 printf(" Transmit Prompt: %d (%s)\n",
7412 xmitp,
7413 chartostr(xmitp)
7414 );
7415 else
7416 printf(" Transmit Prompt: (none)\n");
7417 printf(" Transmit Echo: %s\n", showoff(xmitx));
7418 printf(" Transmit Locking-Shift: %s\n", showoff(xmits));
7419 printf(" Transmit Pause: %d (millisecond%s)\n",
7420 xmitw,
7421 (xmitw == 1) ? "" : "s"
7422 );
7423 printf(" Transmit Timeout: %d (second%s)\n",
7424 xmitt,
7425 (xmitt == 1) ? "" : "s"
7426 );
7427 printf("\n");
7428 break;
7429 #endif /* NOXMIT */
7430
7431 #ifndef NODIAL
7432 case SHMOD: /* SHOW MODEM */
7433 #ifdef IKSD
7434 if (inserver) {
7435 printf("Sorry, command disabled.\r\n");
7436 return(success = 0);
7437 }
7438 #endif /* IKSD */
7439 shomodem(); /* Show SET MODEM items */
7440 break;
7441 #endif /* NODIAL */
7442
7443 #ifndef MAC
7444 case SHDFLT:
7445 printf("%s\n",zgtdir());
7446 break;
7447 #endif /* MAC */
7448
7449 #ifndef NOLOCAL
7450 case SHESC:
7451 #ifdef IKSD
7452 if (inserver) {
7453 printf("Sorry, command disabled.\r\n");
7454 return(success = 0);
7455 }
7456 #endif /* IKSD */
7457 return(shoesc(escape));
7458
7459 #ifndef NODIAL
7460 case SHDIA: /* SHOW DIAL */
7461 #ifdef IKSD
7462 if (inserver) {
7463 printf("Sorry, command disabled.\r\n");
7464 return(success = 0);
7465 }
7466 #endif /* IKSD */
7467 shmdmlin();
7468 printf(", speed: ");
7469 if ((zz = ttgspd()) < 0) {
7470 printf("unknown");
7471 } else {
7472 if (zz == 8880) printf("75/1200"); else printf("%ld",zz);
7473 }
7474 if (carrier == CAR_OFF) s = "off";
7475 else if (carrier == CAR_ON) s = "on";
7476 else if (carrier == CAR_AUT) s = "auto";
7477 else s = "unknown";
7478 printf(", carrier: %s", s);
7479 if (carrier == CAR_ON) {
7480 if (cdtimo) printf(", timeout: %d sec", cdtimo);
7481 else printf(", timeout: none");
7482 }
7483 printf("\n");
7484 doshodial();
7485 if (local
7486 #ifdef NETCONN
7487 && !network
7488 #endif /* NETCONN */
7489 ) {
7490 printf("Type SHOW MODEM to see modem settings.\n");
7491 #ifdef CK_TAPI
7492 printf("Type SHOW TAPI to see TAPI-related items\n");
7493 #endif /* CK_TAPI */
7494 printf("Type SHOW COMMUNICATIONS to see modem signals.\n");
7495 }
7496 break;
7497 #endif /* NODIAL */
7498 #endif /* NOLOCAL */
7499
7500 #ifndef NOXFER
7501 #ifdef CK_LABELED
7502 case SHLBL: /* Labeled file info */
7503 sholbl();
7504 break;
7505 #endif /* CK_LABELED */
7506 #endif /* NOXFER */
7507
7508 case SHCSE: /* Character sets */
7509 #ifdef NOCSETS
7510 printf(
7511 " Character set translation is not supported in this version of C-Kermit\n");
7512 #else
7513 shocharset();
7514 #ifndef NOXFER
7515 printf("\n Unknown-Char-Set: %s\n",
7516 unkcs ? "Keep" : "Discard");
7517 #endif /* NOXFER */
7518 #ifdef OS2
7519 printf("\n");
7520 #endif /* OS2 */
7521 shotcs(tcsl,tcsr);
7522 printf("\n");
7523 #ifdef OS2
7524 /* PC Code Page information */
7525 {
7526 char cpbuf[128];
7527 int cplist[16], cps;
7528 int activecp;
7529 cps = os2getcplist(cplist, sizeof(cplist));
7530
7531 sprintf(cpbuf, /* SAFE */
7532 "%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d",
7533 cps > 1 ? cplist[1] : 0,
7534 cps > 2 ? cplist[2] : 0, cps > 3 ? cplist[3] : 0,
7535 cps > 4 ? cplist[4] : 0, cps > 5 ? cplist[5] : 0,
7536 cps > 6 ? cplist[6] : 0, cps > 7 ? cplist[7] : 0,
7537 cps > 8 ? cplist[8] : 0, cps > 9 ? cplist[9] : 0,
7538 cps > 10 ? cplist[10] : 0, cps > 11 ? cplist[11] : 0,
7539 cps > 12 ? cplist[12] : 0
7540 );
7541 printf(" Code Pages:\n");
7542 activecp = os2getcp();
7543 if ( activecp ) {
7544 printf(" Active: %d\n",activecp);
7545 if (!isWin95())
7546 printf(" Available: %s\n",cpbuf);
7547 } else
7548 printf(" Active: n/a\n");
7549 printf("\n");
7550 }
7551 #endif /* OS2 */
7552 #endif /* NOCSETS */
7553 break;
7554
7555 case SHFEA: /* Features */
7556 shofea();
7557 break;
7558
7559 #ifdef CK_SPEED
7560 case SHCTL: /* Control-Prefix table */
7561 shoctl();
7562 break;
7563 #endif /* CK_SPEED */
7564
7565 case SHEXI: {
7566 extern int exithangup, exitmsg;
7567 printf("\n Exit warning %s\n", xitwarn ?
7568 (xitwarn == 1 ? "on" : "always") : "off");
7569 printf(" Exit message: %s\n", exitmsg ?
7570 (exitmsg == 1 ? "on" : "stderr") : "off");
7571 printf(" Exit on-disconnect: %s\n", showoff(exitonclose));
7572 printf(" Exit hangup: %s\n", showoff(exithangup));
7573 printf(" Current exit status: %d\n\n", xitsta);
7574 break;
7575 }
7576 case SHPRT: {
7577 #ifdef PRINTSWI
7578 extern int printtimo, printertype, noprinter;
7579 extern char * printterm, * printsep;
7580 extern int prncs;
7581 #ifdef BPRINT
7582 extern int printbidi;
7583 #endif /* BPRINT */
7584 #endif /* PRINTSWI */
7585
7586 #ifdef IKSD
7587 if (inserver &&
7588 #ifdef CK_LOGIN
7589 isguest
7590 #else /* CK_LOGIN */
7591 0
7592 #endif /* CK_LOGIN */
7593 ) {
7594 printf("Sorry, command disabled.\r\n");
7595 return(success = 0);
7596 }
7597 #endif /* IKSD */
7598 #ifdef PRINTSWI
7599 if (noprinter) {
7600 printf("Printer: (none)\n\n");
7601 break;
7602 }
7603 #endif /* PRINTSWI */
7604
7605 printf("Printer: %s%s\n",
7606
7607 printpipe ? "| " : "",
7608 printername ? printername :
7609 #ifdef OS2
7610 "PRN"
7611 #else
7612 "(default)"
7613 #endif /* OS2 */
7614 );
7615 #ifdef PRINTSWI
7616 #ifdef BPRINT
7617 if (printbidi) {
7618 printf(" /BIDIRECTIONAL\n");
7619 if (pportspeed > 0)
7620 printf(" /SPEED:%ld\n",pportspeed);
7621 printf(" /PARITY:%s\n",parnam((char)pportparity));
7622 printf(" /FLOW:%s\n",
7623 pportflow == FLO_NONE ? "NONE" :
7624 (pportflow == FLO_RTSC ? "RTS/CTS" : "XON/XOFF")
7625 );
7626 } else
7627 printf(" /OUTPUT-ONLY\n");
7628 #endif /* BPRINT */
7629 switch (printertype) {
7630 case PRT_NON: printf(" /NONE\n"); break;
7631 case PRT_FIL: printf(" /FILE\n"); break;
7632 case PRT_PIP: printf(" /PIPE\n"); break;
7633 case PRT_DOS: printf(" /DOS-DEVICE\n"); break;
7634 case PRT_WIN: printf(" /WINDOWS-QUEUE\n"); break;
7635 }
7636 printf(" /TIMEOUT:%d\n",printtimo);
7637 if (printterm) {
7638 printf(" /END-OF-JOB-STRING:");
7639 shostrdef(printterm);
7640 printf("\n");
7641 } else
7642 printf(" /END-OF-JOB-STRING:(none)\n");
7643 printf(" /JOB-HEADER-FILE:%s\n",printsep ? printsep : "(none)");
7644 printf(" /CHARACTER-SET: %s\n",txrinfo[prncs]->keywd);
7645 #endif /* PRINTSWI */
7646 printf("\n");
7647 break;
7648 }
7649
7650 case SHCMD: {
7651 #ifdef DOUBLEQUOTING
7652 extern int dblquo;
7653 #endif /* DOUBLEQUOTING */
7654 #ifdef CK_AUTODL
7655 printf(" Command autodownload: %s\n",showoff(cmdadl));
7656 #else
7657 printf(" Command autodownload: (not available)\n");
7658 #endif /* CK_AUTODL */
7659 printf(" Command bytesize: %d bits\n", (cmdmsk == 0377) ? 8 : 7);
7660 printf(" Command error-display: %d\n", cmd_err);
7661 #ifdef CK_RECALL
7662 printf(" Command recall-buffer-size: %d\n",cm_recall);
7663 #else
7664 printf(" Command recall-buffer not available in this version\n");
7665 #endif /* CK_RECALL */
7666 #ifdef CK_RECALL
7667 printf(" Command retry: %s\n",showoff(cm_retry));
7668 #else
7669 printf(" Command retry not available in this version\n");
7670 #endif /* CK_RECALL */
7671 printf(" Command interruption: %s\n", showoff(cmdint));
7672 printf(" Command quoting: %s\n", showoff(cmdgquo()));
7673 #ifdef DOUBLEQUOTING
7674 printf(" Command doublequoting: %s\n", showoff(dblquo));
7675 #endif /* DOUBLEQUOTING */
7676 printf(" Command more-prompting: %s\n", showoff(xaskmore));
7677 printf(" Command height: %d\n", cmd_rows);
7678 printf(" Command width: %d\n", cmd_cols);
7679 #ifndef IKSDONLY
7680 #ifdef OS2
7681 printf(" Command statusline: %s\n",showoff(tt_status[VCMD]));
7682 #endif /* OS2 */
7683 #endif /* IKSDONLY */
7684 #ifdef LOCUS
7685 printf(" Locus: %s",
7686 autolocus ? (autolocus == 2 ? "ask" : "auto") :
7687 (locus ? "local" : "remote"));
7688 if (autolocus)
7689 printf(" (%s)", locus ? "local" : "remote");
7690 printf("\n");
7691 #endif /* LOCUS */
7692 printf(" Hints: %s\n", showoff(hints));
7693 printf(" Quiet: %s\n", showoff(quiet));
7694 printf(" Maximum command length: %d\n", CMDBL);
7695 #ifndef NOSPL
7696 {
7697 char * s;
7698 int k;
7699 printf(" Maximum number of macros: %d\n", MAC_MAX);
7700 printf(" Macros defined: %d\n", nmac);
7701 printf(" Maximum macro depth: %d\n", MACLEVEL);
7702 printf(" Maximum TAKE depth: %d\n", MAXTAKE);
7703 s = "(not defined)";
7704 k = mlook(mactab,"on_unknown_command",nmac);
7705 if (k > -1) if (mactab[k].mval) s = mactab[k].mval;
7706 printf(" ON_UNKNOWN_COMMAND: %s\n",s);
7707 }
7708 #endif /* NOSPL */
7709 #ifdef UNIX
7710 #ifndef NOJC
7711 printf(" Suspend: %s\n", showoff(xsuspend));
7712 #endif /* NOJC */
7713 #endif /* UNIX */
7714 printf(" Access to external commands and programs%s allowed\n",
7715 #ifndef NOPUSH
7716 !nopush ? "" :
7717 #endif /* NOPUSH */
7718 " not");
7719 break;
7720 }
7721
7722 #ifndef NOSPL
7723 case SHALRM:
7724 if (ck_alarm)
7725 printf("Alarm at %s %s\n",alrm_date,alrm_time);
7726 else
7727 printf("(no alarm set)\n");
7728 break;
7729 #endif /* NOSPL */
7730
7731 #ifndef NOMSEND
7732 case SHSFL: {
7733 extern struct filelist * filehead;
7734 if (!filehead) {
7735 printf("send-list is empty\n");
7736 } else {
7737 struct filelist * flp;
7738 char * s;
7739 flp = filehead;
7740 while (flp) {
7741 s = flp->fl_alias;
7742 if (!s) s = "(none)";
7743 printf("%s, mode: %s, alias: %s\n",
7744 flp->fl_name,
7745 gfmode(flp->fl_mode,0),
7746 s
7747 );
7748 flp = flp->fl_next;
7749 }
7750 }
7751 }
7752 break;
7753 #endif /* NOMSEND */
7754
7755 #ifdef CKXXCHAR
7756 case SHDBL:
7757 shodbl();
7758 break;
7759 #endif /* CKXXCHAR */
7760
7761 #ifndef NOPUSH
7762 #ifndef NOFRILLS
7763 case SHEDIT:
7764 if (!editor[0]) {
7765 s = getenv("EDITOR");
7766 if (s) ckstrncpy(editor,s,CKMAXPATH);
7767 }
7768 printf("\n editor: %s\n", editor[0] ? editor : "(none)");
7769 if (editor[0]) {
7770 printf(" options: %s\n", editopts[0] ? editopts : "(none)");
7771 printf(" file: %s\n", editfile[0] ? editfile : "(none)");
7772 }
7773 printf("\n");
7774 break;
7775
7776 #ifdef BROWSER
7777 case SHBROWSE:
7778 if (!browser[0]) {
7779 s = getenv("BROWSER");
7780 if (s) ckstrncpy(browser,s,CKMAXPATH);
7781 }
7782 printf("\n browser: %s\n", browser[0] ? browser : "(none)");
7783 if (browser[0]) {
7784 printf(" options: %s\n", browsopts[0] ? browsopts : "(none)");
7785 printf(" url: %s\n", browsurl[0] ? browsurl : "(none)");
7786 }
7787 printf("\n");
7788 break;
7789 #endif /* BROWSER */
7790 #endif /* NOFRILLS */
7791 #endif /* NOPUSH */
7792
7793 #ifndef NOLOCAL
7794 #ifdef CK_TAPI
7795 case SHTAPI: /* TAPI options */
7796 #ifdef IKSD
7797 if (inserver) {
7798 printf("Sorry, command disabled.\r\n");
7799 return(success = 0);
7800 }
7801 #endif /* IKSD */
7802 shotapi(0);
7803 break;
7804 case SHTAPI_L: /* TAPI Locations */
7805 #ifdef IKSD
7806 if (inserver) {
7807 printf("Sorry, command disabled.\r\n");
7808 return(success = 0);
7809 }
7810 #endif /* IKSD */
7811 shotapi(1);
7812 break;
7813 case SHTAPI_M: /* TAPI Modem */
7814 #ifdef IKSD
7815 if (inserver) {
7816 printf("Sorry, command disabled.\r\n");
7817 return(success = 0);
7818 }
7819 #endif /* IKSD */
7820 shotapi(2);
7821 break;
7822 case SHTAPI_C: /* TAPI Comm */
7823 #ifdef IKSD
7824 if (inserver) {
7825 printf("Sorry, command disabled.\r\n");
7826 return(success = 0);
7827 }
7828 #endif /* IKSD */
7829 shotapi(3);
7830 break;
7831 #endif /* CK_TAPI */
7832
7833 case SHTCP: /* SHOTCP */
7834 printf("\n");
7835 shotcp(0);
7836 printf("\n");
7837 break;
7838
7839 #ifdef TNCODE
7840 case SHTEL: /* TELNET */
7841 printf("\n");
7842 shotel(0);
7843 printf("\n");
7844 break;
7845
7846 case SHTOPT: /* TELNET OPTIONS */
7847 printf("\n");
7848 shotopt(0);
7849 printf("\n");
7850 break;
7851 #endif /* TNCODE */
7852
7853 case SHOTMPDIR: /* TEMPORARY DIRECTORY */
7854 {
7855 extern char * tempdir;
7856 if (!tempdir) {
7857 printf(" (none)\n");
7858 } else if (!*tempdir) {
7859 printf(" (none)\n");
7860 } else {
7861 printf(" %s\n", tempdir);
7862 }
7863 break;
7864 }
7865 #ifdef CK_TRIGGER
7866 case SHTRIG: {
7867 extern char * tt_trigger[], * triggerval;
7868 int i;
7869 if (!tt_trigger[0]) {
7870 printf(" Triggers: (none)\n");
7871 } else {
7872 printf(" Triggers:\n");
7873 for (i = 0; i < TRIGGERS; i++) {
7874 if (!tt_trigger[i])
7875 break;
7876 printf(" \"%s\"\n",tt_trigger[i]);
7877 }
7878 printf(" Most recent trigger encountered: ");
7879 if (triggerval)
7880 printf("\"%s\"\n",triggerval);
7881 else
7882 printf("(none)\n");
7883 }
7884 break;
7885 }
7886 #endif /* CK_TRIGGER */
7887 #endif /* NOLOCAL */
7888
7889 #ifndef NOSPL
7890 case SHINP:
7891 shoinput();
7892 break;
7893 #endif /* NOSPL */
7894
7895 case SHLOG: {
7896 #ifndef MAC
7897 #ifdef IKSD
7898 if (inserver &&
7899 #ifdef CK_LOGIN
7900 isguest
7901 #else /* CK_LOGIN */
7902 0
7903 #endif /* CK_LOGIN */
7904 ) {
7905 printf("Sorry, command disabled.\r\n");
7906 return(success = 0);
7907 }
7908 #endif /* IKSD */
7909 #ifdef DEBUG
7910 printf("\n Debug log: %s", deblog ? debfil : "(none)");
7911 {
7912 extern int debtim;
7913 if (debtim) printf(" (timestamps)");
7914 printf("\n");
7915 }
7916 #endif /* DEBUG */
7917 #ifndef NOXFER
7918 printf(" Packet log: %s\n", pktlog ? pktfil : "(none)");
7919 #endif /* NOXFER */
7920 #ifndef NOLOCAL
7921 printf(" Session log: %s", seslog ? sesfil : "(none)");
7922 {
7923 extern int sessft, slogts, slognul;
7924 switch (sessft) {
7925 case XYFT_T: printf(" (text)"); break;
7926 case XYFT_B: printf(" (binary)"); break;
7927 case XYFT_D: printf(" (debug)"); break;
7928 }
7929 if (slogts) printf("(timestamped)");
7930 if (slognul) printf("(null-padded)");
7931 printf("\n");
7932 }
7933
7934 #endif /* NOLOCAL */
7935 #ifdef TLOG
7936 printf(" Transaction log: %s (%s)\n",
7937 (tralog ? (*trafil ? trafil : "(none)") : "(none)"),
7938 (tlogfmt ? ((tlogfmt == 2) ? "ftp" : "verbose") : "brief")
7939 );
7940 #endif /* TLOG */
7941 #ifdef CKLOGDIAL
7942 printf(" Connection log: %s\n", dialog ? diafil : "(none)");
7943 #endif /* CKLOGDIAL */
7944 printf("\n");
7945 #endif /* MAC */
7946 break;
7947 }
7948
7949 #ifndef NOSPL
7950 case SHOUTP: /* OUTPUT */
7951 shooutput();
7952 break;
7953 #endif /* NOSPL */
7954
7955 #ifdef PATTERNS
7956 case SHOPAT: /* PATTERNS */
7957 shopat();
7958 break;
7959 #endif /* PATTERNS */
7960
7961 #ifdef STREAMING
7962 case SHOSTR: { /* STREAMING */
7963 extern int streamrq, clearrq, cleared;
7964 extern long tfcps;
7965 debug(F101,"SHOW RELIABLE reliable","",reliable);
7966 printf("\n Reliable: %s\n",showooa(reliable));
7967 printf(" Clearchannel: %s\n",showooa(clearrq));
7968 printf(" Streaming: %s\n\n",showooa(streamrq));
7969 if ((!local && (streamrq == SET_ON)) ||
7970 (streamrq == SET_AUTO && reliable))
7971 printf(" Streaming will be done if requested.\n");
7972 else if ((streamrq == SET_OFF) ||
7973 ((streamrq == SET_AUTO) && !reliable))
7974 printf(" Streaming will not be requested and will not be done.\n");
7975 else if ((streamrq == SET_ON) ||
7976 ((streamrq == SET_AUTO) && reliable))
7977 printf(
7978 " Streaming will be requested and will be done if the other Kermit agrees.\n");
7979 printf(" Last transfer: %sstreaming%s, %ld cps.\n",
7980 streamed > 0 ? "" : "no ",
7981 cleared ? ", clearchannel" : "",
7982 tfcps
7983 );
7984 printf("\n");
7985 break;
7986 }
7987 #endif /* STREAMING */
7988
7989 case SHOIKS:
7990 return(sho_iks());
7991 break;
7992
7993 #ifdef CK_AUTHENTICATION
7994 case SHOAUTH:
7995 return(sho_auth(0));
7996 #endif /* CK_AUTHENTICATION */
7997
7998 #ifndef NOFTP
7999 case SHOFTP: {
8000 #ifdef IKSD
8001 if (inserver) {
8002 printf("Sorry, command disabled.\r\n");
8003 return(success = 0);
8004 }
8005 #endif /* IKSD */
8006 #ifdef SYSFTP
8007 {
8008 extern char ftpapp[], ftpopts[];
8009 printf(" ftp-client: %s\n", ftpapp[0] ? ftpapp : "(none)");
8010 if (ftpapp[0])
8011 printf(" ftp options: %s\n", ftpopts[0] ? ftpopts : "(none)");
8012 }
8013 #else
8014 #ifdef NEWFTP
8015 shoftp(0);
8016 #else
8017 printf("(No FTP client included in this version of Kermit.)\n");
8018 #endif /* NEWFTP */
8019 #endif /* SYSFTP */
8020 break;
8021 }
8022 #endif /* NOFTP */
8023
8024 #ifndef NOCMDL
8025 case SHXOPT: {
8026 #ifdef IKSDB
8027 extern int dbenabled;
8028 extern char * dbfile, * dbdir;
8029 #endif /* IKSDB */
8030 #ifdef CKWTMP
8031 extern int ckxwtmp;
8032 extern char * wtmpfile;
8033 #endif /* CKWTMP */
8034 #ifdef CK_LOGIN
8035 extern int ckxanon, xferlog, logintimo;
8036 extern char * xferfile;
8037 #ifdef UNIX
8038 extern int ckxpriv;
8039 #endif /* UNIX */
8040 #ifdef CK_PERMS
8041 extern int ckxperms;
8042 #endif /* CK_PERMS */
8043 #endif /* CK_LOGIN */
8044 extern char * bannerfile, * helpfile;
8045
8046 #ifdef IKSD
8047 if (inserver &&
8048 #ifdef CK_LOGIN
8049 isguest
8050 #else /* CK_LOGIN */
8051 0
8052 #endif /* CK_LOGIN */
8053 ) {
8054 printf("Sorry, command disabled.\r\n");
8055 return(success = 0);
8056 }
8057 #endif /* IKSD */
8058 printf("\n");
8059 if (!cmdint)
8060 printf(" --nointerrupts\n");
8061 printf(" --bannerfile=%s\n",bannerfile ? bannerfile : "(null)");
8062 printf(" --cdfile:%s\n",cdmsgstr ? cdmsgstr : "(null)");
8063 printf(" --cdmessage:%d\n",srvcdmsg);
8064 printf(" --helpfile:%d\n",helpfile);
8065 if (inserver) {
8066 printf("\n");
8067 break;
8068 }
8069 #ifdef CKSYSLOG
8070 #ifdef SYSLOGLEVEL
8071 printf(" --syslog:%d (forced)\n",ckxsyslog);
8072 #else
8073 printf(" --syslog:%d\n",ckxsyslog);
8074 #endif /* SYSLOGLEVEL */
8075 #endif /* CKSYSLOG */
8076 #ifdef CKWTMP
8077 printf(" --wtmplog:%d\n",ckxwtmp);
8078 printf(" --wtmpfile=%s\n",wtmpfile ? wtmpfile : "(null)");
8079 #endif /* CKWTMP */
8080 #ifdef IKSD
8081 #ifdef CK_LOGIN
8082 printf(" --anonymous:%d\n",ckxanon);
8083 #ifdef UNIX
8084 printf(" --privid:%d\n",ckxpriv);
8085 #endif /* UNIX */
8086 #ifdef CK_PERMS
8087 printf(" --permission:%04o\n",ckxperms);
8088 #endif /* CK_PERMS */
8089 printf(" --initfile:%s\n",anonfile ? anonfile : "(null)");
8090 printf(" --userfile:%s\n",userfile ? userfile : "(null)");
8091 printf(" --root:%s\n",anonroot ? anonroot : "(null)");
8092 printf(" --xferlog=%d\n",xferlog);
8093 printf(" --xferfile=%s\n",xferfile ? xferfile : "(null)");
8094 printf(" --timeout=%d\n",logintimo);
8095 #endif /* CK_LOGIN */
8096 #ifdef IKSDB
8097 printf(" --database=%d\n",dbenabled);
8098 printf(" --dbfile=%s\n",dbfile ? dbfile : "(null)");
8099 if (dbdir)
8100 printf(" (db directory=[%s])\n",dbdir);
8101 #endif /* IKSDB */
8102 #ifdef IKSDCONF
8103 printf(" IKSD conf=%s\n",iksdconf);
8104 #endif /* IKSDCONF */
8105 #endif /* IKSD */
8106 printf("\n");
8107 break;
8108 }
8109 #endif /* NOCMDL */
8110
8111 case SHCD: {
8112 extern char * myhome;
8113 s = getenv("CDPATH");
8114 if (!s) s = "(none)";
8115 printf("\n current directory: %s\n", zgtdir());
8116 printf(" previous directory: %s\n", prevdir ? prevdir : "(none)");
8117 printf(" cd home: %s\n", homepath());
8118 printf(" cd path: %s\n", ckcdpath ? ckcdpath : s);
8119 printf(" cd message: %s\n", showoff(srvcdmsg & 2));
8120 printf(" server cd-message: %s\n", showoff(srvcdmsg & 1));
8121 printf(" cd message file: %s\n\n",cdmsgstr ? cdmsgstr : "(none)");
8122 break;
8123 }
8124 #ifndef NOCSETS
8125 case SHASSOC:
8126 (VOID) showassoc();
8127 break;
8128 #endif /* NOCSETS */
8129
8130 #ifdef CKLOGDIAL
8131 case SHCONNX:
8132 #ifdef NEWFTP
8133 if (ftpisconnected()) {
8134 extern char cxlogbuf[];
8135 dologshow(W_FTP | 1);
8136 if (cxlogbuf[0])
8137 dologshow(1);
8138 } else {
8139 #endif /* NEWFTP */
8140 dologshow(1);
8141 #ifdef NEWFTP
8142 }
8143 #endif /* NEWFTP */
8144 break;
8145 #endif /* CKLOGDIAL */
8146
8147 case SHOPTS:
8148 optlines = 0;
8149 #ifndef NOFRILLS
8150 (VOID) showdelopts();
8151 #endif /* NOFRILLS */
8152 #ifdef DOMYDIR
8153 (VOID) showdiropts();
8154 #endif /* DOMYDIR */
8155 #ifdef CKPURGE
8156 (VOID) showpurgopts();
8157 #endif /* CKPURGE */
8158 (VOID) showtypopts();
8159 break;
8160
8161 #ifndef NOLOCAL
8162 case SHOFLO:
8163 (VOID) shoflow();
8164 break;
8165 #endif /* NOLOCAL */
8166
8167 #ifndef NOXFER
8168 case SHOXFER:
8169 (VOID) shoxfer();
8170 break;
8171 #endif /* NOXFER */
8172
8173 #ifdef CK_RECALL
8174 case SHHISTORY:
8175 (VOID) cmhistory();
8176 break;
8177 #endif /* CK_RECALL */
8178
8179 #ifndef NOSEXP
8180 #ifndef NOSPL
8181 case SHSEXP:
8182 (VOID) shosexp();
8183 break;
8184 #endif /* NOSPL */
8185 #endif /* NOSEXP */
8186
8187 #ifdef ANYSSH
8188 case SHOSSH:
8189 (VOID) shossh();
8190 break;
8191 #endif /* ANYSSH */
8192
8193 #ifdef KUI
8194 case SHOGUI:
8195 (VOID) shogui();
8196 break;
8197 #endif /* KUI */
8198
8199 #ifndef NOFRILLS
8200 #ifndef NORENAME
8201 case SHOREN:
8202 (VOID) shorename();
8203 break;
8204 #endif /* NORENAME */
8205 #endif /* NOFRILLS */
8206
8207 case SHOLOC: {
8208 #ifdef HAVE_LOCALE
8209 char *s;
8210 extern int nolocale;
8211 printf("\n");
8212
8213 printf("Locale %s:\n", nolocale ? "disabled" : "enabled");
8214
8215 #ifdef COMMENT
8216 s = setlocale(LC_ALL, NULL);
8217 if (!s) s = "";
8218 printf("LC_ALL=%s\n",s);
8219 #endif /* COMMENT */
8220
8221 s = setlocale(LC_COLLATE, NULL);
8222 if (!s) s = "";
8223 printf(" LC_COLLATE=\"%s\"\n",s);
8224
8225 s = setlocale(LC_CTYPE, NULL);
8226 if (!s) s = "";
8227 printf(" LC_CTYPE=\"%s\"\n",s);
8228
8229 s = setlocale(LC_MONETARY, NULL);
8230 if (!s) s = "";
8231 printf(" LC_MONETARY=\"%s\"\n",s);
8232
8233 s = setlocale(LC_MESSAGES, NULL);
8234 if (!s) s = "";
8235 printf(" LC_MESSAGES=\"%s\"\n",s);
8236
8237 s = setlocale(LC_NUMERIC, NULL);
8238 if (!s) s = "";
8239 printf(" LC_NUMERIC=\"%s\"\n",s);
8240
8241 s = setlocale(LC_TIME, NULL);
8242 if (!s) s = "";
8243 printf(" LC_TIME=\"%s\"\n",s);
8244
8245 printf(" LANG=\"%s\"\n",getenv("LANG"));
8246 printf("\n");
8247 #else
8248 printf("\n");
8249 printf(" Locale support is not included in this version of Kermit\n");
8250 printf("\n");
8251 #endif /* HAVE_LOCALE */
8252
8253 break;
8254 }
8255 default:
8256 printf("\nNothing to show...\n");
8257 return(-2);
8258
8259 }
8260 return(success = 1);
8261 }
8262
8263 #ifndef NOXFER
8264 int
shoatt()8265 shoatt() {
8266 printf("Attributes: %s\n", showoff(atcapr));
8267 if (!atcapr) return(0);
8268 printf(" Blocksize: %s\n", showoff(atblki));
8269 printf(" Date: %s\n", showoff(atdati));
8270 printf(" Disposition: %s\n", showoff(atdisi));
8271 printf(" Encoding (Character Set): %s\n", showoff(atenci));
8272 printf(" Length: %s\n", showoff(atleni));
8273 printf(" Type (text/binary): %s\n", showoff(attypi));
8274 printf(" System ID: %s\n", showoff(atsidi));
8275 printf(" System Info: %s\n", showoff(atsysi));
8276 #ifdef CK_PERMS
8277 printf(" Permissions In: %s\n", showoff(atlpri));
8278 printf(" Permissions Out: %s\n", showoff(atlpro));
8279 #endif /* CK_PERMS */
8280 #ifdef STRATUS
8281 printf(" Format: %s\n", showoff(atfrmi));
8282 printf(" Creator: %s\n", showoff(atcrei));
8283 printf(" Account: %s\n", showoff(atacti));
8284 #endif /* STRATUS */
8285 return(0);
8286 }
8287 #endif /* NOXFER */
8288
8289 #ifndef NOSPL
8290 int /* SHOW MACROS */
shomac(s1,s2)8291 shomac(s1, s2) char *s1, *s2; {
8292 int x, n, pp;
8293 pp = 0; /* Parenthesis counter */
8294
8295 debug(F110,"shomac s1",s1,0);
8296 debug(F110,"shomac s2",s2,0);
8297
8298 #ifdef IKSD
8299 if ( inserver &&
8300 #ifdef IKSDCONF
8301 iksdcf
8302 #else /* IKSDCONF */
8303 1
8304 #endif /* IKSDCONF */
8305 ) {
8306 if (!ckstrcmp("on_exit",s1,-1,0) ||
8307 !ckstrcmp("on_logout",s1,-1,0))
8308 return(0);
8309 }
8310 #endif /* IKSD */
8311
8312 if (!s1)
8313 return(0);
8314 else
8315 printf("%s = ",s1); /* Print blank line and macro name */
8316 n = (int)strlen(s1) + 4; /* Width of current line */
8317 if (!s2) s2 = "(not defined)";
8318
8319 while ((x = *s2++)) { /* Loop thru definition */
8320 if (x == '(') pp++; /* Treat commas within parens */
8321 if (x == ')') pp--; /* as ordinary text */
8322 if (pp < 0) pp = 0; /* Outside parens, */
8323 if (x == ',' && pp == 0) { /* comma becomes comma-dash-NL. */
8324 putchar(',');
8325 putchar('-');
8326 x = '\n';
8327 }
8328 if (inserver && (x == '\n')) /* Send CR before LF */
8329 putchar(CR);
8330 putchar((CHAR)x); /* Output the character */
8331 if (x == '\n') { /* If it was a newline */
8332 #ifdef UNIX
8333 #ifdef NOSETBUF
8334 fflush(stdout);
8335 #endif /* NOSETBUF */
8336 #endif /* UNIX */
8337 putchar(' '); /* Indent the next line 1 space */
8338 while(*s2 == ' ') s2++; /* skip past leading blanks */
8339 n = 2; /* restart the character counter */
8340 slc++; /* and increment the line counter. */
8341 } else if (++n > (cmd_cols - 1)) { /* If line is too wide */
8342 putchar('-'); /* output a dash */
8343 if (inserver)
8344 putchar(CR); /* and a carriage return */
8345 putchar(NL); /* and a newline */
8346 #ifdef UNIX
8347 #ifdef NOSETBUF
8348 fflush(stdout);
8349 #endif /* NOSETBUF */
8350 #endif /* UNIX */
8351 n = 1; /* and restart the char counter */
8352 slc++; /* and increment the line counter */
8353 }
8354 if (n < 3 && slc > (cmd_rows - 3)) { /* If new line and screen full */
8355 if (!askmore()) return(-1); /* ask if they want more. */
8356 n = 1; /* They do, start a new line */
8357 slc = 0; /* and restart line counter */
8358 }
8359 }
8360 if (inserver)
8361 putchar(CR);
8362 putchar(NL); /* End of definition */
8363 if (++slc > (cmd_rows - 3)) {
8364 if (!askmore()) return(-1);
8365 slc = 0;
8366 }
8367 return(0);
8368 }
8369 #endif /* NOSPL */
8370 #endif /* NOSHOW */
8371
8372 int x_ifnum = 0; /* Flag for IF NUMERIC active */
8373
8374 #ifndef NOSPL
8375 /* Evaluate an arithmetic expression. */
8376 /* Code adapted from ev, by Howie Kaye of Columbia U & others. */
8377
8378 static int xerror = 0;
8379 int divbyzero = 0;
8380 static char *cp;
8381 static CK_OFF_T tokval;
8382 static char curtok;
8383 static CK_OFF_T expval;
8384
8385 #define LONGBITS (8*sizeof (CK_OFF_T))
8386 #define NUMBER 'N'
8387 #define N_EOT 'E'
8388
8389 /*
8390 Replacement for strchr() and index(), neither of which seem to be universal.
8391 */
8392
8393 static char *
8394 #ifdef CK_ANSIC
windex(char * s,char c)8395 windex(char * s, char c)
8396 #else
8397 windex(s,c) char *s, c;
8398 #endif /* CK_ANSIC */
8399 /* windex */ {
8400 while (*s != NUL && *s != c) s++;
8401 if (*s == c) return(s); else return(NULL);
8402 }
8403
8404
8405 /*
8406 g e t t o k
8407
8408 Returns the next token. If token is a NUMBER, sets tokval appropriately.
8409 */
8410 static char
gettok()8411 gettok() {
8412 char tbuf[80] /* ,*tp */ ; /* Buffer to accumulate number */
8413
8414 while (isspace(*cp)) /* Skip past leading spaces */
8415 cp++;
8416
8417 debug(F110,"GETTOK",cp,0);
8418
8419 switch (*cp) {
8420 case '$': /* ??? */
8421 case '+': /* Add */
8422 case '-': /* Subtract or Negate */
8423 case '@': /* Greatest Common Divisor */
8424 case '*': /* Multiply */
8425 case '/': /* Divide */
8426 case '%': /* Modulus */
8427 case '<': /* Left shift */
8428 case '>': /* Right shift */
8429 case '&': /* And */
8430 case '|': /* Or */
8431 case '#': /* Exclusive Or */
8432 case '~': /* Not */
8433 case '^': /* Exponent */
8434 case '!': /* Factorial */
8435 case '(': /* Parens for grouping */
8436 case ')': return(*cp++); /* operator, just return it */
8437 case '\n':
8438 case '\0': return(N_EOT); /* End of line, return that */
8439 }
8440 #ifdef COMMENT
8441 /* This is the original code, which allows only integer numbers. */
8442
8443 if (isxdigit(*cp)) { /* Digit, must be a number */
8444 int radix = 10; /* Default radix */
8445 for (tp = tbuf; isxdigit(*cp); cp++)
8446 *tp++ = (char) (isupper(*cp) ? tolower(*cp) : *cp);
8447 *tp = '\0'; /* End number */
8448 switch(isupper(*cp) ? tolower(*cp) : *cp) { /* Examine break char */
8449 case 'h':
8450 case 'x': radix = 16; cp++; break; /* if radix signifier... */
8451 case 'o':
8452 case 'q': radix = 8; cp++; break;
8453 case 't': radix = 2; cp++; break;
8454 }
8455 for (tp = tbuf, tokval = 0; *tp != '\0'; tp++) {
8456 int dig;
8457 dig = *tp - '0'; /* Convert number */
8458 if (dig > 10) dig -= 'a'-'0'-10;
8459 if (dig >= radix) {
8460 if (cmdlvl == 0 && !x_ifnum && !xerror)
8461 printf("?Invalid digit '%c' in number\n",*tp);
8462 xerror = 1;
8463 return(NUMBER);
8464 }
8465 tokval = radix*tokval + dig;
8466 }
8467 return(NUMBER);
8468 }
8469 if (cmdlvl == 0 && !x_ifnum && !xerror)
8470 printf("Invalid character '%c' in input\n",*cp);
8471 xerror = 1;
8472 cp++;
8473 return(gettok());
8474 #else
8475 /* This code allows non-numbers to be treated as macro names */
8476 {
8477 int i, x;
8478 char * s, * cp1;
8479 cp1 = cp;
8480 tp = tbuf;
8481 for (i = 0; i < 80; i++) {
8482 /* Look ahead to next break character */
8483 /* pretty much anything that is not in the switch() above. */
8484 if (isalpha(*cp) || isdigit(*cp) ||
8485 *cp == '_' || *cp == ':' || *cp == '.' ||
8486 *cp == '[' || *cp == ']' ||
8487 *cp == '{' || *cp == '}'
8488 )
8489 tbuf[i] = *cp++;
8490 else
8491 break;
8492 }
8493 if (i >= 80) {
8494 printf("Too long - \"%s\"\n", cp1);
8495 xerror = 1;
8496 cp++;
8497 return(gettok());
8498 }
8499 if (xerror) return(NUMBER);
8500
8501 tbuf[i] = NUL;
8502 s = tbuf;
8503 if (!isdigit(tbuf[0])) {
8504 char * s2 = NULL;
8505 x = mxlook(mactab,tbuf,nmac);
8506 debug(F111,"gettok mxlook",tbuf,x);
8507 if (x < 0) {
8508 if (cmdlvl == 0 && !x_ifnum && !xerror)
8509 printf("Bad number - \"%s\"\n",tbuf);
8510 xerror = 1;
8511 cp++;
8512 return(gettok());
8513 }
8514 s2 = mactab[x].mval;
8515 if (!s2) s2 = "";
8516 if (*s2) s = s2;
8517 }
8518 #ifdef CKFLOAT
8519 x = isfloat(s,0);
8520 #else
8521 x = chknum(s);
8522 #endif /* CKFLOAT */
8523 if (x > 0) {
8524 tokval = ckatofs(s);
8525 } else {
8526 if (cmdlvl == 0 && !x_ifnum && !xerror)
8527 printf("Bad number - \"%s\"\n",tbuf);
8528 xerror = 1;
8529 cp++;
8530 return(gettok());
8531 }
8532 return(NUMBER);
8533 }
8534 #endif /* COMMENT */
8535 }
8536
8537 static CK_OFF_T
8538 #ifdef CK_ANSIC
expon(CK_OFF_T x,CK_OFF_T y)8539 expon(CK_OFF_T x, CK_OFF_T y)
8540 #else
8541 expon(x,y) CK_OFF_T x,y;
8542 #endif /* CK_ANSIC */
8543 /* expon */ {
8544 CK_OFF_T result = 1;
8545 int sign = 1;
8546 if (y < 0) return(0);
8547 if (x < 0) {
8548 x = -x;
8549 if (y & 1) sign = -1;
8550 }
8551 while (y != 0) {
8552 if (y & 1) result *= x;
8553 y >>= 1;
8554 if (y != 0) x *= x;
8555 }
8556 return(result * sign);
8557 }
8558
8559 /*
8560 * factor ::= simple | simple ^ factor
8561 *
8562 */
8563 static VOID
factor()8564 factor() {
8565 CK_OFF_T oldval;
8566 simple();
8567 if (curtok == '^') {
8568 oldval = expval;
8569 curtok = gettok();
8570 factor();
8571 expval = expon(oldval,expval);
8572 }
8573 }
8574
8575 /*
8576 * termp ::= NULL | {*,/,%,&} factor termp
8577 *
8578 */
8579 static VOID
termp()8580 termp() {
8581 while (curtok == '*' || curtok == '/' || curtok == '%' || curtok == '&') {
8582 CK_OFF_T oldval;
8583 char op;
8584 op = curtok;
8585 curtok = gettok(); /* skip past operator */
8586 oldval = expval;
8587 factor();
8588 switch(op) {
8589 case '*': expval = oldval * expval; break;
8590 case '/':
8591 case '%':
8592 if (expval == 0) {
8593 if (!x_ifnum)
8594 printf("?Divide by zero\n");
8595 xerror = 1;
8596 divbyzero = 1;
8597 expval = -1;
8598 } else
8599 expval = (op == '/') ? (oldval / expval) : (oldval % expval);
8600 break;
8601 case '&':
8602 expval = oldval & expval; break;
8603 }
8604 }
8605 }
8606
8607 static CK_OFF_T
8608 #ifdef CK_ANSIC
fact(CK_OFF_T x)8609 fact(CK_OFF_T x)
8610 #else
8611 fact(x) CK_OFF_T x;
8612 #endif /* CK_ANSIC */
8613 /* fact */ { /* factorial */
8614 CK_OFF_T result = 1;
8615 while (x > 1)
8616 result *= x--;
8617 return(result);
8618 }
8619
8620 /*
8621 * term ::= factor termp
8622 *
8623 */
8624 static VOID
term()8625 term() {
8626 factor();
8627 termp();
8628 }
8629
8630 static CK_OFF_T
8631 #ifdef CK_ANSIC
gcd(CK_OFF_T x,CK_OFF_T y)8632 gcd(CK_OFF_T x, CK_OFF_T y)
8633 #else
8634 gcd(x,y) CK_OFF_T x,y;
8635 #endif /* CK_ANSIC */
8636 /* gcd */ { /* Greatest Common Divisor */
8637 int nshift = 0;
8638 if (x < 0) x = -x;
8639 if (y < 0) y = -y; /* validate arguments */
8640 if (x == 0 || y == 0) return(x + y); /* this is bogus */
8641
8642 while (!((x & 1) | (y & 1))) { /* get rid of powers of 2 */
8643 nshift++;
8644 x >>= 1;
8645 y >>= 1;
8646 }
8647 while (x != 1 && y != 1 && x != 0 && y != 0) {
8648 while (!(x & 1)) x >>= 1; /* eliminate unnecessary */
8649 while (!(y & 1)) y >>= 1; /* powers of 2 */
8650 if (x < y) { /* force x to be larger */
8651 CK_OFF_T t;
8652 t = x;
8653 x = y;
8654 y = t;
8655 }
8656 x -= y;
8657 }
8658 if (x == 0 || y == 0) return((x + y) << nshift); /* gcd is non-zero one */
8659 else return((CK_OFF_T) 1 << nshift); /* else gcd is 1 */
8660 }
8661
8662 /*
8663 * exprp ::= NULL | {+,-,|,...} term exprp
8664 *
8665 */
8666 static VOID
exprp()8667 exprp() {
8668 while (windex("+-|<>#@",curtok) != NULL) {
8669 CK_OFF_T oldval;
8670 char op;
8671 op = curtok;
8672 curtok = gettok(); /* skip past operator */
8673 oldval = expval;
8674 term();
8675 switch(op) {
8676 case '+' : expval = oldval + expval; break;
8677 case '-' : expval = oldval - expval; break;
8678 case '|' : expval = oldval | expval; break;
8679 case '#' : expval = oldval ^ expval; break;
8680 case '@' : expval = gcd(oldval,expval); break;
8681 case '<' : expval = oldval << expval; break;
8682 case '>' : expval = oldval >> expval; break;
8683 }
8684 }
8685 }
8686
8687 /*
8688 * expr ::= term exprp
8689 *
8690 */
8691 static VOID
expr()8692 expr() {
8693 term();
8694 exprp();
8695 }
8696
8697 static CK_OFF_T
xparse()8698 xparse() {
8699 curtok = gettok();
8700 expr();
8701 #ifdef COMMENT
8702 if (curtok == '$') {
8703 curtok = gettok();
8704 if (curtok != NUMBER) {
8705 if (cmdlvl == 0 && !x_ifnum)
8706 printf("?Illegal radix\n");
8707 xerror = 1;
8708 return(0);
8709 }
8710 curtok = gettok();
8711 }
8712 #endif /* COMMENT */
8713 if (curtok != N_EOT) {
8714 if (cmdlvl == 0 && !x_ifnum && !xerror)
8715 printf("?Extra characters after expression\n");
8716 xerror = 1;
8717 }
8718 return(expval);
8719 }
8720
8721 char * /* Silent front end for evala() */
evalx(s)8722 evalx(s) char *s; {
8723 char * p;
8724 int t;
8725 t = x_ifnum;
8726 x_ifnum = 1;
8727 p = evala(s);
8728 x_ifnum = t;
8729 return(p);
8730 }
8731
8732 char *
evala(s)8733 evala(s) char *s; {
8734 CK_OFF_T v; /* Numeric value */
8735 if (!s) return("");
8736 xerror = 0; /* Start out with no error */
8737 divbyzero = 0;
8738 cp = s; /* Make the argument global */
8739 v = xparse(); /* Parse the string */
8740 return(xerror ? "" : ckfstoa(v)); /* Return empty string on error */
8741 }
8742
8743 /*
8744 * simplest ::= NUMBER | ( expr )
8745 *
8746 */
8747 static VOID
simplest()8748 simplest() {
8749 char * p;
8750 p = cp;
8751 if (curtok == NUMBER)
8752 expval = tokval;
8753 else if (curtok == '(') {
8754 curtok = gettok(); /* skip over paren */
8755 expr();
8756 if (curtok != ')') {
8757 if (cmdlvl == 0 && !x_ifnum && !xerror)
8758 printf("?Missing right parenthesis\n");
8759 xerror = 1;
8760 }
8761 debug(F110,"GETTOK SIMPLEST ()",p,0);
8762
8763 } else {
8764 if (cmdlvl == 0 && !x_ifnum && !xerror)
8765 printf("?Operator unexpected\n");
8766 xerror = 1;
8767 }
8768 curtok = gettok();
8769 }
8770
8771 /*
8772 * simpler ::= simplest | simplest !
8773 *
8774 */
8775 static VOID
simpler()8776 simpler() {
8777 simplest();
8778 if (curtok == '!') {
8779 curtok = gettok();
8780 expval = fact(expval);
8781 }
8782 }
8783
8784 /*
8785 * simple ::= {-,~,!} simpler | simpler
8786 *
8787 */
8788
8789 static VOID
simple()8790 simple() {
8791 if (curtok == '-' || curtok == '~' || curtok == '!' || curtok == '+') {
8792 int op = curtok;
8793 curtok = gettok(); /* skip over - sign */
8794 simpler(); /* parse the factor again */
8795 if (op != '+')
8796 expval = (op == '-') ? -expval : ((op == '!') ? !expval : ~expval);
8797 } else simpler();
8798 }
8799
8800 /* D C L A R R A Y -- Declare an array */
8801 /*
8802 Call with:
8803 char a = single character designator for the array, e.g. "a".
8804 int n = size of array. -1 means to undeclare the array.
8805 Returns:
8806 0 or greater on success, having created the requested array with
8807 with n+1 elements, 0..n. If an array of the same name existed
8808 previously, it is destroyed. The new array has all its elements
8809 initialized to NULL pointers. When an array is successfully created,
8810 the return value is its index (0 = 'a', 1 = 'b', and so on.)
8811 -1 on failure (because 'a' out of range or malloc failure).
8812 */
8813 int
8814 #ifdef CK_ANSIC
dclarray(char a,int n)8815 dclarray(char a, int n)
8816 #else
8817 dclarray(a,n) char a; int n;
8818 #endif /* CK_ANSIC */
8819 /* dclarray */ {
8820 char c, **p; int i, n2, rc;
8821
8822 if (a > 63 && a < 91) a += 32; /* Convert letters to lowercase */
8823 if (a < ARRAYBASE || a > 122) /* Verify name */
8824 return(-1);
8825
8826 if (n < 0) /* Check arg */
8827 return(-1);
8828 if (n+1 < 0) /* MAXINT+1 wraps around */
8829 return(-1);
8830
8831 c = a;
8832 a -= ARRAYBASE; /* Convert name to number */
8833 rc = a; /* Array index will be return code */
8834 if ((p = a_ptr[a]) != NULL) { /* Delete old array of same name */
8835 if (a_link[a] > -1) { /* Is it a link? */
8836 if (n == 0) { /* If we're just deleting it */
8837 a_ptr[a] = (char **) NULL; /* clear all the info. */
8838 a_dim[a] = 0;
8839 a_link[a] = -1;
8840 return(0);
8841 } /* Not deleting */
8842 a = a_link[a]; /* Switch to linked-to array */
8843 }
8844 n2 = a_dim[a]; /* Real array */
8845 for (i = 0; i <= n2; i++) { /* First delete its elements */
8846 if (p[i]) {
8847 free(p[i]);
8848 p[i] = NULL;
8849 }
8850 }
8851 free((char *)a_ptr[a]); /* Then the element list */
8852 if (n == 0) { /* If undeclaring this array... */
8853 for (i = 0; i < 122 - ARRAYBASE; i++) { /* Any linked arrays? */
8854 if (i != a && a_link[i] == a) { /* Find them */
8855 a_ptr[i] = (char **) NULL; /* and remove them */
8856 a_dim[i] = 0;
8857 a_link[i] = -1;
8858 }
8859 }
8860 }
8861 a_ptr[a] = (char **) NULL; /* Remove pointer to element list */
8862 a_dim[a] = 0; /* Set dimension at zero. */
8863 a_link[a] = -1; /* Unset link word */
8864 }
8865 if (n < 0) /* If only undeclaring, */
8866 return(0); /* we're done. */
8867 p = (char **) malloc((n+1) * sizeof(char **)); /* Allocate for new array */
8868 if (p == NULL) return(-1); /* Check */
8869 a_ptr[a] = p; /* Save pointer to member list */
8870 a_dim[a] = n; /* Save dimension */
8871 for (i = 0; i <= n; i++) /* Initialize members to null */
8872 p[i] = NULL;
8873 for (i = 0; i < (int) 'z' - ARRAYBASE; i++) { /* Any linked arrays? */
8874 if (i != a && a_link[i] == a) { /* Find and update them */
8875 a_ptr[i] = p;
8876 a_dim[i] = n;
8877 }
8878 }
8879 return(rc);
8880 }
8881
8882 /* X A R R A Y -- Convert array name to array index */
8883
8884 int
xarray(s)8885 xarray(s) char * s; {
8886 char buf[8];
8887 int x;
8888 char c;
8889
8890 if (!s) s = "";
8891 debug(F110,"xarray",s,0);
8892 if (!*s)
8893 return(-1);
8894 x = strlen(s);
8895
8896 buf[0] = NUL;
8897 buf[1] = NUL;
8898 buf[2] = s[0];
8899 buf[3] = (x > 0) ? s[1] : NUL;
8900 buf[4] = (x > 1) ? s[2] : NUL;
8901 buf[5] = (x > 2) ? s[3] : NUL;
8902 buf[6] = NUL;
8903 debug(F110,"xarray buf[3]",&buf[3],0);
8904 s = buf+2;
8905 if (*s == '&') {
8906 buf[1] = CMDQ;
8907 s--;
8908 } else if (*s != CMDQ) {
8909 buf[0] = CMDQ;
8910 buf[1] = '&';
8911 s = buf;
8912 }
8913 debug(F110,"xarray s",s,0);
8914 c = *(s+2);
8915 if (isupper(c))
8916 c = tolower(c);
8917 if (c == '@')
8918 c = 96;
8919 x = (int)c - ARRAYBASE;
8920 if (*(s+3) == '[')
8921 *(s+3) = NUL;
8922 if (x < 0) {
8923 return(-1);
8924 }
8925 if (x > ('z' - ARRAYBASE)) {
8926 debug(F101,"xarray x out of range","",x);
8927 return(-1);
8928 }
8929 if (*(s+3)) {
8930 debug(F110,"xarray syntax",s,0);
8931 return(-1);
8932 }
8933 return(x);
8934 }
8935
8936 /*
8937 boundspair() -- parses blah[n:m]
8938
8939 For use with array segment specifiers and compact substring notation.
8940 Ignores the "blah" part, gets the values of n and m, which can be
8941 numbers, variables, or arithmetic expressions; anything that resolves
8942 to a number.
8943
8944 Call with:
8945 s - string to parse
8946 sep - array of permissible bounds separator chars
8947 lo - pointer to low-bound result (or -1)
8948 hi - pointer to hi-bound result (or -1)
8949 zz - pointer to separator char that was encountered (or NUL)
8950 Returns:
8951 -1 on failure
8952 0 on success
8953 */
8954
8955 int
8956 #ifdef CK_ANSIC
boundspair(char * s,char * sep,int * lo,int * hi,char * zz)8957 boundspair(char *s, char *sep, int *lo, int *hi, char *zz)
8958 #else
8959 boundspair(s,sep,lo,hi,zz) char *s, *sep, *zz; int *lo, *hi;
8960 #endif /* CK_ANSIC */
8961 {
8962 int i, x, y, range[2], bc = 0;
8963 char c = NUL, *s2 = NULL, buf[256], *p, *q, *r, *e[2], *tmp = NULL;
8964
8965 debug(F110,"boundspair s",s,0);
8966 debug(F110,"boundspair sep",sep,0);
8967
8968 *lo = -1; /* Default bounds */
8969 *hi = -1;
8970 *zz = 0; /* Default bounds separator */
8971
8972 range[0] = -1; /* It's OK -- get contents */
8973 range[1] = -1; /* of subscript brackets */
8974 if (!s) s = "";
8975 if (!*s)
8976 return(-1);
8977 makestr(&tmp,s); /* Make a pokeable copy */
8978 p = tmp;
8979 q = NULL;
8980 r = NULL;
8981 for (p = s; *p; p++) { /* Get the two elements */
8982 if (*p == '[') {
8983 bc++; /* Bracket counter */
8984 if (bc == 1 && !q) q = p+1;
8985 } else if (*p == ']') {
8986 bc--;
8987 if (bc == 0 && q) *p = NUL;
8988 } else if (bc == 1) { /* If within brackers */
8989 s2 = ckstrchr(sep,*p); /* Check for separator */
8990 if (s2) {
8991 debug(F000,"boundspair *s2","",*s2);
8992 if (c) {
8993 debug(F000,"boundspair","Too many separators",*s2);
8994 makestr(&tmp,NULL);
8995 return(-1);
8996 }
8997 c = *s2; /* Separator character */
8998 *p = NUL;
8999 r = p+1;
9000 }
9001 }
9002 }
9003 if (bc == 0 && !q) {
9004 /* This allows such constructions as "show array a" */
9005 debug(F110,"boundspair","no brackets",0);
9006 makestr(&tmp,NULL);
9007 return(0);
9008 }
9009 if (bc != 0 || !q) {
9010 debug(F110,"boundspair","unbalanced or missing brackets",0);
9011 makestr(&tmp,NULL);
9012 return(-1);
9013 }
9014 if (!q) q = "";
9015 if (!*q) q = "-1";
9016 if (!r) r = "";
9017 if (!*r) r = "-1";
9018
9019 e[0] = q;
9020 e[1] = r;
9021
9022 debug(F000,"boundspair c","",c);
9023 debug(F110,"boundspair q",q,0);
9024 debug(F110,"boundspair r",r,0);
9025
9026 for (i = 0; i < 2 && e[i]; i++) {
9027 y = 255; /* Expand variables, etc. */
9028 s = buf;
9029 zzstring(e[i],&s,&y);
9030 s = evalx(buf); /* Evaluate it arithmetically */
9031 if (s) if (*s)
9032 ckstrncpy(buf,s,256);
9033 if (!chknum(buf)) { /* Did we get a number? */
9034 debug(F110,"boundspair element not numeric",buf,0);
9035 makestr(&tmp,NULL); /* No, fail. */
9036 return(-1);
9037 }
9038 range[i] = atoi(buf);
9039 }
9040 makestr(&tmp,NULL); /* Free temporary poked string */
9041 *lo = range[0]; /* Return what we got */
9042 *hi = range[1];
9043 *zz = c;
9044 debug(F101,"boundspair lo","",*lo);
9045 debug(F101,"boundspair hi","",*hi);
9046 return(0);
9047 }
9048
9049 /* A R R A Y B O U N D S -- Parse array segment notation \&a[n:m] */
9050
9051 /*
9052 Call with s = array reference, plus two pointers to ints.
9053 Returns -1 on error, or array index, with the two ints set as follows:
9054 \&a[] -1, -1
9055 \&a[3] 3, -1
9056 \&a[3:17] 3, 17
9057 The array need not be declared -- this routine is just for parsing.
9058 */
9059 int
arraybounds(s,lo,hi)9060 arraybounds(s,lo,hi) char * s; int * lo, * hi; {
9061 int i, x, y, range[2];
9062 char zz, buf[256], * p, * q;
9063 char * tmp = NULL;
9064
9065 *lo = -1; /* Default bounds */
9066 *hi = -1;
9067
9068 if (!s) s = ""; /* Defense de null args */
9069 if (!*s)
9070 return(-1);
9071
9072 x = xarray(s); /* Check basic structure */
9073 debug(F111,"arraybounds xarray",s,x);
9074 if (x < 0) /* Not OK, fail. */
9075 return(-1);
9076 y = boundspair(s,":",lo,hi,&zz);
9077 debug(F111,"arraybounds boundspair",s,y);
9078 debug(F101,"arraybounds lo","",*lo);
9079 debug(F101,"arraybounds hi","",*hi);
9080 if (y < 0) /* Get bounds */
9081 return(-1);
9082 return(x);
9083 }
9084
9085 /* A R R A Y N A M -- Parse an array name */
9086
9087 /*
9088 Call with pointer to string that starts with the array reference.
9089 String may begin with either \& or just &.
9090 On success,
9091 Returns letter ID (always lowercase) in argument c,
9092 which can also be accent grave (` = 96; '@' is converted to grave);
9093 Dimension or subscript in argument n;
9094 IMPORTANT: These arguments must be provided by the caller as addresses
9095 of ints (not chars), for example:
9096 char *s; int x, y;
9097 arraynam(s,&x,&y);
9098 On failure, returns a negative number, with args n and c set to zero.
9099 */
9100 int
arraynam(ss,c,n)9101 arraynam(ss,c,n) char *ss; int *c; int *n; {
9102 int i, y, pp, len;
9103 char x;
9104 char *s, *p, *sx, *vnp;
9105 /* On stack to allow for recursive calls... */
9106 char vnbuf[ARRAYREFLEN+1]; /* Entire array reference */
9107 char ssbuf[ARRAYREFLEN+1]; /* Subscript in "plain text" */
9108 char sxbuf[16]; /* Evaluated subscript */
9109
9110 *c = *n = 0; /* Initialize return values */
9111 len = strlen(ss);
9112 for (pp = 0,i = 0; i < len; i++) { /* Check length */
9113 if (ss[i] == '[') {
9114 pp++;
9115 } else if (ss[i] == ']') {
9116 if (--pp == 0)
9117 break;
9118 }
9119 }
9120 if (i > ARRAYREFLEN) {
9121 printf("?Array reference too long - %s\n",ss);
9122 return(-9);
9123 }
9124 ckstrncpy(vnbuf,ss,ARRAYREFLEN);
9125 vnp = vnbuf;
9126 if (vnbuf[0] == CMDQ && vnbuf[1] == '&') vnp++;
9127 if (*vnp != '&') {
9128 printf("?Not an array - %s\n",vnbuf);
9129 return(-9);
9130 }
9131 x = *(vnp + 1); /* Fold case of array name */
9132
9133 /* We don't use isupper & tolower here on purpose because these */
9134 /* would produce undesired effects with accented letters. */
9135 if (x > 63 && x < 91) x = *(vnp + 1) = (char) (x + 32);
9136 if ((x < ARRAYBASE) || (x > 122) || (*(vnp+2) != '[')) {
9137 if (msgflg) {
9138 printf("?Invalid format for array name - %s\n",vnbuf);
9139 return(-9);
9140 } else
9141 return(-2);
9142 }
9143 *c = x; /* Return the array name */
9144 s = vnp+3; /* Get dimension */
9145 p = ssbuf;
9146 pp = 1; /* Bracket counter */
9147 for (i = 0; i < ARRAYREFLEN && *s != NUL; i++) { /* Copy up to ] */
9148 if (*s == '[') pp++;
9149 if (*s == ']' && --pp == 0) break;
9150 *p++ = *s++;
9151 }
9152 if (*s != ']') {
9153 printf("?No closing bracket on array dimension - %s\n",vnbuf);
9154 return(-9);
9155 }
9156 p--; /* Trim whitespace from end */
9157 while (*p == SP || *p == HT)
9158 p--;
9159 p++;
9160 *p = NUL; /* Terminate subscript with null */
9161 p = ssbuf; /* Point to beginning of subscript */
9162 while (*p == SP || *p == HT) /* Trim whitespace from beginning */
9163 p++;
9164 sx = sxbuf; /* Where to put expanded subscript */
9165 y = 16;
9166 {
9167 /* Even if VARIABLE-EVALUATION SIMPLE use RECURSIVE for subscripts */
9168 /* NOTE: This is vulnerable to SIGINT and whatnot... */
9169 int tmp = vareval; /* Save VARIABLE-EVALUATION setting */
9170 vareval = 1; /* Force it to RECURSIVE */
9171 zzstring(p,&sx,&y); /* Convert variables, etc. */
9172 vareval = tmp; /* Restore VARIABLE-EVALUATION */
9173 }
9174 sx = sxbuf;
9175 while (*sx == SP) sx++;
9176 /* debug(F110,"arraynam sx","",sx); */
9177 if (!*sx) { /* Empty brackets... */
9178 *n = -17; /* (Secret code :-) */
9179 return(-2);
9180 }
9181 p = evala(sx); /* Run it thru \fneval()... */
9182 if (p) if (*p) ckstrncpy(sxbuf,p,16); /* We know it has to be a number. */
9183
9184 if (!chknum(sxbuf)) { /* Make sure it's all digits */
9185 if (msgflg) {
9186 printf("?Array dimension or subscript missing or not numeric\n");
9187 return(-9);
9188 } else
9189 return(-2);
9190 }
9191 if ((y = atoi(sxbuf)) < 0) {
9192 if (cmflgs == 0) printf("\n");
9193 if (msgflg) {
9194 printf("?Array dimension or subscript not positive or zero\n");
9195 return(-9);
9196 } else
9197 return(-2);
9198 }
9199 *n = y; /* Return the subscript or dimension */
9200 return(0);
9201 }
9202
9203 /* chkarray returns 0 or greater if array exists, negative otherwise */
9204
9205 int
chkarray(a,i)9206 chkarray(a,i) int a, i; { /* Check if array is declared */
9207 int x; /* and if subscript is in range */
9208 if (a == 64) a = 96; /* Convert atsign to grave accent */
9209 x = a - ARRAYBASE; /* Values must be in range 95-122 */
9210 #ifdef COMMENT
9211 if (x == 0 && maclvl < 0) /* Macro arg vector but no macro */
9212 return(0);
9213 #endif /* COMMENT */
9214 if (x < 0 || x > 'z' - ARRAYBASE) /* Not in range */
9215 return(-2);
9216 if (a_ptr[x] == NULL) return(-1); /* Not declared */
9217 if (i > a_dim[x]) return(-2); /* Declared but out of range. */
9218 return(a_dim[x]); /* All ok, return dimension */
9219 }
9220
9221 #ifdef COMMENT /* This isn't used. */
9222 char *
arrayval(a,i)9223 arrayval(a,i) int a, i; { /* Return value of \&a[i] */
9224 int x; char **p; /* (possibly NULL) */
9225 if (a == 64) a = 96; /* Convert atsign to grave accent */
9226 x = a - ARRAYBASE; /* Values must be in range 95-122 */
9227 if (x < 0 || x > 27) return(NULL); /* Not in range */
9228 if ((x > 0) && (p = a_ptr[x]) == NULL) /* Array not declared */
9229 return(NULL);
9230 if (i > a_dim[x]) /* Subscript out of range. */
9231 return(NULL);
9232 return(p[i]); /* All ok, return pointer to value. */
9233 }
9234 #endif /* COMMENT */
9235
9236 /*
9237 pusharray() is called when an array name is included in a LOCAL statement.
9238 It moves the pointers from the global definition to the stack, and removes
9239 the global definition. Later, if the same array is declared in the local
9240 context, it occupies the global definition in the normal way. But when
9241 popclvl() is called, it replaces the global definition with the one saved
9242 here. The "secret code" is used to indicate to popclv() that it should
9243 remove the global array when popping through this level -- otherwise if a
9244 local array were declared that had no counterpart at any higher level, it
9245 would never be deleted. This allows Algol-like inheritance to work both
9246 on the way down and on the way back up.
9247 */
9248 int
pusharray(x,z)9249 pusharray(x,z) int x, z; {
9250 int y;
9251 debug(F000,"pusharray x","",x);
9252 debug(F101,"pusharray z","",z);
9253 y = chkarray(x,z);
9254 debug(F101,"pusharray y","",y);
9255 x -= ARRAYBASE; /* Convert name letter to index. */
9256 if (x < 0 || x > 27)
9257 return(-1);
9258 if (y < 0) {
9259 aa_ptr[cmdlvl][x] = (char **) NULL;
9260 aa_dim[cmdlvl][x] = -23; /* Secret code (see popclvl()) */
9261 } else {
9262 aa_ptr[cmdlvl][x] = a_ptr[x];
9263 aa_dim[cmdlvl][x] = y;
9264 }
9265 a_ptr[x] = (char **) NULL;
9266 a_dim[x] = 0;
9267 return(0);
9268 }
9269
9270 /* P A R S E V A R -- Parse a variable name or array reference. */
9271 /*
9272 Call with:
9273 s = pointer to candidate variable name or array reference.
9274 *c = address of integer in which to return variable ID.
9275 *i = address of integer in which to return array subscript.
9276 Returns:
9277 -2: syntax error in variable name or array reference.
9278 1: successful parse of a simple variable, with ID in c.
9279 2: successful parse of an array reference, w/ID in c and subscript in i.
9280 */
9281 int
parsevar(s,c,i)9282 parsevar(s,c,i) char *s; int *c, *i; {
9283 char *p;
9284 int x,y,z;
9285
9286 p = s;
9287 if (*s == CMDQ) s++; /* Point after backslash */
9288
9289 if (*s != '%' && *s != '&') { /* Make sure it's % or & */
9290 printf("?Not a variable name - %s\n",p);
9291 return(-9);
9292 }
9293 if ((int)strlen(s) < 2) {
9294 printf("?Incomplete variable name - %s\n",p);
9295 return(-9);
9296 }
9297 if (*s == '%' && *(s+2) != '\0') {
9298 printf("?Only one character after '%%' in variable name, please\n");
9299 return(-9);
9300 }
9301 if (*s == '&' && *(s+2) != '[') {
9302 printf("?Array subscript expected - %s\n",p);
9303 return(-9);
9304 }
9305 if (*s == '%') { /* Simple variable. */
9306 y = *(s+1); /* Get variable ID letter/char */
9307 if (isupper(y)) y -= ('a'-'A'); /* Convert upper to lower case */
9308 *c = y; /* Set the return values. */
9309 *i = -1; /* No array subscript. */
9310 return(1); /* Return 1 = simple variable */
9311 }
9312 if (*s == '&') { /* Array reference. */
9313 y = arraynam(s,&x,&z); /* Go parse it. */
9314 debug(F101,"parsevar arraynam","",y);
9315 if ((y) < 0) {
9316 if (y == -2)
9317 return(pusharray(x,z));
9318 if (y != -9)
9319 printf("?Invalid array reference - %s\n",p);
9320 return(-9);
9321 }
9322 if (chkarray(x,z) < 0) { /* Check if declared, etc. */
9323 printf("?Array not declared or subscript out of range\n");
9324 return(-9);
9325 }
9326 *c = x; /* Return array letter */
9327 *i = z; /* and subscript. */
9328 return(2);
9329 }
9330 return(-2); /* None of the above. */
9331 }
9332
9333
9334 #define VALN 32
9335
9336 /* Get the numeric value of a variable */
9337 /*
9338 Call with pointer to variable name, pointer to int for return value.
9339 Returns:
9340 0 on success with second arg containing the value.
9341 -1 on failure (bad variable syntax, variable not defined or not numeric).
9342 */
9343 int
varval(s,v)9344 varval(s,v) char *s; CK_OFF_T *v; {
9345 char valbuf[VALN+1]; /* s is pointer to variable name */
9346 char name[256];
9347 char *p;
9348 int y;
9349
9350 if (*s != CMDQ) { /* Handle macro names too */
9351 ckmakmsg(name,256,"\\m(",s,")",NULL);
9352 s = name;
9353 }
9354 p = valbuf; /* Expand variable into valbuf. */
9355 y = VALN;
9356 if (zzstring(s,&p,&y) < 0) return(-1);
9357 p = valbuf; /* Make sure value is numeric */
9358 if (!*p) { /* Be nice -- let an undefined */
9359 valbuf[0] = '0'; /* variable be treated as 0. */
9360 valbuf[1] = NUL;
9361 }
9362 if (chknum(p)) { /* Convert numeric string to int */
9363 *v = ckatofs(p); /* OK */
9364 } else { /* Not OK */
9365 p = evala(p); /* Maybe it's an expression */
9366 if (!chknum(p)) /* Did it evaluate? */
9367 return(-1); /* No, failure. */
9368 else /* Yes, */
9369 *v = ckatofs(p); /* success */
9370 }
9371 return(0);
9372 }
9373
9374 /* Increment or decrement a variable */
9375 /* Returns -1 on failure, 0 on success */
9376
9377 int
incvar(s,x,z)9378 incvar(s,x,z) char *s; CK_OFF_T x; int z; { /* Increment a numeric variable */
9379 CK_OFF_T n; /* s is pointer to variable name */
9380 /* x is amount to increment by */
9381 /* z != 0 means add */
9382 /* z = 0 means subtract */
9383 if (varval(s,&n) < 0) /* Convert numeric string to int */
9384 return(-1);
9385 if (z) /* Increment it by the given amount */
9386 n += x;
9387 else /* or decrement as requested. */
9388 n -= x;
9389 addmac(s,ckfstoa(n)); /* Replace old variable */
9390 return(0);
9391 }
9392
9393 /* D O D O -- Do a macro */
9394
9395 /*
9396 Call with x = macro table index, s = pointer to arguments.
9397 Returns 0 on failure, 1 on success.
9398 */
9399 int
dodo(x,s,flags)9400 dodo(x,s,flags) int x; char *s; int flags; {
9401 int y;
9402 extern int tra_asg, tra_cmd; int tra_tmp; /* For TRACE */
9403 #ifndef NOLOCAL
9404 #ifdef OS2
9405 extern int term_io;
9406 int term_io_sav = term_io;
9407 #endif /* OS2 */
9408 #endif /* NOLOCAL */
9409
9410 if (x < 0) /* It can happen! */
9411 return(-1);
9412
9413 tra_tmp = tra_asg;
9414
9415 if (++maclvl >= MACLEVEL) { /* Make sure we have storage */
9416 debug(F101,"dodo maclvl too deep","",maclvl);
9417 --maclvl;
9418 printf("Macros nested too deeply\n");
9419 return(0);
9420 }
9421 macp[maclvl] = mactab[x].mval; /* Point to the macro body */
9422 macx[maclvl] = mactab[x].mval; /* Remember where the beginning is */
9423
9424 #ifdef COMMENT
9425 makestr(&(m_line[maclvl]),s); /* Entire arg string for "\%*" */
9426 #endif /* COMMENT */
9427
9428 cmdlvl++; /* Entering a new command level */
9429 if (cmdlvl >= CMDSTKL) { /* Too many macros + TAKE files? */
9430 debug(F101,"dodo cmdlvl too deep","",cmdlvl);
9431 cmdlvl--;
9432 printf("?TAKE files and DO commands nested too deeply\n");
9433 return(0);
9434 }
9435 #ifdef DEBUG
9436 if (deblog) {
9437 debug(F111,"CMD +M",mactab[x].kwd,cmdlvl);
9438 debug(F010,"CMD ->",s,0);
9439 }
9440 #endif /* DEBUG */
9441
9442 #ifdef VMS
9443 conres(); /* So Ctrl-C, etc, will work. */
9444 #endif /* VMS */
9445 #ifndef NOLOCAL
9446 #ifdef OS2
9447 term_io = 0; /* Disable terminal emulator I/O */
9448 #endif /* OS2 */
9449 #endif /* NOLOCAL */
9450 ifcmd[cmdlvl] = 0;
9451 iftest[cmdlvl] = 0;
9452 count[cmdlvl] = count[cmdlvl-1]; /* Inherit COUNT from previous level */
9453 intime[cmdlvl] = intime[cmdlvl-1]; /* Inherit previous INPUT TIMEOUT */
9454 inpcas[cmdlvl] = inpcas[cmdlvl-1]; /* and INPUT CASE */
9455 takerr[cmdlvl] = takerr[cmdlvl-1]; /* and TAKE ERROR */
9456 merror[cmdlvl] = merror[cmdlvl-1]; /* and MACRO ERROR */
9457 xquiet[cmdlvl] = quiet;
9458 xvarev[cmdlvl] = vareval;
9459 xcmdsrc = CMD_MD;
9460 cmdstk[cmdlvl].src = CMD_MD; /* Say we're in a macro */
9461 cmdstk[cmdlvl].lvl = maclvl; /* and remember the macro level */
9462 cmdstk[cmdlvl].ccflgs = flags & ~CF_IMAC; /* Set flags */
9463
9464 /* Initialize return value except in FOR, WHILE, IF, and SWITCH macros */
9465
9466 if (!(flags & CF_IMAC) && mrval[maclvl]) {
9467 free(mrval[maclvl]);
9468 mrval[maclvl] = NULL;
9469 }
9470
9471 /* Clear old %0..%9 arguments */
9472
9473 addmac("%0",mactab[x].kwd); /* Define %0 = name of macro */
9474 makestr(&(m_xarg[maclvl][0]),mactab[x].kwd);
9475 varnam[0] = '%';
9476 varnam[2] = '\0';
9477 tra_asg = 0;
9478 for (y = 1; y < 10; y++) { /* Clear args %1..%9 */
9479 if (m_arg[maclvl][y]) { /* Don't call delmac() unless */
9480 varnam[1] = (char) (y + '0'); /* we have to... */
9481 delmac(varnam,0);
9482 }
9483 }
9484 tra_asg = tra_tmp;
9485
9486 /* Break the big "s" string up into macro arguments */
9487
9488 xwords(s,MAXARGLIST,NULL,0);
9489
9490 #ifndef NOLOCAL
9491 #ifdef OS2
9492 term_io = term_io_sav;
9493 #endif /* OS2 */
9494 #endif /* NOLOCAL */
9495 if (tra_cmd)
9496 printf("[%d] +M: \"%s\"\n",cmdlvl,mactab[x].kwd);
9497 return(1);
9498 }
9499
9500 /* Insert "literal" quote around each comma-separated command to prevent */
9501 /* its premature expansion. Only do this if object command is surrounded */
9502 /* by braces. */
9503
9504 static char* flit = "\\flit(";
9505
9506 int
litcmd(src,dest,n)9507 litcmd(src,dest,n) char **src, **dest; int n; {
9508 int bc = 0, pp = 0;
9509 char c, *s, *lp, *ss;
9510
9511 s = *src;
9512 lp = *dest;
9513
9514 debug(F010,"litcmd",s,0);
9515
9516 while (*s == SP) s++; /* Strip extra leading spaces */
9517
9518 if (*s == '{') { /* Starts with brace */
9519 pp = 0; /* Paren counter */
9520 bc = 1; /* Count leading brace */
9521 *lp++ = *s++; /* Copy it */
9522 if (--n < 1) return(-1); /* Check space */
9523 while (*s == SP) s++; /* Strip interior leading spaces */
9524 ss = flit; /* Point to "\flit(" */
9525 while ((*lp++ = *ss++)) /* Copy it */
9526 if (--n < 1) /* and check space */
9527 return(-1);
9528 lp--; /* Back up over null */
9529
9530 while (*s) { /* Go thru rest of text */
9531 c = *s;
9532 if (c == '{') bc++; /* Count brackets */
9533 if (c == '(') pp++; /* and parens */
9534 if (c == ')') { /* Right parenthesis. */
9535 pp--; /* Count it. */
9536 if (pp < 0) { /* An unbalanced right paren... */
9537 #ifdef COMMENT
9538 /*
9539 The problem here is that "\{" appears to be a quoted brace and therefore
9540 isn't counted; then the "}" matches an earlier opening brace, causing
9541 (e.g.) truncation of macros by getncm().
9542 */
9543 if (n < 5) /* Out of space in dest buffer? */
9544 return(-1); /* If so, give up. */
9545 *lp++ = CMDQ; /* Must be quoted to prevent */
9546 *lp++ = '}'; /* premature termination of */
9547 *lp++ = '4'; /* \flit(...) */
9548 *lp++ = '1';
9549 *lp++ = '}';
9550 n -= 5;
9551 #else
9552 /* Here we rely on the fact the \nnn never takes more than 3 digits */
9553 if (n < 4) /* Out of space in dest buffer? */
9554 return(-1); /* If so, give up. */
9555 *lp++ = CMDQ; /* Must be quoted to prevent */
9556 *lp++ = '0'; /* premature termination of */
9557 *lp++ = '4'; /* \flit(...) */
9558 *lp++ = '1';
9559 n -= 4;
9560 #endif /* COMMENT */
9561 pp++; /* Uncount it. */
9562 s++;
9563 continue;
9564 }
9565 }
9566 if (c == '}') { /* Closing brace. */
9567 if (--bc == 0) { /* Final one? */
9568 *lp++ = ')'; /* Add closing paren for "\flit()" */
9569 if (--n < 1) return(-1);
9570 *lp++ = c;
9571 if (--n < 1) return(-1);
9572 s++;
9573 break;
9574 }
9575 }
9576 *lp++ = c; /* General case */
9577 if (--n < 1) return(-1);
9578 s++;
9579 }
9580 *lp = NUL;
9581 } else { /* No brackets around, */
9582 while ((*lp++ = *s++)) /* just copy. */
9583 if (--n < 1)
9584 return(-1);
9585 lp--;
9586 }
9587 *src = s; /* Return updated source */
9588 *dest = lp; /* and destination pointers */
9589 if (bc) /* Fail if braces unbalanced */
9590 return(-1);
9591 else /* Otherwise succeed. */
9592 return(0);
9593 }
9594 #endif /* NOSPL */
9595
9596 /* Functions moved here from ckuusr.c to even out the module sizes... */
9597
9598 /*
9599 Breaks up string s -- IN PLACE! -- into a list of up to max words.
9600 Pointers to each word go into the array list[].
9601 max is the maximum number of words (pointers).
9602 If list is NULL, then they are added to the macro table.
9603 flag = 0 means the last field is to be one word, like all the other fields,
9604 so anything after it is discarded.
9605 flag = 1 means the last field extends to the end of the string, even if
9606 there are lots of words left, so the last field contains the
9607 remainder of the string.
9608 */
9609 VOID
xwords(s,max,list,flag)9610 xwords(s,max,list,flag) char *s; int max; char *list[]; int flag; {
9611 char *p;
9612 int b, i, k, q, y, z;
9613 int macro = 0;
9614
9615 if (!list) {
9616 debug(F100," xwords list is NULL","",0);
9617 macro = 1;
9618 } else {
9619 debug(F100," xwords LIST is defined","",0);
9620 }
9621 debug(F100,"xwords ENTRY","",0);
9622
9623 #ifndef NOSPL
9624 /*
9625 debug(F110," xwords macro",(char *)m_xarg[maclvl][0],0);
9626 */
9627 debug(F101," xwords maclvl","",maclvl);
9628 debug(F101," xwords max","",max);
9629 debug(F101," xwords flag","",flag);
9630 debug(F110," xwords string",s,0);
9631 debug(F101," xwords macro","",macro);
9632 #endif /* NOSPL */
9633
9634 p = s; /* Pointer to beginning of string */
9635 q = 0; /* Flag for doublequote removal */
9636 b = 0; /* Flag for outer brace removal */
9637 k = 0; /* Flag for in-word */
9638 y = 0; /* Brace nesting level */
9639 z = 0; /* "Word" counter, 0 thru max */
9640
9641 if (!s) s = ""; /* Nothing to do */
9642 if (!*s) return;
9643 if (list)
9644 for (i = 0; i <= max; i++) /* Initialize pointers */
9645 list[i] = NULL;
9646
9647 if (flag) max--;
9648
9649 #ifndef NOSPL
9650 /*
9651 Macro arguments at this point are a single string... must split it up.
9652 As of C-Kermit 9.0.304 Dev.22, 24 April 2017, we use cksplit() for
9653 this instead of tons of messy code in xwords() written decades ago
9654 to do what cksplit() does better.
9655 */
9656 if (macro) {
9657 struct stringarray * q = NULL;
9658 char **pp = NULL;
9659 int n;
9660 if (maclvl < 0) {
9661 debug(F101," xwords maclvl < 0","",maclvl);
9662 newerrmsg("Internal error: maclvl < 0");
9663 }
9664 debug(F101," xwords splitting macro arguments.. maclvl","",maclvl);
9665
9666 /* Space is the only separator; grouping is with "" or {} */
9667 q = cksplit(1,0,p," ","ALL",1+2,0,0,1);
9668 z = q->a_size; /* Number of "words" in string */
9669 if (z <= 0) return;
9670 pp = q->a_head;
9671 if (pp) {
9672 /*
9673 In C-Kermit 9.0.304 Dev.22, April 2017, we have to get the macro arguments
9674 from the previous macro level (prev). Up to now, the macro arguments were
9675 evaluated when the DO command was parsed, before dodo() or xwords() were
9676 ever called. Now we're evaluating them after already entering the new macro
9677 stack level: evalmacroarg() is just a front end for zzstring(), which is at
9678 the heart of all variable-substitution operations. To evaluate a \%1-9
9679 variable, zzstring() looks in the CURRENT macro stack frame. Rather than
9680 mess with zzstring(), I set maclvl back before calling evalmacroarg() and
9681 restore it immediately afterward. It's the only safe way to do this,
9682 Because zzstring() has no way of knowing whether (say) \%1 is on the DO
9683 command line or in some other context.
9684 */
9685 debug(F101," xwords macro cksplit items","",z);
9686 if (z > max) z = max;
9687 for (i = 1; i <= z; i++) { /* Loop through macro arguments. */
9688 p = pp[i];
9689 debug(F111," xwords arg i",p,i);
9690 maclvl--; /* Get argument from previous level */
9691 evalmacroarg(&p); /* Evaluate it */
9692 maclvl++; /* Use its value on currentlevel */
9693 debug(F111," xwords arg i evaluated",p,i);
9694 makestr(&(m_xarg[maclvl][i]),p);
9695 if (i < 10) {
9696 varnam[1] = (char) (i + '0'); /* Assign last arg */
9697 addmac(varnam,p);
9698 debug(F111," xwords arg name",varnam,maclvl);
9699 debug(F111," xwords def def ",p,maclvl);
9700 }
9701 }
9702 /* Handle argc and the dimension of the \&_[] arg vector array */
9703
9704 if (maclvl < 0) { /* (How can this be?) */
9705 a_dim[0] = z; /* Array dimension is one less */
9706 topargc = z + 1; /* than \v(argc) */
9707 debug(F111," xwords a_dim[0]","IMPOSSIBLE",a_dim[0]);
9708 } else {
9709 macargc[maclvl] = z + 1; /* Set \v(argc) variable */
9710 n_xarg[maclvl] = z + 1; /* This is the actual number */
9711 a_ptr[0] = m_xarg[maclvl]; /* Point \&_[] at the args */
9712 a_dim[0] = z; /* And give it this dimension */
9713 debug(F111," xwords a_dim[0]","E",a_dim[0]);
9714 }
9715 }
9716 return;
9717 }
9718 #endif /* NOSPL */
9719 /*
9720 Not macro args, some other kind of list.
9721 This whole mess could be a cksplit() call...
9722 */
9723 while (1) { /* Go thru word list */
9724 if (!s || (*s == '\0')) { /* No more characters? */
9725 if (k != 0) { /* Was I in a word? */
9726 if (z == max) break; /* Yes, only go up to max. */
9727 z++; /* Count this word. */
9728 list[z] = p; /* Assign pointer. */
9729 debug(F111," xwords list item p z",p,z);
9730 }
9731 break; /* And get out. */
9732 }
9733 if (k == 0 && (*s == SP || *s == HT)) { /* Eat leading blanks */
9734 s++;
9735 continue;
9736 } else if (q == 0 && *s == '{') { /* An opening brace */
9737 if (k == 0 && y == 0) { /* If leading brace */
9738 p = s+1; /* point past it */
9739 b = 1; /* and flag that we did this */
9740 }
9741 k = 1; /* Flag that we're in a word */
9742 y++; /* Count the brace. */
9743 } else if (q == 0 && *s == '}') { /* A closing brace. */
9744 y--; /* Count it. */
9745 if (y <= 0 && b != 0) { /* If it matches the leading brace */
9746 char c;
9747 c = *(s+1);
9748 if (!c || c == SP || c == HT) { /* at EOL or followed by SP */
9749 *s = SP; /* change it to a space */
9750 b = 0; /* and we're not in braces any more */
9751 }
9752 }
9753 #ifdef DOUBLEQUOTING
9754 /* Opening doublequote */
9755 } else if (k == 0 && b == 0 && *s == '"' && dblquo) {
9756 y++;
9757 p = s+1; /* point past it */
9758 q = 1; /* and flag that we did this */
9759 k = 1; /* Flag that we're in a word */
9760 /* Closing double quote */
9761 } else if (q > 0 && k > 0 && b == 0 && *s == '"' && dblquo) {
9762 char c;
9763 c = *(s+1);
9764 if (!c || c == SP || c == HT) { /* at EOL or followed by SP */
9765 y--;
9766 *s = SP; /* change it to a space */
9767 q = 0; /* and we're not in quotes any more */
9768 }
9769 #endif /* DOUBLEQUOTING */
9770
9771 } else if (*s != SP && *s != HT) { /* Nonspace means we're in a word */
9772 if (k == 0) { /* If we weren't in a word before, */
9773 p = s; /* Mark the beginning */
9774 if (flag && z == max) { /* Want last word to be remainder? */
9775 z++;
9776 list[z] = p; /* Yes, point to it */
9777 break; /* and quit */
9778 }
9779 k = 1; /* Set in-word flag */
9780 }
9781 }
9782 /* If we're not inside a braced quantity, and we are in a word, and */
9783 /* we have hit whitespace, then we have a word. */
9784 if ((y < 1) && (k != 0) && (*s == SP || *s == HT) && !b) {
9785 if (!flag || z < max) /* if we don't want to keep rest */
9786 *s = '\0'; /* terminate the arg with null */
9787 k = 0; /* say we're not in a word any more */
9788 y = 0; /* start braces off clean again */
9789 if (z == max) break; /* Only go up to max. */
9790 z++; /* count this arg */
9791 list[z] = p;
9792 p = s+1;
9793 }
9794 s++; /* Point past this character */
9795 }
9796 if ((z == 0) && (y > 1)) { /* Extra closing brace(s) at end */
9797 z++;
9798 list[z] = p;
9799 }
9800 return;
9801 }
9802
9803 #ifndef NOSPL
9804
9805 /* D O S H I F T -- Do the SHIFT Command; shift macro args left by n */
9806
9807 /* Note: at some point let's consolidate m_arg[][] and m_xarg[][]. */
9808
9809 int
doshift(n)9810 doshift(n) int n; { /* n = shift count */
9811 int i, top, level;
9812 char /* *s, *m, */ buf[6]; /* Buffer to build scalar names */
9813 char * sx = tmpbuf;
9814 int nx = TMPBUFSIZ;
9815
9816 debug(F101,"SHIFT count","",n);
9817 debug(F101,"SHIFT topargc","",topargc);
9818
9819 if (n < 1) /* Stay in range */
9820 return(n == 0 ? 1 : 0);
9821
9822 level = maclvl;
9823 top = (level < 0) ? topargc : macargc[level];
9824
9825 if (n >= top)
9826 n = top - 1;
9827
9828 #ifdef DEBUG
9829 if (deblog) {
9830 debug(F101,"SHIFT count 2","",n);
9831 debug(F101,"SHIFT level","",level);
9832 if (level > -1)
9833 debug(F101,"SHIFT macargc[level]","",macargc[level]);
9834 }
9835 #endif /* DEBUG */
9836
9837 buf[0] = '\\'; /* Initialize name template */
9838 buf[1] = '%';
9839 buf[2] = NUL;
9840 buf[3] = NUL;
9841
9842 for (i = 1; i <= n; i++) { /* Free shifted-over args */
9843 if (level < 0) {
9844 makestr(&(toparg[i]),NULL);
9845 } else {
9846 makestr(&(m_xarg[level][i]),NULL);
9847 }
9848 if (i < 10) { /* Is this necessary? */
9849 buf[2] = (char)(i+'0');
9850 delmac(buf,0);
9851 }
9852 }
9853 for (i = 1; i <= top-n; i++) { /* Shift remaining args */
9854 if (level < 0) {
9855 #ifdef COMMENT
9856 toparg[i] = toparg[i+n]; /* Full vector */
9857 #else
9858 makestr(&(toparg[i]),toparg[i+n]); /* Full vector */
9859 #endif /* COMMENT */
9860 if (i < 10) /* Scalars... */
9861 makestr(&(g_var[i+'0']),toparg[i+n]);
9862 } else {
9863 #ifdef COMMENT
9864 m_xarg[level][i] = m_xarg[level][i+n];
9865 #else
9866 makestr(&(m_xarg[level][i]),m_xarg[level][i+n]);
9867 #endif /* COMMENT */
9868 if (i < 10) {
9869 buf[2] = (char)(i+'0');
9870 debug(F010,"SHIFT buf",buf,0);
9871 addmac(buf,m_xarg[level][i+n]);
9872 }
9873 }
9874 }
9875 for (i = top-n; i <= top; i++) { /* Clear n args from the end */
9876 if (level < 0) {
9877 #ifdef COMMENT
9878 toparg[i] = NULL;
9879 #else
9880 makestr(&(toparg[i]),NULL);
9881 #endif /* COMMENt */
9882 if (i < 10)
9883 makestr(&(g_var[i+'0']),NULL);
9884 } else {
9885 #ifdef COMMENT
9886 m_xarg[level][i] = NULL;
9887 #else
9888 makestr(&(m_xarg[level][i]),NULL);
9889 #endif /* COMMENt */
9890 if (i < 10) {
9891 buf[2] = (char)(i+'0');
9892 delmac(buf,0);
9893 }
9894 }
9895 }
9896 if (level > -1) { /* Macro args */
9897 macargc[level] -= n; /* Adjust count */
9898 n_xarg[maclvl] = macargc[level]; /* Here too */
9899 a_dim[0] = macargc[level] - 1; /* Adjust array dimension */
9900 debug(F111,"a_dim[0]","F",a_dim[0]);
9901 zzstring("\\fjoin(&_[],{ },1)",&sx,&nx); /* Handle \%* */
9902 #ifdef COMMENT
9903 makestr(&(m_line[level]),tmpbuf);
9904 #endif /* COMMENT */
9905 } else { /* Ditto for top level */
9906 topargc -= n;
9907 a_dim[0] = topargc - 1;
9908 debug(F111,"a_dim[0]","G",a_dim[0]);
9909 zzstring("\\fjoin(&_[],{ },1)",&sx,&nx);
9910 #ifdef COMMENT
9911 makestr(&topline,tmpbuf);
9912 #endif /* COMMENT */
9913 }
9914 return(1);
9915 }
9916 #endif /* NOSPL */
9917
9918 int
docd(cx)9919 docd(cx) int cx; { /* Do the CD command */
9920 int x;
9921 extern int server, srvcdmsg, cdactive;
9922 extern char * cdmsgfile[], * ckcdpath;
9923 char *s, *p;
9924 #ifdef MAC
9925 char temp[34];
9926 #endif /* MAC */
9927 #ifdef IKSDCONF
9928 extern int iksdcf;
9929 #endif /* IKSDCONF */
9930
9931 #ifndef NOFRILLS
9932 if (cx == XXBACK) {
9933 if ((x = cmcfm()) < 0)
9934 cwdf = 1;
9935 if (prevdir) {
9936 s = zgtdir();
9937 if (!zchdir(prevdir)) {
9938 cwdf = 0;
9939 perror(s);
9940 } else {
9941 makestr(&prevdir,s);
9942 }
9943 }
9944 return(cwdf);
9945 }
9946 #endif /* NOFRILLS */
9947
9948 if (cx == XXCDUP) {
9949 #ifdef VMS
9950 s = "[-]";
9951 #else
9952 #ifdef datageneral
9953 s = "^";
9954 #else
9955 s = "..";
9956 #endif /* datageneral */
9957 #endif /* VMS */
9958 ckstrncpy(line,s,LINBUFSIZ);
9959 goto gocd;
9960 }
9961 #ifndef NOSPL
9962 if (cx == XXKCD) { /* Symbolic (Kermit) CD */
9963 char * p;
9964 int n, k;
9965 x = cmkey(kcdtab,nkcdtab,"Symbolic directory name","home",xxstring);
9966 if (x < 0)
9967 return(x);
9968 x = lookup(kcdtab,atmbuf,nkcdtab,&k); /* Get complete keyword */
9969 if (x < 0) {
9970 printf("?Lookup error\n"); /* shouldn't happen */
9971 return(-9);
9972 }
9973 if ((x = cmcfm()) < 0)
9974 return(x);
9975 if (k == VN_HOME) { /* HOME: allow SET HOME to override */
9976 ckstrncpy(line,homepath(),LINBUFSIZ);
9977 } else { /* Other symbolic name */
9978 /* Convert to variable syntax */
9979 ckmakmsg(tmpbuf,TMPBUFSIZ,"\\v(",kcdtab[k].kwd,")",NULL);
9980 p = line; /* Expand the variable */
9981 n = LINBUFSIZ;
9982 zzstring(tmpbuf,&p,&n);
9983 if (!line[0]) { /* Fail if variable not defined */
9984 printf("?%s - not defined\n",tmpbuf);
9985 return(success = 0);
9986 }
9987 }
9988 s = line; /* All OK, go try to CD... */
9989 goto gocd;
9990 }
9991 #endif /* NOSPL */
9992
9993 cdactive = 1;
9994 #ifdef GEMDOS
9995 if ((x = cmdir("Name of local directory, or carriage return",
9996 homepath(),
9997 &s,
9998 NULL
9999 )
10000 ) < 0 )
10001 return(x);
10002 #else
10003 #ifdef OS2
10004 if ((x = cmdirp("Name of PC disk and/or directory,\n\
10005 or press the Enter key for the default",
10006 homepath(),
10007 &s,
10008 ckcdpath ? ckcdpath : getenv("CDPATH"),
10009 xxstring
10010 )
10011 ) < 0 )
10012 return(x);
10013 #else
10014 #ifdef MAC
10015 x = ckstrncpy(temp,homepath(),32);
10016 if (x > 0) if (temp[x-1] != ':') { temp[x] = ':'; temp[x+1] = NUL; }
10017 if ((x = cmtxt("Name of Macintosh volume and/or folder,\n\
10018 or press the Return key for the desktop on the boot disk",
10019 temp,&s, xxstring)) < 0 )
10020 return(x);
10021 #else
10022 if ((x = cmdirp("Carriage return for home directory,\n\
10023 or name of directory on this computer",
10024 #ifdef VMS
10025 "SYS$LOGIN", /* With no colon */
10026 #else
10027 homepath(), /* In VMS this is "SYS$LOGIN:" */
10028 #endif /* VMS */
10029 &s,
10030 ckcdpath ? ckcdpath : getenv("CDPATH"),
10031 xxstring
10032 )) < 0)
10033 return(x);
10034 #endif /* MAC */
10035 #endif /* OS2 */
10036 #endif /* GEMDOS */
10037 ckstrncpy(line,s,LINBUFSIZ); /* Make a safe copy */
10038 s = line;
10039 #ifdef VMS
10040 if (ckmatch("*.DIR;1$",s,0,0))
10041 if (cvtdir(s,tmpbuf,TMPBUFSIZ) > 0)
10042 s = tmpbuf;
10043 #endif /* VMS */
10044 debug(F110,"docd",s,0);
10045 #ifndef MAC
10046 if ((x = cmcfm()) < 0) /* Get confirmation */
10047 return(x);
10048 #endif /* MAC */
10049
10050 gocd:
10051
10052 #ifdef datageneral
10053 x = strlen(line); /* homdir ends in colon, */
10054 if (x > 1 && line[x-1] == ':') /* and "dir" doesn't like that... */
10055 line[x-1] = NUL;
10056 #endif /* datageneral */
10057
10058 #ifdef MAC
10059 cwdf = 1;
10060 if (!zchdir(s)) {
10061 cwdf = 0;
10062 if (*s != ':') { /* If it failed, */
10063 char *p; /* supply leading colon */
10064 int len = (int)strlen(s) + 2;
10065 p = malloc(len); /* and try again... */
10066 if (p) {
10067 strcpy(p,":"); /* safe */
10068 strcat(p,s); /* safe */
10069 if (zchdir(p))
10070 cwdf = 1;
10071 free(p);
10072 p = NULL;
10073 }
10074 }
10075 }
10076 if (!cwdf)
10077 perror(s);
10078 #else
10079 p = zgtdir();
10080 if (!zchdir(s)) {
10081 cwdf = 0;
10082 #ifdef CKROOT
10083 if (ckrooterr)
10084 printf("?Off limits: \"%s\"\n",s);
10085 else
10086 #endif /* CKROOT */
10087 perror(s);
10088 } else cwdf = 1;
10089 #endif /* MAC */
10090
10091 x = 0;
10092 if (cwdf) {
10093 makestr(&prevdir,p);
10094 debug(F111,"docd","srvcdmsg",srvcdmsg);
10095 if (srvcdmsg
10096 #ifdef IKSDCONF
10097 && !(inserver && !iksdcf)
10098 #endif /* IKSDCONF */
10099 ) {
10100 int i;
10101 for (i = 0; i < 8; i++) {
10102 debug(F111,"docd cdmsgfile[i]",cdmsgfile[i],i);
10103 if (zchki(cdmsgfile[i]) > -1) {
10104 x = 1;
10105 dotype(cdmsgfile[i],xaskmore,0,0,NULL,0,NULL,0,0,NULL,0);
10106 break;
10107 }
10108 }
10109 }
10110 }
10111 /* xdocd: */
10112 if (!x && srvcdmsg && !server
10113 #ifdef IKSDCONF
10114 && !(inserver && !iksdcf)
10115 #endif /* IKSDCONF */
10116 && !quiet && !xcmdsrc)
10117 printf("%s\n", zgtdir());
10118
10119 return(cwdf);
10120 }
10121
10122 static int on_ctrlc = 0;
10123
10124 VOID
fixcmd()10125 fixcmd() { /* Fix command parser after interruption */
10126 #ifndef NOSPL
10127 #ifndef NOONCTRLC
10128 if (nmac) { /* Any macros defined? */
10129 int k; /* Yes */
10130 char * s = "on_ctrlc"; /* Name of Ctrl-C handling macro */
10131 k = mlook(mactab,s,nmac); /* Look it up. */
10132 if (k >= 0) { /* If found, */
10133 if (on_ctrlc++ == 0) { /* if not already executing, */
10134 if (dodo(k,"",0) > -1) /* set it up, */
10135 parser(1); /* execute it, */
10136 }
10137 delmac(s,1); /* and undefine it. */
10138 }
10139 }
10140 on_ctrlc = 0;
10141 #endif /* NOONCTRLC */
10142 #endif /* NOSPL */
10143 dostop(); /* Back to top level (also calls conint()). */
10144 bgchk(); /* Check background status */
10145 if (*psave) { /* If old prompt saved, */
10146 cmsetp(psave); /* restore it. */
10147 *psave = NUL;
10148 }
10149 success = 0; /* Tell parser last command failed */
10150 }
10151
10152 #ifndef NOSHOW /* SHOW FEATURES */
10153 /*
10154 Note, presently optlist[] index overflow is not checked.
10155 There is plenty of room (less than 360 entries for 1000 slots).
10156 When space starts to get tight, check for noptlist >= NOPTLIST
10157 every time noptlist is incremented.
10158 */
10159 #define NOPTLIST 1024
10160 static int noptlist = 0;
10161 static char * optlist[NOPTLIST+1];
10162 static int hpos = 0;
10163
10164 int
prtopt(lines,s)10165 prtopt(lines,s) int * lines; char *s; { /* Print an option */
10166 int y, i; /* Does word wrap. */
10167 if (!s) s = "";
10168 i = *lines;
10169 if (!*s) { /* Empty argument */
10170 if (hpos > 0) { /* means to end this line. */
10171 printf("\n"); /* Not needed if already at */
10172 if (++i > (cmd_rows - 3)) { /* beginning of new line. */
10173 if (!askmore())
10174 return(0);
10175 else
10176 i = 0;
10177 }
10178 }
10179 printf("\n"); /* And then make a blank line */
10180 if (++i > (cmd_rows - 3)) {
10181 if (!askmore())
10182 return(0);
10183 else
10184 i = 0;
10185 }
10186 hpos = 0;
10187 *lines = i;
10188 return(1);
10189 }
10190 y = (int)strlen(s) + 1;
10191 hpos += y;
10192 debug(F101,"prtopt hpos","",hpos);
10193 debug(F101,"prtopt cmd_cols","",cmd_cols);
10194
10195 if (
10196 #ifdef OS2
10197 hpos > ((cmd_cols > 40) ? (cmd_cols - 1) : 79)
10198 #else /* OS2 */
10199 hpos > ((tt_cols > 40) ? (tt_cols - 1) : 79)
10200 #endif /* OS2 */
10201 ) {
10202 printf("\n");
10203 if (++i > (cmd_rows - 3)) {
10204 if (!askmore())
10205 return(0);
10206 else
10207 i = 0;
10208 }
10209 printf(" %s",s);
10210 hpos = y;
10211 } else
10212 printf(" %s",s);
10213 *lines = i;
10214 return(1);
10215 }
10216
10217 static VOID
initoptlist()10218 initoptlist() {
10219 int i;
10220 if (noptlist > 0)
10221 return;
10222 for (i = 0; i < NOPTLIST; i++)
10223 optlist[i] = NULL;
10224
10225 #ifdef MAC
10226 #ifdef MPW
10227 makestr(&(optlist[noptlist++]),"MPW");
10228 #endif /* MPW */
10229 #endif /* MAC */
10230
10231 #ifdef MAC
10232 #ifdef THINK_C
10233 makestr(&(optlist[noptlist++]),"THINK_C");
10234 #endif /* THINK_C */
10235 #endif /* MAC */
10236
10237 #ifdef __386__
10238 makestr(&(optlist[noptlist++]),"__386__");
10239 #endif /* __386__ */
10240
10241 /* Memory models... */
10242
10243 #ifdef __FLAT__
10244 makestr(&(optlist[noptlist++]),"__FLAT__");
10245 #endif /* __FLAT__ */
10246 #ifdef __SMALL__
10247 makestr(&(optlist[noptlist++]),"__SMALL__");
10248 #endif /* __SMALL__ */
10249 #ifdef __MEDIUM__
10250 makestr(&(optlist[noptlist++]),"__MEDIUM__");
10251 #endif /* __MEDIUM__ */
10252 #ifdef __COMPACT__
10253 makestr(&(optlist[noptlist++]),"__COMPACT__");
10254 #endif /* __COMPACT__ */
10255 #ifdef __LARGE__
10256 makestr(&(optlist[noptlist++]),"__LARGE__");
10257 #endif /* __LARGE__ */
10258
10259 #ifdef DEBUG
10260 #ifdef IFDEBUG
10261 makestr(&(optlist[noptlist++]),"IFDEBUG");
10262 #else
10263 makestr(&(optlist[noptlist++]),"DEBUG");
10264 #endif /* IFDEBUG */
10265 #endif /* DEBUG */
10266 #ifdef TLOG
10267 makestr(&(optlist[noptlist++]),"TLOG");
10268 #endif /* TLOG */
10269 #ifdef BIGBUFOK
10270 makestr(&(optlist[noptlist++]),"BIGBUFOK");
10271 #endif /* BIGBUFOK */
10272 #ifdef INPBUFSIZ
10273 sprintf(line,"INPBUFSIZ=%d",INPBUFSIZ); /* SAFE */
10274 makestr(&(optlist[noptlist++]),line);
10275 #endif /* INPBUFSIZE */
10276 #ifdef LINBUFSIZ
10277 sprintf(line,"LINBUFSIZ=%d",LINBUFSIZ); /* SAFE */
10278 makestr(&(optlist[noptlist++]),line);
10279 #endif /* LINBUFSIZE */
10280 #ifdef INBUFSIZE
10281 sprintf(line,"INBUFSIZE=%d",INBUFSIZE); /* SAFE */
10282 makestr(&(optlist[noptlist++]),line);
10283 #endif /* INBUFSIZE */
10284 #ifdef OBUFSIZE
10285 sprintf(line,"OBUFSIZE=%d",OBUFSIZE); /* SAFE */
10286 makestr(&(optlist[noptlist++]),line);
10287 #endif /* OBUFSIZE */
10288 #ifdef FD_SETSIZE
10289 sprintf(line,"FD_SETSIZE=%d",FD_SETSIZE); /* SAFE */
10290 makestr(&(optlist[noptlist++]),line);
10291 #endif /* FD_SETSIZE */
10292 #ifdef XFRCAN
10293 makestr(&(optlist[noptlist++]),"XFRCAN");
10294 #endif /* XFRCAN */
10295 #ifdef XPRINT
10296 makestr(&(optlist[noptlist++]),"XPRINT");
10297 #endif /* XPRINT */
10298 #ifdef PIPESEND
10299 makestr(&(optlist[noptlist++]),"PIPESEND");
10300 #endif /* PIPESEND */
10301 #ifdef CK_SPEED
10302 makestr(&(optlist[noptlist++]),"CK_SPEED");
10303 #endif /* CK_SPEED */
10304 #ifdef CK_FAST
10305 makestr(&(optlist[noptlist++]),"CK_FAST");
10306 #endif /* CK_FAST */
10307 #ifdef CK_APC
10308 makestr(&(optlist[noptlist++]),"CK_APC");
10309 #endif /* CK_APC */
10310 #ifdef CK_AUTODL
10311 makestr(&(optlist[noptlist++]),"CK_AUTODL");
10312 #endif /* CK_AUTODL */
10313 #ifdef CK_MKDIR
10314 makestr(&(optlist[noptlist++]),"CK_MKDIR");
10315 #endif /* CK_MKDIR */
10316 #ifdef HAVE_LOCALE
10317 makestr(&(optlist[noptlist++]),"HAVE_LOCALE");
10318 #endif /* HAVE_LOCALE */
10319 #ifdef HAVE_SNPRINTF
10320 makestr(&(optlist[noptlist++]),"HAVE_SNPRINTF");
10321 #endif /* HAVE_SNPRINTF */
10322 #ifdef NOMKDIR
10323 makestr(&(optlist[noptlist++]),"NOMKDIR");
10324 #endif /* NOMKDIR */
10325 #ifdef CK_LABELED
10326 makestr(&(optlist[noptlist++]),"CK_LABELED");
10327 #endif /* CK_LABELED */
10328 #ifdef NODIAL
10329 makestr(&(optlist[noptlist++]),"NODIAL");
10330 #endif /* NODIAL */
10331 #ifdef MINIDIAL
10332 makestr(&(optlist[noptlist++]),"MINIDIAL");
10333 #endif /* MINIDIAL */
10334 #ifdef WHATAMI
10335 makestr(&(optlist[noptlist++]),"WHATAMI");
10336 #endif /* WHATAMI */
10337 #ifdef DYNAMIC
10338 makestr(&(optlist[noptlist++]),"DYNAMIC");
10339 #endif /* DYNAMIC */
10340 #ifndef NOSPL
10341 sprintf(line,"CMDDEP=%d",CMDDEP); /* SAFE */
10342 makestr(&(optlist[noptlist++]),line);
10343 #endif /* NOSPL */
10344
10345 #ifdef MAXPATHLEN
10346 sprintf(line,"MAXPATHLEN=%d",MAXPATHLEN); /* SAFE */
10347 makestr(&(optlist[noptlist++]),line);
10348 #endif /* MAXPATHLEN */
10349
10350 #ifdef DEVNAMLEN
10351 sprintf(line,"DEVNAMLEN=%d",DEVNAMLEN); /* SAFE */
10352 makestr(&(optlist[noptlist++]),line);
10353 #endif /* DEVNAMLEN */
10354
10355 #ifdef NO_PARAM_H
10356 makestr(&(optlist[noptlist++]),"NO_PARAM_H");
10357 #endif /* NO_PARAM_H */
10358
10359 #ifdef INCL_PARAM_H
10360 makestr(&(optlist[noptlist++]),"INCL_PARAM_H");
10361 #endif /* INCL_PARAM_H */
10362
10363 sprintf(line,"CKMAXPATH=%d",CKMAXPATH); /* SAFE */
10364 makestr(&(optlist[noptlist++]),line);
10365
10366 sprintf(line,"CKMAXOPEN=%d",CKMAXOPEN); /* SAFE */
10367 makestr(&(optlist[noptlist++]),line);
10368
10369 #ifndef UNIX
10370 /*
10371 These aren't actually used... In Unix we get maximum number of open
10372 files from sysconf() at runtime.
10373 */
10374 sprintf(line,"Z_MAXCHAN=%d",Z_MAXCHAN); /* SAFE */
10375 makestr(&(optlist[noptlist++]),line);
10376
10377 #ifdef OPEN_MAX
10378 sprintf(line,"OPEN_MAX=%d",OPEN_MAX); /* SAFE */
10379 makestr(&(optlist[noptlist++]),line);
10380 #endif /* OPEN_MAX */
10381
10382 #ifdef _POSIX_OPEN_MAX
10383 sprintf(line,"_POSIX_OPEN_MAX=%d",_POSIX_OPEN_MAX); /* SAFE */
10384 makestr(&(optlist[noptlist++]),line);
10385 #endif /* _POSIX_OPEN_MAX */
10386 #endif /* UNIX */
10387
10388 #ifdef CKCHANNELIO
10389 {
10390 extern int z_maxchan;
10391 #ifdef UNIX
10392 extern int ckmaxfiles;
10393 sprintf(line,"ckmaxfiles=%d",ckmaxfiles); /* SAFE */
10394 makestr(&(optlist[noptlist++]),line);
10395 #endif /* UNIX */
10396 sprintf(line,"z_maxchan=%d",z_maxchan); /* SAFE */
10397 makestr(&(optlist[noptlist++]),line);
10398 }
10399 #endif /* CKCHANNELIO */
10400
10401 #ifdef FOPEN_MAX
10402 sprintf(line,"FOPEN_MAX=%d",FOPEN_MAX); /* SAFE */
10403 makestr(&(optlist[noptlist++]),line);
10404 #endif /* FOPEN_MAX */
10405
10406 #ifdef MAXGETPATH
10407 sprintf(line,"MAXGETPATH=%d",MAXGETPATH); /* SAFE */
10408 makestr(&(optlist[noptlist++]),line);
10409 #endif /* MAXGETPATH */
10410
10411 #ifdef CMDBL
10412 sprintf(line,"CMDBL=%d",CMDBL); /* SAFE */
10413 makestr(&(optlist[noptlist++]),line);
10414 #endif /* CMDBL */
10415
10416 #ifdef VNAML
10417 sprintf(line,"VNAML=%d",VNAML); /* SAFE */
10418 makestr(&(optlist[noptlist++]),line);
10419 #endif /* VNAML */
10420
10421 #ifdef ARRAYREFLEN
10422 sprintf(line,"ARRAYREFLEN=%d",ARRAYREFLEN); /* SAFE */
10423 makestr(&(optlist[noptlist++]),line);
10424 #endif /* ARRAYREFLEN */
10425
10426 #ifdef UIDBUFLEN
10427 sprintf(line,"UIDBUFLEN=%d",UIDBUFLEN); /* SAFE */
10428 makestr(&(optlist[noptlist++]),line);
10429 #endif /* UIDBUFLEN */
10430
10431 #ifdef FORDEPTH
10432 sprintf(line,"FORDEPTH=%d",FORDEPTH); /* SAFE */
10433 makestr(&(optlist[noptlist++]),line);
10434 #endif /* FORDEPTH */
10435
10436 #ifdef MAXTAKE
10437 sprintf(line,"MAXTAKE=%d",MAXTAKE); /* SAFE */
10438 makestr(&(optlist[noptlist++]),line);
10439 #endif /* MAXTAKE */
10440
10441 #ifdef MACLEVEL
10442 sprintf(line,"MACLEVEL=%d",MACLEVEL); /* SAFE */
10443 makestr(&(optlist[noptlist++]),line);
10444 #endif /* MACLEVEL */
10445
10446 #ifdef MAC_MAX
10447 sprintf(line,"MAC_MAX=%d",MAC_MAX); /* SAFE */
10448 makestr(&(optlist[noptlist++]),line);
10449 #endif /* MAC_MAX */
10450
10451 #ifdef _LARGEFILE_SOURCE
10452 makestr(&(optlist[noptlist++]),"_LARGEFILE_SOURCE");
10453 #endif /* _LARGEFILE_SOURCE */
10454
10455 #ifdef _FILE_OFFSET_BITS
10456 sprintf(line,"_FILE_OFFSET_BITS=%d",_FILE_OFFSET_BITS); /* SAFE */
10457 makestr(&(optlist[noptlist++]),line);
10458 #endif /* _FILE_OFFSET_BITS */
10459
10460 #ifdef __USE_FILE_OFFSET64
10461 makestr(&(optlist[noptlist++]),"__USE_FILE_OFFSET64");
10462 #endif /* __USE_FILE_OFFSET64 */
10463
10464 #ifdef __USE_LARGEFILE64
10465 makestr(&(optlist[noptlist++]),"__USE_LARGEFILE64");
10466 #endif /* __USE_LARGEFILE64 */
10467
10468 #ifdef COMMENT
10469 #ifdef CHAR_MAX
10470 sprintf(line,"CHAR_MAX=%llx",CHAR_MAX); /* SAFE */
10471 makestr(&(optlist[noptlist++]),line);
10472 #endif /* CHAR_MAX */
10473 #ifdef UCHAR_MAX
10474 sprintf(line,"UCHAR_MAX=%llx",UCHAR_MAX); /* SAFE */
10475 makestr(&(optlist[noptlist++]),line);
10476 #endif /* UCHAR_MAX */
10477 #ifdef SHRT_MAX
10478 sprintf(line,"SHRT_MAX=%llx",SHRT_MAX); /* SAFE */
10479 makestr(&(optlist[noptlist++]),line);
10480 #endif /* SHRT_MAX */
10481 #ifdef USHRT_MAX
10482 sprintf(line,"USHRT_MAX=%llx",USHRT_MAX); /* SAFE */
10483 makestr(&(optlist[noptlist++]),line);
10484 #endif /* USHRT_MAX */
10485 #ifdef INT_MAX
10486 sprintf(line,"INT_MAX=%llx",INT_MAX); /* SAFE */
10487 makestr(&(optlist[noptlist++]),line);
10488 #endif /* INT_MAX */
10489 #ifdef UINT_MAX
10490 sprintf(line,"UINT_MAX=%llx",UINT_MAX); /* SAFE */
10491 makestr(&(optlist[noptlist++]),line);
10492 #endif /* UINT_MAX */
10493 #ifdef MAX_LONG
10494 sprintf(line,"MAX_LONG=%llx",MAX_LONG); /* SAFE */
10495 makestr(&(optlist[noptlist++]),line);
10496 #endif /* MAX_LONG */
10497 #ifdef LONG_MAX
10498 sprintf(line,"LONG_MAX=%llx",LONG_MAX); /* SAFE */
10499 makestr(&(optlist[noptlist++]),line);
10500 #endif /* LONG_MAX */
10501 #ifdef ULONG_MAX
10502 sprintf(line,"ULONG_MAX=%llx",ULONG_MAX); /* SAFE */
10503 makestr(&(optlist[noptlist++]),line);
10504 #endif /* ULONG_MAX */
10505 #ifdef MAXINT
10506 sprintf(line,"MAXINT=%llx",MAXINT); /* SAFE */
10507 makestr(&(optlist[noptlist++]),line);
10508 #endif /* MAXINT */
10509 #ifdef MAXLONG
10510 sprintf(line,"MAXLONG=%llx",MAXLONG); /* SAFE */
10511 makestr(&(optlist[noptlist++]),line);
10512 #endif /* MAXLONG */
10513 #ifdef NT
10514 #ifdef LLONG_MAX
10515 sprintf(line,"LLONG_MAX=%I64x",LLONG_MAX); /* SAFE */
10516 makestr(&(optlist[noptlist++]),line);
10517 #endif /* LLONG_MAX */
10518 #ifdef ULLONG_MAX
10519 sprintf(line,"ULLONG_MAX=%I64x",ULLONG_MAX); /* SAFE */
10520 makestr(&(optlist[noptlist++]),line);
10521 #endif /* ULLONG_MAX */
10522 #ifdef MAXLONGLONG
10523 sprintf(line,"MAXLONGLONG=%I64x",MAXLONGLONG); /* SAFE */
10524 makestr(&(optlist[noptlist++]),line);
10525 #endif /* MAXLONGLONG */
10526 #else
10527 #ifdef LLONG_MAX
10528 sprintf(line,"LLONG_MAX=%llx",LLONG_MAX); /* SAFE */
10529 makestr(&(optlist[noptlist++]),line);
10530 #endif /* LLONG_MAX */
10531 #ifdef ULLONG_MAX
10532 sprintf(line,"ULLONG_MAX=%llx",ULLONG_MAX); /* SAFE */
10533 makestr(&(optlist[noptlist++]),line);
10534 #endif /* ULLONG_MAX */
10535 #ifdef MAXLONGLONG
10536 sprintf(line,"MAXLONGLONG=%llx",MAXLONGLONG); /* SAFE */
10537 makestr(&(optlist[noptlist++]),line);
10538 #endif /* MAXLONGLONG */
10539 #endif
10540 #ifdef _INTEGRAL_MAX_BITS
10541 sprintf(line,"_INTEGRAL_MAX_BITS=%d",_INTEGRAL_MAX_BITS); /* SAFE */
10542 makestr(&(optlist[noptlist++]),line);
10543 #endif /* _INTEGRAL_MAX_BITS */
10544 #endif /* COMMENT */
10545
10546 #ifdef MINPUTMAX
10547 sprintf(line,"MINPUTMAX=%d",MINPUTMAX); /* SAFE */
10548 makestr(&(optlist[noptlist++]),line);
10549 #endif /* MINPUTMAX */
10550
10551 #ifdef MAXWLD
10552 sprintf(line,"MAXWLD=%d",MAXWLD); /* SAFE */
10553 makestr(&(optlist[noptlist++]),line);
10554 #else
10555 #ifdef OS2
10556 makestr(&(optlist[noptlist++]),"MAXWLD=unlimited");
10557 #endif /* OS2 */
10558 #endif /* MAXWLD */
10559
10560 #ifdef MSENDMAX
10561 sprintf(line,"MSENDMAX=%d",MSENDMAX); /* SAFE */
10562 makestr(&(optlist[noptlist++]),line);
10563 #endif /* MSENDMAX */
10564
10565 #ifdef MAXDDIR
10566 sprintf(line,"MAXDDIR=%d",MAXDDIR); /* SAFE */
10567 makestr(&(optlist[noptlist++]),line);
10568 #endif /* MAXDDIR */
10569
10570 #ifdef MAXDNUMS
10571 sprintf(line,"MAXDNUMS=%d",MAXDNUMS); /* SAFE */
10572 makestr(&(optlist[noptlist++]),line);
10573 #endif /* MAXDNUMS */
10574
10575 #ifdef UNIX
10576 makestr(&(optlist[noptlist++]),"UNIX");
10577 #endif /* UNIX */
10578
10579 #ifdef VMS
10580 makestr(&(optlist[noptlist++]),"VMS");
10581 #ifdef __VMS_VER
10582 sprintf(line,"__VMS_VER=%d",__VMS_VER); /* SAFE */
10583 makestr(&(optlist[noptlist++]),line);
10584 #endif /* __VMS_VER */
10585 #ifdef VMSV70
10586 makestr(&(optlist[noptlist++]),"VMSV70");
10587 #endif /* VMSV70 */
10588 #ifdef OLD_VMS
10589 makestr(&(optlist[noptlist++]),"OLD_VMS");
10590 #endif /* OLD_VMS */
10591 #ifdef vms
10592 makestr(&(optlist[noptlist++]),"vms");
10593 #endif /* vms */
10594 #ifdef VMSV60
10595 makestr(&(optlist[noptlist++]),"VMSV60");
10596 #endif /* VMSV60 */
10597 #ifdef VMSV80
10598 makestr(&(optlist[noptlist++]),"VMSV80");
10599 #endif /* VMSV80 */
10600 #ifdef VMSSHARE
10601 makestr(&(optlist[noptlist++]),"VMSSHARE");
10602 #endif /* VMSSHARE */
10603 #ifdef NOVMSSHARE
10604 makestr(&(optlist[noptlist++]),"NOVMSSHARE");
10605 #endif /* NOVMSSHARE */
10606 #endif /* VMS */
10607
10608 #ifdef datageneral
10609 makestr(&(optlist[noptlist++]),"datageneral");
10610 #endif /* datageneral */
10611 #ifdef apollo
10612 makestr(&(optlist[noptlist++]),"apollo");
10613 #endif /* apollo */
10614 #ifdef aegis
10615 makestr(&(optlist[noptlist++]),"aegis");
10616 #endif /* aegis */
10617 #ifdef A986
10618 makestr(&(optlist[noptlist++]),"A986");
10619 #endif /* A986 */
10620 #ifdef AMIGA
10621 makestr(&(optlist[noptlist++]),"AMIGA");
10622 #endif /* AMIGA */
10623 #ifdef CONVEX9
10624 makestr(&(optlist[noptlist++]),"CONVEX9");
10625 #endif /* CONVEX9 */
10626 #ifdef CONVEX10
10627 makestr(&(optlist[noptlist++]),"CONVEX10");
10628 #endif /* CONVEX9 */
10629 #ifdef MAC
10630 makestr(&(optlist[noptlist++]),"MAC");
10631 #endif /* MAC */
10632 #ifdef AUX
10633 makestr(&(optlist[noptlist++]),"AUX");
10634 #endif /* AUX */
10635
10636 #ifdef OS2
10637 makestr(&(optlist[noptlist++]),"OS2");
10638 #ifdef NT
10639 makestr(&(optlist[noptlist++]),"NT");
10640 #endif /* NT */
10641 #endif /* OS2 */
10642
10643 #ifdef OSK
10644 makestr(&(optlist[noptlist++]),"OS9");
10645 #endif /* OSK */
10646
10647 #ifdef MSDOS
10648 makestr(&(optlist[noptlist++]),"MSDOS");
10649 #endif /* MSDOS */
10650
10651 #ifdef DIRENT
10652 makestr(&(optlist[noptlist++]),"DIRENT");
10653 #endif /* DIRENT */
10654
10655 #ifdef SDIRENT
10656 makestr(&(optlist[noptlist++]),"SDIRENT");
10657 #endif /* SDIRENT */
10658
10659 #ifdef NDIR
10660 makestr(&(optlist[noptlist++]),"NDIR");
10661 #endif /* NDIR */
10662
10663 #ifdef XNDIR
10664 makestr(&(optlist[noptlist++]),"XNDIR");
10665 #endif /* XNDIR */
10666
10667 #ifdef SAVEDUID
10668 makestr(&(optlist[noptlist++]),"SAVEDUID");
10669 #endif /* SAVEDUID */
10670
10671 #ifdef RENAME
10672 makestr(&(optlist[noptlist++]),"RENAME");
10673 #endif /* RENAME */
10674
10675 #ifdef CK_TMPDIR
10676 makestr(&(optlist[noptlist++]),"CK_TMPDIR");
10677 #endif /* CK_TMPDIR */
10678
10679 #ifdef NOCCTRAP
10680 makestr(&(optlist[noptlist++]),"NOCCTRAP");
10681 #endif /* NOCCTRAP */
10682
10683 #ifdef NOCOTFMC
10684 makestr(&(optlist[noptlist++]),"NOCOTFMC");
10685 #endif /* NOCOTFMC */
10686
10687 #ifdef NOFRILLS
10688 makestr(&(optlist[noptlist++]),"NOFRILLS");
10689 #endif /* NOFRILLS */
10690
10691 #ifdef PARSENSE
10692 makestr(&(optlist[noptlist++]),"PARSENSE");
10693 #endif /* PARSENSE */
10694
10695 #ifdef TIMEH
10696 makestr(&(optlist[noptlist++]),"TIMEH");
10697 #endif /* TIMEH */
10698
10699 #ifdef NOTIMEH
10700 makestr(&(optlist[noptlist++]),"TIMEH");
10701 #endif /* NOTIMEH */
10702
10703 #ifdef SYSTIMEH
10704 makestr(&(optlist[noptlist++]),"SYSTIMEH");
10705 #endif /* SYSTIMEH */
10706
10707 #ifdef NOSYSTIMEH
10708 makestr(&(optlist[noptlist++]),"SYSTIMEH");
10709 #endif /* NOSYSTIMEH */
10710
10711 #ifdef SYSTIMEBH
10712 makestr(&(optlist[noptlist++]),"SYSTIMEBH");
10713 #endif /* SYSTIMEBH */
10714
10715 #ifdef NOSYSTIMEBH
10716 makestr(&(optlist[noptlist++]),"SYSTIMEBH");
10717 #endif /* NOSYSTIMEBH */
10718
10719 #ifdef UTIMEH
10720 makestr(&(optlist[noptlist++]),"UTIMEH");
10721 #endif /* UTIMEH */
10722
10723 #ifdef SYSUTIMEH
10724 makestr(&(optlist[noptlist++]),"SYSUTIMEH");
10725 #endif /* SYSUTIMEH */
10726
10727 #ifdef CK_NEED_SIG
10728 makestr(&(optlist[noptlist++]),"CK_NEED_SIG");
10729 #endif /* CK_NEED_SIG */
10730
10731 #ifdef CK_TTYFD
10732 makestr(&(optlist[noptlist++]),"CK_TTYFD");
10733 #endif /* CK_TTYFD */
10734
10735 #ifdef NETCONN
10736 makestr(&(optlist[noptlist++]),"NETCONN");
10737 #endif /* NETCONN */
10738
10739 #ifdef TCPSOCKET
10740 makestr(&(optlist[noptlist++]),"TCPSOCKET");
10741 #ifdef NOTCPOPTS
10742 makestr(&(optlist[noptlist++]),"NOTCPOPTS");
10743 #endif /* NOTCPOPTS */
10744 #ifdef CK_DNS_SRV
10745 makestr(&(optlist[noptlist++]),"CK_DNS_SRV");
10746 #endif /* CK_DNS_SRV */
10747 #ifdef NO_DNS_SRV
10748 makestr(&(optlist[noptlist++]),"NO_DNS_SRV");
10749 #endif /* NO_DNS_SRV */
10750 #ifdef CKGHNLHOST
10751 makestr(&(optlist[noptlist++]),"CKGHNLHOST");
10752 #endif /* CKGHNLHOST */
10753 #ifdef NOLISTEN
10754 makestr(&(optlist[noptlist++]),"NOLISTEN");
10755 #endif /* NOLISTEN */
10756 #ifdef SOL_SOCKET
10757 makestr(&(optlist[noptlist++]),"SOL_SOCKET");
10758 #endif /* SOL_SOCKET */
10759 #ifdef SO_OOBINLINE
10760 makestr(&(optlist[noptlist++]),"SO_OOBINLINE");
10761 #endif /* SO_OOBINLNE */
10762 #ifdef SO_DONTROUTE
10763 makestr(&(optlist[noptlist++]),"SO_DONTROUTE");
10764 #endif /* SO_DONTROUTE */
10765 #ifdef SO_KEEPALIVE
10766 makestr(&(optlist[noptlist++]),"SO_KEEPALIVE");
10767 #endif /* SO_KEEPALIVE */
10768 #ifdef SO_LINGER
10769 makestr(&(optlist[noptlist++]),"SO_LINGER");
10770 #endif /* SO_LINGER */
10771 #ifdef TCP_NODELAY
10772 makestr(&(optlist[noptlist++]),"TCP_NODELAY");
10773 #endif /* TCP_NODELAY */
10774 #ifdef SO_SNDBUF
10775 makestr(&(optlist[noptlist++]),"SO_SNDBUF");
10776 #endif /* SO_SNDBUF */
10777 #ifdef SO_RCVBUF
10778 makestr(&(optlist[noptlist++]),"SO_RCVBUF");
10779 #endif /* SO_RCVBUF */
10780 #ifdef h_addr
10781 makestr(&(optlist[noptlist++]),"h_addr");
10782 #endif /* h_addr */
10783 #ifdef HADDRLIST
10784 makestr(&(optlist[noptlist++]),"HADDRLIST");
10785 #endif /* HADDRLIST */
10786 #ifdef CK_SOCKS
10787 makestr(&(optlist[noptlist++]),"CK_SOCKS");
10788 #ifdef CK_SOCKS5
10789 makestr(&(optlist[noptlist++]),"CK_SOCKS5");
10790 #endif /* CK_SOCKS5 */
10791 #ifdef CK_SOCKS_NS
10792 makestr(&(optlist[noptlist++]),"CK_SOCKS_NS");
10793 #endif /* CK_SOCKS_NS */
10794 #endif /* CK_SOCKS */
10795 #ifdef RLOGCODE
10796 makestr(&(optlist[noptlist++]),"RLOGCODE");
10797 #endif /* RLOGCODE */
10798 #ifdef NETCMD
10799 makestr(&(optlist[noptlist++]),"NETCMD");
10800 #endif /* NETCMD */
10801 #ifdef NONETCMD
10802 makestr(&(optlist[noptlist++]),"NONETCMD");
10803 #endif /* NONETCMD */
10804 #ifdef NETPTY
10805 makestr(&(optlist[noptlist++]),"NETPTY");
10806 #endif /* NETPTY */
10807 #ifdef CK_ENVIRONMENT
10808 makestr(&(optlist[noptlist++]),"CK_ENVIRONMENT");
10809 #endif /* CK_ENVIRONMENT */
10810 #endif /* TCPSOCKET */
10811 #ifdef TNCODE
10812 makestr(&(optlist[noptlist++]),"TNCODE");
10813 #endif /* TNCODE */
10814 #ifdef CK_FORWARD_X
10815 makestr(&(optlist[noptlist++]),"CK_FORWARD_X");
10816 #endif /* CK_FORWARD_X */
10817 #ifdef TN_COMPORT
10818 makestr(&(optlist[noptlist++]),"TN_COMPORT");
10819 #endif /* TN_COMPORT */
10820 #ifdef MULTINET
10821 makestr(&(optlist[noptlist++]),"MULTINET");
10822 #endif /* MULTINET */
10823 #ifdef DEC_TCPIP
10824 makestr(&(optlist[noptlist++]),"DEC_TCPIP");
10825 #endif /* DEC_TCPIP */
10826 #ifdef TCPWARE
10827 makestr(&(optlist[noptlist++]),"TCPWARE");
10828 #endif /* TCPWARE */
10829 #ifdef UCX50
10830 makestr(&(optlist[noptlist++]),"UCX50");
10831 #endif /* UCX50 */
10832 #ifdef CMU_TCPIP
10833 makestr(&(optlist[noptlist++]),"CMU_TCPIP");
10834 #endif /* CMU_TCPIP */
10835 #ifdef TTLEBUF
10836 makestr(&(optlist[noptlist++]),"TTLEBUF");
10837 #endif /* TTLEBUF */
10838 #ifdef NETLEBUF
10839 makestr(&(optlist[noptlist++]),"NETLEBUF");
10840 #endif /* NETLEBUF */
10841 #ifdef IKS_OPTION
10842 makestr(&(optlist[noptlist++]),"IKS_OPTION");
10843 #endif /* IKS_OPTION */
10844 #ifdef IKSDB
10845 makestr(&(optlist[noptlist++]),"IKSDB");
10846 #endif /* IKSDB */
10847 #ifdef IKSDCONF
10848 makestr(&(optlist[noptlist++]),"IKSDCONF");
10849 #endif /* IKSDCONF */
10850 #ifdef CK_LOGIN
10851 makestr(&(optlist[noptlist++]),"CK_LOGIN");
10852 #endif /* CK_LOGIN */
10853 #ifdef CK_PAM
10854 makestr(&(optlist[noptlist++]),"CK_PAM");
10855 #endif /* CK_PAM */
10856 #ifdef CK_SHADOW
10857 makestr(&(optlist[noptlist++]),"CK_SHADOW");
10858 #endif /* CK_SHADOW */
10859 #ifdef CONGSPD
10860 makestr(&(optlist[noptlist++]),"CONGSPD");
10861 #endif /* CONGSPD */
10862 #ifdef SUNX25
10863 makestr(&(optlist[noptlist++]),"SUNX25");
10864 #endif /* SUNX25 */
10865 #ifdef IBMX25
10866 makestr(&(optlist[noptlist++]),"IBMX25");
10867 #endif /* IBMX25 */
10868 #ifdef HPX25
10869 makestr(&(optlist[noptlist++]),"HPX25");
10870 #endif /* HPX25 */
10871 #ifdef DECNET
10872 makestr(&(optlist[noptlist++]),"DECNET");
10873 #endif /* DECNET */
10874 #ifdef SUPERLAT
10875 makestr(&(optlist[noptlist++]),"SUPERLAT");
10876 #endif /* SUPERLAT */
10877 #ifdef NPIPE
10878 makestr(&(optlist[noptlist++]),"NPIPE");
10879 #endif /* NPIPE */
10880 #ifdef CK_NETBIOS
10881 makestr(&(optlist[noptlist++]),"CK_NETBIOS");
10882 #endif /* CK_NETBIOS */
10883 #ifdef ATT7300
10884 makestr(&(optlist[noptlist++]),"ATT7300");
10885 #endif /* ATT7300 */
10886 #ifdef ATT6300
10887 makestr(&(optlist[noptlist++]),"ATT6300");
10888 #endif /* ATT6300 */
10889 #ifdef HDBUUCP
10890 makestr(&(optlist[noptlist++]),"HDBUUCP");
10891 #endif /* HDBUUCP */
10892 #ifdef USETTYLOCK
10893 makestr(&(optlist[noptlist++]),"USETTYLOCK");
10894 #endif /* USETTYLOCK */
10895 #ifdef USE_UU_LOCK
10896 makestr(&(optlist[noptlist++]),"USE_UU_LOCK");
10897 #endif /* USE_UU_LOCK */
10898 #ifdef HAVE_LOCKDEV
10899 makestr(&(optlist[noptlist++]),"HAVE_LOCKDEV");
10900 #endif /* HAVE_LOCKDEV */
10901 #ifdef HAVE_BAUDBOY
10902 makestr(&(optlist[noptlist++]),"HAVE_BAUDBOY");
10903 #endif /* HAVE_BAUDBOY */
10904 #ifdef HAVE_OPENPTY
10905 makestr(&(optlist[noptlist++]),"HAVE_OPENPTY");
10906 #endif /* HAVE_OPENPTY */
10907 #ifdef TTPTYCMD
10908 makestr(&(optlist[noptlist++]),"TTPTYCMD");
10909 #endif /* TTPTYCMD */
10910 #ifdef NOUUCP
10911 makestr(&(optlist[noptlist++]),"NOUUCP");
10912 #endif /* NOUUCP */
10913 #ifdef LONGFN
10914 makestr(&(optlist[noptlist++]),"LONGFN");
10915 #endif /* LONGFN */
10916 #ifdef RDCHK
10917 makestr(&(optlist[noptlist++]),"RDCHK");
10918 #endif /* RDCHK */
10919 #ifdef SELECT
10920 makestr(&(optlist[noptlist++]),"SELECT");
10921 #endif /* SELECT */
10922 #ifdef USLEEP
10923 makestr(&(optlist[noptlist++]),"USLEEP");
10924 #endif /* USLEEP */
10925 #ifdef NAP
10926 makestr(&(optlist[noptlist++]),"NAP");
10927 #endif /* NAP */
10928 #ifdef NAPHACK
10929 makestr(&(optlist[noptlist++]),"NAPHACK");
10930 #endif /* NAPHACK */
10931 #ifdef CK_POLL
10932 makestr(&(optlist[noptlist++]),"CK_POLL");
10933 #endif /* CK_POLL */
10934 #ifdef NOIEXTEN
10935 makestr(&(optlist[noptlist++]),"NOIEXTEN");
10936 #endif /* NOIEXTEN */
10937 #ifdef EXCELAN
10938 makestr(&(optlist[noptlist++]),"EXCELAN");
10939 #endif /* EXCELAN */
10940 #ifdef INTERLAN
10941 makestr(&(optlist[noptlist++]),"INTERLAN");
10942 #endif /* INTERLAN */
10943 #ifdef NOFILEH
10944 makestr(&(optlist[noptlist++]),"NOFILEH");
10945 #endif /* NOFILEH */
10946 #ifdef NOSYSIOCTLH
10947 makestr(&(optlist[noptlist++]),"NOSYSIOCTLH");
10948 #endif /* NOSYSIOCTLH */
10949 #ifdef DCLPOPEN
10950 makestr(&(optlist[noptlist++]),"DCLPOPEN");
10951 #endif /* DCLPOPEN */
10952 #ifdef NOSETBUF
10953 makestr(&(optlist[noptlist++]),"NOSETBUF");
10954 #endif /* NOSETBUF */
10955 #ifdef NOXFER
10956 makestr(&(optlist[noptlist++]),"NOXFER");
10957 #endif /* NOXFER */
10958 #ifdef NOCURSES
10959 makestr(&(optlist[noptlist++]),"NOCURSES");
10960 #endif /* NOCURSES */
10961 #ifdef NOSERVER
10962 makestr(&(optlist[noptlist++]),"NOSERVER");
10963 #endif /* NOSERVER */
10964 #ifdef NOPATTERNS
10965 makestr(&(optlist[noptlist++]),"NOPATTERNS");
10966 #else
10967 #ifdef PATTERNS
10968 makestr(&(optlist[noptlist++]),"PATTERNS");
10969 #endif /* PATTERNS */
10970 #endif /* NOPATTERNS */
10971 #ifdef NOCKEXEC
10972 makestr(&(optlist[noptlist++]),"NOCKEXEC");
10973 #else
10974 #ifdef CKEXEC
10975 makestr(&(optlist[noptlist++]),"CKEXEC");
10976 #endif /* CKEXEC */
10977 #endif /* NOCKEXEC */
10978 #ifdef NOAUTODL
10979 makestr(&(optlist[noptlist++]),"NOAUTODL");
10980 #endif /* NOAUTODL */
10981 #ifdef NOMSEND
10982 makestr(&(optlist[noptlist++]),"NOMSEND");
10983 #endif /* NOMSEND */
10984 #ifdef NOFDZERO
10985 makestr(&(optlist[noptlist++]),"NOFDZERO");
10986 #endif /* NOFDZERO */
10987 #ifdef NOPOPEN
10988 makestr(&(optlist[noptlist++]),"NOPOPEN");
10989 #endif /* NOPOPEN */
10990 #ifdef NOPARTIAL
10991 makestr(&(optlist[noptlist++]),"NOPARTIAL");
10992 #endif /* NOPARTIAL */
10993 #ifdef NOKVERBS
10994 makestr(&(optlist[noptlist++]),"NOKVERBS");
10995 #endif /* NOKVERBS */
10996 #ifdef NOSETREU
10997 makestr(&(optlist[noptlist++]),"NOSETREU");
10998 #endif /* NOSETREU */
10999 #ifdef LCKDIR
11000 makestr(&(optlist[noptlist++]),"LCKDIR");
11001 #endif /* LCKDIR */
11002 #ifdef ACUCNTRL
11003 makestr(&(optlist[noptlist++]),"ACUCNTRL");
11004 #endif /* ACUCNTRL */
11005 #ifdef BSD4
11006 makestr(&(optlist[noptlist++]),"BSD4");
11007 #endif /* BSD4 */
11008 #ifdef BSD44
11009 makestr(&(optlist[noptlist++]),"BSD44");
11010 #endif /* BSD44 */
11011 #ifdef BSD41
11012 makestr(&(optlist[noptlist++]),"BSD41");
11013 #endif /* BSD41 */
11014 #ifdef BSD43
11015 makestr(&(optlist[noptlist++]),"BSD43");
11016 #endif /* BSD43 */
11017 #ifdef BSD29
11018 makestr(&(optlist[noptlist++]),"BSD29");
11019 #endif /* BSD29 */
11020 #ifdef BSDI
11021 makestr(&(optlist[noptlist++]),"BSDI");
11022 #endif /* BSDI */
11023 #ifdef __bsdi__
11024 makestr(&(optlist[noptlist++]),"__bsdi__");
11025 #endif /* __bsdi__ */
11026 #ifdef __NetBSD__
11027 makestr(&(optlist[noptlist++]),"__NetBSD__");
11028 #endif /* __NetBSD__ */
11029 #ifdef __OpenBSD__
11030 makestr(&(optlist[noptlist++]),"__OpenBSD__");
11031 #endif /* __OpenBSD__ */
11032 #ifdef __FreeBSD__
11033 makestr(&(optlist[noptlist++]),"__FreeBSD__");
11034 #endif /* __FreeBSD__ */
11035 #ifdef FREEBSD4
11036 makestr(&(optlist[noptlist++]),"FREEBSD4");
11037 #endif /* FREEBSD4 */
11038 #ifdef FREEBSD8
11039 makestr(&(optlist[noptlist++]),"FREEBSD8");
11040 #endif /* FREEBSD8 */
11041 #ifdef FREEBSD9
11042 makestr(&(optlist[noptlist++]),"FREEBSD9");
11043 #endif /* FREEBSD9 */
11044 #ifdef __linux__
11045 makestr(&(optlist[noptlist++]),"__linux__");
11046 #endif /* __linux__ */
11047 #ifdef LINUX_HI_SPD
11048 makestr(&(optlist[noptlist++]),"LINUX_HI_SPD");
11049 #endif /* LINUX_HI_SPD */
11050 #ifdef LYNXOS
11051 makestr(&(optlist[noptlist++]),"LYNXOS");
11052 #endif /* LYNXOS */
11053 #ifdef V7
11054 makestr(&(optlist[noptlist++]),"V7");
11055 #endif /* V7 */
11056 #ifdef AIX370
11057 makestr(&(optlist[noptlist++]),"AIX370");
11058 #endif /* AIX370 */
11059 #ifdef RTAIX
11060 makestr(&(optlist[noptlist++]),"RTAIX");
11061 #endif /* RTAIX */
11062 #ifdef HPUX
11063 makestr(&(optlist[noptlist++]),"HPUX");
11064 #endif /* HPUX */
11065 #ifdef HPUX9
11066 makestr(&(optlist[noptlist++]),"HPUX9");
11067 #endif /* HPUX9 */
11068 #ifdef HPUX10
11069 makestr(&(optlist[noptlist++]),"HPUX10");
11070 #endif /* HPUX10 */
11071 #ifdef HPUX1000
11072 makestr(&(optlist[noptlist++]),"HPUX1000");
11073 #endif /* HPUX1000 */
11074 #ifdef HPUX1100
11075 makestr(&(optlist[noptlist++]),"HPUX1100");
11076 #endif /* HPUX1100 */
11077 #ifdef HPUXPRE65
11078 makestr(&(optlist[noptlist++]),"HPUXPRE65");
11079 #endif /* HPUXPRE65 */
11080 #ifdef DGUX
11081 makestr(&(optlist[noptlist++]),"DGUX");
11082 #endif /* DGUX */
11083 #ifdef DGUX430
11084 makestr(&(optlist[noptlist++]),"DGUX430");
11085 #endif /* DGUX430 */
11086 #ifdef DGUX540
11087 makestr(&(optlist[noptlist++]),"DGUX540");
11088 #endif /* DGUX540 */
11089 #ifdef DGUX543
11090 makestr(&(optlist[noptlist++]),"DGUX543");
11091 #endif /* DGUX543 */
11092 #ifdef DGUX54410
11093 makestr(&(optlist[noptlist++]),"DGUX54410");
11094 #endif /* DGUX54410 */
11095 #ifdef DGUX54411
11096 makestr(&(optlist[noptlist++]),"DGUX54411");
11097 #endif /* DGUX54411 */
11098 #ifdef sony_news
11099 makestr(&(optlist[noptlist++]),"sony_news");
11100 #endif /* sony_news */
11101 #ifdef CIE
11102 makestr(&(optlist[noptlist++]),"CIE");
11103 #endif /* CIE */
11104 #ifdef XENIX
11105 makestr(&(optlist[noptlist++]),"XENIX");
11106 #endif /* XENIX */
11107 #ifdef SCO_XENIX
11108 makestr(&(optlist[noptlist++]),"SCO_XENIX");
11109 #endif /* SCO_XENIX */
11110 #ifdef ISIII
11111 makestr(&(optlist[noptlist++]),"ISIII");
11112 #endif /* ISIII */
11113 #ifdef I386IX
11114 makestr(&(optlist[noptlist++]),"I386IX");
11115 #endif /* I386IX */
11116 #ifdef RTU
11117 makestr(&(optlist[noptlist++]),"RTU");
11118 #endif /* RTU */
11119 #ifdef PROVX1
11120 makestr(&(optlist[noptlist++]),"PROVX1");
11121 #endif /* PROVX1 */
11122 #ifdef PYRAMID
11123 makestr(&(optlist[noptlist++]),"PYRAMID");
11124 #endif /* PYRAMID */
11125 #ifdef TOWER1
11126 makestr(&(optlist[noptlist++]),"TOWER1");
11127 #endif /* TOWER1 */
11128 #ifdef UTEK
11129 makestr(&(optlist[noptlist++]),"UTEK");
11130 #endif /* UTEK */
11131 #ifdef ZILOG
11132 makestr(&(optlist[noptlist++]),"ZILOG");
11133 #endif /* ZILOG */
11134 #ifdef TRS16
11135 makestr(&(optlist[noptlist++]),"TRS16");
11136 #endif /* TRS16 */
11137 #ifdef MINIX
11138 makestr(&(optlist[noptlist++]),"MINIX");
11139 #endif /* MINIX */
11140 #ifdef MINIX2
11141 makestr(&(optlist[noptlist++]),"MINIX2");
11142 #endif /* MINIX2 */
11143 #ifdef MINIX3
11144 makestr(&(optlist[noptlist++]),"MINIX3");
11145 #endif /* MINIX3 */
11146 #ifdef MINIX315
11147 makestr(&(optlist[noptlist++]),"MINIX315");
11148 #endif /* MINIX315 */
11149 #ifdef C70
11150 makestr(&(optlist[noptlist++]),"C70");
11151 #endif /* C70 */
11152 #ifdef AIXPS2
11153 makestr(&(optlist[noptlist++]),"AIXPS2");
11154 #endif /* AIXPS2 */
11155 #ifdef AIXRS
11156 makestr(&(optlist[noptlist++]),"AIXRS");
11157 #endif /* AIXRS */
11158 #ifdef UTSV
11159 makestr(&(optlist[noptlist++]),"UTSV");
11160 #endif /* UTSV */
11161 #ifdef ATTSV
11162 makestr(&(optlist[noptlist++]),"ATTSV");
11163 #endif /* ATTSV */
11164 #ifdef SVR3
11165 makestr(&(optlist[noptlist++]),"SVR3");
11166 #endif /* SVR3 */
11167 #ifdef SVR4
11168 makestr(&(optlist[noptlist++]),"SVR4");
11169 #endif /* SVR4 */
11170 #ifdef DELL_SVR4
11171 makestr(&(optlist[noptlist++]),"DELL_SVR4");
11172 #endif /* DELL_SVR4 */
11173 #ifdef ICL_SVR4
11174 makestr(&(optlist[noptlist++]),"ICL_SVR4");
11175 #endif /* ICL_SVR4 */
11176 #ifdef OSF
11177 makestr(&(optlist[noptlist++]),"OSF");
11178 #endif /* OSF */
11179 #ifdef OSF1
11180 makestr(&(optlist[noptlist++]),"OSF1");
11181 #endif /* OSF1 */
11182 #ifdef __OSF
11183 makestr(&(optlist[noptlist++]),"__OSF");
11184 #endif /* __OSF */
11185 #ifdef __OSF__
11186 makestr(&(optlist[noptlist++]),"__OSF__");
11187 #endif /* __OSF__ */
11188 #ifdef __osf__
11189 makestr(&(optlist[noptlist++]),"__osf__");
11190 #endif /* __osf__ */
11191 #ifdef __OSF1
11192 makestr(&(optlist[noptlist++]),"__OSF1");
11193 #endif /* __OSF1 */
11194 #ifdef __OSF1__
11195 makestr(&(optlist[noptlist++]),"__OSF1__");
11196 #endif /* __OSF1__ */
11197 #ifdef PTX
11198 makestr(&(optlist[noptlist++]),"PTX");
11199 #endif /* PTX */
11200 #ifdef POSIX
11201 makestr(&(optlist[noptlist++]),"POSIX");
11202 #endif /* POSIX */
11203 #ifdef BSD44ORPOSIX
11204 makestr(&(optlist[noptlist++]),"BSD44ORPOSIX");
11205 #endif /* BSD44ORPOSIX */
11206 #ifdef SVORPOSIX
11207 makestr(&(optlist[noptlist++]),"SVORPOSIX");
11208 #endif /* SVORPOSIX */
11209 #ifdef SVR4ORPOSIX
11210 makestr(&(optlist[noptlist++]),"SVR4ORPOSIX");
11211 #endif /* SVR4ORPOSIX */
11212 #ifdef OS2ORVMS
11213 makestr(&(optlist[noptlist++]),"OS2ORVMS");
11214 #endif /* OS2ORVMS */
11215 #ifdef OS2ORUNIX
11216 makestr(&(optlist[noptlist++]),"OS2ORUNIX");
11217 #endif /* OS2ORUNIX */
11218 #ifdef VMSORUNIX
11219 makestr(&(optlist[noptlist++]),"VMSORUNIX");
11220 #endif /* VMSORUNIX */
11221 #ifdef VMS64BIT
11222 makestr(&(optlist[noptlist++]),"VMS64BIT"); /* VMS on Alpha or IA64 */
11223 #endif /* VMS64BIT */
11224 #ifdef VMSI64
11225 makestr(&(optlist[noptlist++]),"VMSI64"); /* VMS on IA64 */
11226 #endif /* VMSI64 */
11227 #ifdef _POSIX_SOURCE
11228 makestr(&(optlist[noptlist++]),"_POSIX_SOURCE");
11229 #endif /* _POSIX_SOURCE */
11230 #ifdef _XOPEN_SOURCE
11231 makestr(&(optlist[noptlist++]),"_XOPEN_SOURCE");
11232 #endif
11233 #ifdef _ALL_SOURCE
11234 makestr(&(optlist[noptlist++]),"_ALL_SOURCE");
11235 #endif
11236 #ifdef _SVID3
11237 makestr(&(optlist[noptlist++]),"_SVID3");
11238 #endif /* _SVID3 */
11239 #ifdef Plan9
11240 makestr(&(optlist[noptlist++]),"Plan9");
11241 #endif /* Plan9 */
11242 #ifdef SOLARIS
11243 makestr(&(optlist[noptlist++]),"SOLARIS");
11244 #ifdef SOLARIS24
11245 makestr(&(optlist[noptlist++]),"SOLARIS24");
11246 #endif /* SOLARIS24 */
11247 #ifdef SOLARIS25
11248 makestr(&(optlist[noptlist++]),"SOLARIS25");
11249 #endif /* SOLARIS25 */
11250 #ifdef SOLARIS26
11251 makestr(&(optlist[noptlist++]),"SOLARIS26");
11252 #endif /* SOLARIS26 */
11253 #ifdef SOLARIS7
11254 makestr(&(optlist[noptlist++]),"SOLARIS7");
11255 #endif /* SOLARIS7 */
11256 #ifdef SOLARIS8
11257 makestr(&(optlist[noptlist++]),"SOLARIS8");
11258 #endif /* SOLARIS8 */
11259 #ifdef SOLARIS9
11260 makestr(&(optlist[noptlist++]),"SOLARIS9");
11261 #endif /* SOLARIS9 */
11262 #ifdef SOLARIS10
11263 makestr(&(optlist[noptlist++]),"SOLARIS10");
11264 #endif /* SOLARIS10 */
11265 #endif /* SOLARIS */
11266
11267 #ifdef SUNOS4
11268 makestr(&(optlist[noptlist++]),"SUNOS4");
11269 #endif /* SUNOS4 */
11270 #ifdef SUN4S5
11271 makestr(&(optlist[noptlist++]),"SUN4S5");
11272 #endif /* SUN4S5 */
11273 #ifdef IRIX
11274 makestr(&(optlist[noptlist++]),"IRIX");
11275 #endif /* IRIX */
11276 #ifdef ENCORE
11277 makestr(&(optlist[noptlist++]),"ENCORE");
11278 #endif /* ENCORE */
11279 #ifdef ultrix
11280 makestr(&(optlist[noptlist++]),"ultrix");
11281 #endif
11282 #ifdef sxaE50
11283 makestr(&(optlist[noptlist++]),"sxaE50");
11284 #endif
11285 #ifdef mips
11286 makestr(&(optlist[noptlist++]),"mips");
11287 #endif
11288 #ifdef MIPS
11289 makestr(&(optlist[noptlist++]),"MIPS");
11290 #endif
11291 #ifdef vax
11292 makestr(&(optlist[noptlist++]),"vax");
11293 #endif
11294 #ifdef VAX
11295 makestr(&(optlist[noptlist++]),"VAX");
11296 #endif
11297 #ifdef alpha
11298 makestr(&(optlist[noptlist++]),"alpha");
11299 #endif
11300 #ifdef ALPHA
11301 makestr(&(optlist[noptlist++]),"ALPHA");
11302 #endif
11303 #ifdef __ALPHA
11304 makestr(&(optlist[noptlist++]),"__ALPHA");
11305 #endif
11306 #ifdef __alpha
11307 makestr(&(optlist[noptlist++]),"__alpha");
11308 #endif
11309 #ifdef __AXP
11310 makestr(&(optlist[noptlist++]),"__AXP");
11311 #endif
11312 #ifdef AXP
11313 makestr(&(optlist[noptlist++]),"AXP");
11314 #endif
11315 #ifdef axp
11316 makestr(&(optlist[noptlist++]),"axp");
11317 #endif
11318 #ifdef __ALPHA__
11319 makestr(&(optlist[noptlist++]),"__ALPHA__");
11320 #endif
11321 #ifdef __alpha__
11322 makestr(&(optlist[noptlist++]),"__alpha__");
11323 #endif
11324 #ifdef sun
11325 makestr(&(optlist[noptlist++]),"sun");
11326 #endif
11327 #ifdef sun3
11328 makestr(&(optlist[noptlist++]),"sun3");
11329 #endif
11330 #ifdef sun386
11331 makestr(&(optlist[noptlist++]),"sun386");
11332 #endif
11333 #ifdef _SUN
11334 makestr(&(optlist[noptlist++]),"_SUN");
11335 #endif
11336 #ifdef sun4
11337 makestr(&(optlist[noptlist++]),"sun4");
11338 #endif
11339 #ifdef sparc
11340 makestr(&(optlist[noptlist++]),"sparc");
11341 #endif
11342 #ifdef _CRAY
11343 makestr(&(optlist[noptlist++]),"_CRAY");
11344 #endif /* _CRAY */
11345 #ifdef NEXT33
11346 makestr(&(optlist[noptlist++]),"NEXT33");
11347 #endif
11348 #ifdef NEXT
11349 makestr(&(optlist[noptlist++]),"NEXT");
11350 #endif
11351 #ifdef NeXT
11352 makestr(&(optlist[noptlist++]),"NeXT");
11353 #endif
11354 #ifdef MACH
11355 makestr(&(optlist[noptlist++]),"MACH");
11356 #endif
11357
11358 #ifdef MACOSX
11359 makestr(&(optlist[noptlist++]),"MACOSX");
11360 #endif
11361 #ifdef MACOSX10
11362 makestr(&(optlist[noptlist++]),"MACOSX10");
11363 #endif
11364 #ifdef MACOSX103
11365 makestr(&(optlist[noptlist++]),"MACOSX10e");
11366 #endif
11367 #ifdef COMMENT
11368 /* not used */
11369 #ifdef MACOSX103
11370 makestr(&(optlist[noptlist++]),"MACOSX103");
11371 #endif
11372 #endif /* COMMENT */
11373
11374 #ifdef sgi
11375 makestr(&(optlist[noptlist++]),"sgi");
11376 #endif
11377 #ifdef M_SYS5
11378 makestr(&(optlist[noptlist++]),"M_SYS5");
11379 #endif
11380 #ifdef __SYSTEM_FIVE
11381 makestr(&(optlist[noptlist++]),"__SYSTEM_FIVE");
11382 #endif
11383 #ifdef sysV
11384 makestr(&(optlist[noptlist++]),"sysV");
11385 #endif
11386 #ifdef M_XENIX /* SCO Xenix V and UNIX/386 */
11387 makestr(&(optlist[noptlist++]),"M_XENIX");
11388 #endif
11389 #ifdef M_UNIX /* SCO UNIX */
11390 makestr(&(optlist[noptlist++]),"M_UNIX");
11391 #endif
11392 #ifdef _M_UNIX /* SCO UNIX 3.2v4 = ODT 2.0 */
11393 makestr(&(optlist[noptlist++]),"_M_UNIX");
11394 #endif
11395 #ifdef CK_SCOV5
11396 makestr(&(optlist[noptlist++]),"CK_SCOV5");
11397 #endif
11398 #ifdef SCO_OSR504
11399 makestr(&(optlist[noptlist++]),"SCO_OSR504");
11400 #endif
11401 #ifdef M_IA64
11402 makestr(&(optlist[noptlist++]),"M_IA64");
11403 #endif
11404 #ifdef _M_IA64
11405 makestr(&(optlist[noptlist++]),"_M_IA64");
11406 #endif
11407 #ifdef ia64
11408 makestr(&(optlist[noptlist++]),"ia64");
11409 #endif
11410 #ifdef _ia64
11411 makestr(&(optlist[noptlist++]),"_ia64");
11412 #endif
11413 #ifdef _ia64_
11414 makestr(&(optlist[noptlist++]),"_ia64_");
11415 #endif
11416 #ifdef __ia64
11417 makestr(&(optlist[noptlist++]),"__ia64");
11418 #endif
11419 #ifdef M_I686
11420 makestr(&(optlist[noptlist++]),"M_I686");
11421 #endif
11422 #ifdef _M_I686
11423 makestr(&(optlist[noptlist++]),"_M_I686");
11424 #endif
11425 #ifdef i686
11426 makestr(&(optlist[noptlist++]),"i686");
11427 #endif
11428 #ifdef M_I586
11429 makestr(&(optlist[noptlist++]),"M_I586");
11430 #endif
11431 #ifdef _M_I586
11432 makestr(&(optlist[noptlist++]),"_M_I586");
11433 #endif
11434 #ifdef i586
11435 makestr(&(optlist[noptlist++]),"i586");
11436 #endif
11437 #ifdef M_I486
11438 makestr(&(optlist[noptlist++]),"M_I486");
11439 #endif
11440 #ifdef _M_I486
11441 makestr(&(optlist[noptlist++]),"_M_I486");
11442 #endif
11443 #ifdef i486
11444 makestr(&(optlist[noptlist++]),"i486");
11445 #endif
11446 #ifdef M_I386
11447 makestr(&(optlist[noptlist++]),"M_I386");
11448 #endif
11449 #ifdef _M_I386
11450 makestr(&(optlist[noptlist++]),"_M_I386");
11451 #endif
11452 #ifdef i386
11453 makestr(&(optlist[noptlist++]),"i386");
11454 #endif
11455 #ifdef __i386
11456 makestr(&(optlist[noptlist++]),"__i386");
11457 #endif
11458 #ifdef __x86
11459 makestr(&(optlist[noptlist++]),"__x86");
11460 #endif
11461 #ifdef __x86_64
11462 makestr(&(optlist[noptlist++]),"__x86_64");
11463 #endif
11464 #ifdef __amd64
11465 makestr(&(optlist[noptlist++]),"__amd64");
11466 #endif
11467 #ifdef _ILP32
11468 makestr(&(optlist[noptlist++]),"_ILP32");
11469 #endif
11470 #ifdef _ILP64
11471 makestr(&(optlist[noptlist++]),"_ILP64");
11472 #endif
11473 #ifdef _LP32
11474 makestr(&(optlist[noptlist++]),"_LP32");
11475 #endif
11476 #ifdef _LP64
11477 makestr(&(optlist[noptlist++]),"_LP64");
11478 #endif
11479 #ifdef __LP32__
11480 makestr(&(optlist[noptlist++]),"__LP32__");
11481 #endif
11482 #ifdef __LP64__
11483 makestr(&(optlist[noptlist++]),"__LP64__");
11484 #endif
11485 #ifdef _XGP4_2
11486 makestr(&(optlist[noptlist++]),"_XGP4_2");
11487 #endif
11488 #ifdef __ppc__
11489 makestr(&(optlist[noptlist++]),"__ppc__");
11490 #endif
11491 #ifdef __ppc32__
11492 makestr(&(optlist[noptlist++]),"__ppc32__");
11493 #endif
11494 #ifdef __ppc64__
11495 makestr(&(optlist[noptlist++]),"__ppc64__");
11496 #endif
11497 #ifdef CK_64BIT
11498 makestr(&(optlist[noptlist++]),"CK_64BIT");
11499 #endif
11500 #ifdef i286
11501 makestr(&(optlist[noptlist++]),"i286");
11502 #endif
11503 #ifdef M_I286
11504 makestr(&(optlist[noptlist++]),"M_I286");
11505 #endif
11506 #ifdef __sparc
11507 makestr(&(optlist[noptlist++]),"__sparc");
11508 #endif
11509 #ifdef __sparcv8
11510 makestr(&(optlist[noptlist++]),"__sparcv8");
11511 #endif
11512 #ifdef __sparcv9
11513 makestr(&(optlist[noptlist++]),"__sparcv9");
11514 #endif
11515 #ifdef mc68000
11516 makestr(&(optlist[noptlist++]),"mc68000");
11517 #endif
11518 #ifdef mc68010
11519 makestr(&(optlist[noptlist++]),"mc68010");
11520 #endif
11521 #ifdef mc68020
11522 makestr(&(optlist[noptlist++]),"mc68020");
11523 #endif
11524 #ifdef mc68030
11525 makestr(&(optlist[noptlist++]),"mc68030");
11526 #endif
11527 #ifdef mc68040
11528 makestr(&(optlist[noptlist++]),"mc68040");
11529 #endif
11530 #ifdef M_68000
11531 makestr(&(optlist[noptlist++]),"M_68000");
11532 #endif
11533 #ifdef M_68010
11534 makestr(&(optlist[noptlist++]),"M_68010");
11535 #endif
11536 #ifdef M_68020
11537 makestr(&(optlist[noptlist++]),"M_68020");
11538 #endif
11539 #ifdef M_68030
11540 makestr(&(optlist[noptlist++]),"M_68030");
11541 #endif
11542 #ifdef M_68040
11543 makestr(&(optlist[noptlist++]),"M_68040");
11544 #endif
11545 #ifdef m68k
11546 makestr(&(optlist[noptlist++]),"m68k");
11547 #endif
11548 #ifdef m88k
11549 makestr(&(optlist[noptlist++]),"m88k");
11550 #endif
11551 #ifdef pdp11
11552 makestr(&(optlist[noptlist++]),"pdp11");
11553 #endif
11554 #ifdef iAPX
11555 makestr(&(optlist[noptlist++]),"iAPX");
11556 #endif
11557 #ifdef hpux
11558 makestr(&(optlist[noptlist++]),"hpux");
11559 #endif
11560 #ifdef __hpux
11561 makestr(&(optlist[noptlist++]),"__hpux");
11562 #endif
11563 #ifdef __hp9000s800
11564 makestr(&(optlist[noptlist++]),"__hp9000s800");
11565 #endif
11566 #ifdef __hp9000s700
11567 makestr(&(optlist[noptlist++]),"__hp9000s700");
11568 #endif
11569 #ifdef __hp9000s500
11570 makestr(&(optlist[noptlist++]),"__hp9000s500");
11571 #endif
11572 #ifdef __hp9000s300
11573 makestr(&(optlist[noptlist++]),"__hp9000s300");
11574 #endif
11575 #ifdef __hp9000s200
11576 makestr(&(optlist[noptlist++]),"__hp9000s200");
11577 #endif
11578 #ifdef AIX
11579 makestr(&(optlist[noptlist++]),"AIX");
11580 #endif
11581 #ifdef _AIXFS
11582 makestr(&(optlist[noptlist++]),"_AIXFS");
11583 #endif
11584 #ifdef u370
11585 makestr(&(optlist[noptlist++]),"u370");
11586 #endif
11587 #ifdef u3b
11588 makestr(&(optlist[noptlist++]),"u3b");
11589 #endif
11590 #ifdef u3b2
11591 makestr(&(optlist[noptlist++]),"u3b2");
11592 #endif
11593 #ifdef multimax
11594 makestr(&(optlist[noptlist++]),"multimax");
11595 #endif
11596 #ifdef balance
11597 makestr(&(optlist[noptlist++]),"balance");
11598 #endif
11599 #ifdef ibmrt
11600 makestr(&(optlist[noptlist++]),"ibmrt");
11601 #endif
11602 #ifdef _IBMRT
11603 makestr(&(optlist[noptlist++]),"_IBMRT");
11604 #endif
11605 #ifdef ibmrs6000
11606 makestr(&(optlist[noptlist++]),"ibmrs6000");
11607 #endif
11608 #ifdef _AIX
11609 makestr(&(optlist[noptlist++]),"_AIX");
11610 #endif /* _AIX */
11611 #ifdef _IBMR2
11612 makestr(&(optlist[noptlist++]),"_IBMR2");
11613 #endif
11614 #ifdef UNIXWARE
11615 makestr(&(optlist[noptlist++]),"UNIXWARE");
11616 #endif
11617 #ifdef QNX
11618 makestr(&(optlist[noptlist++]),"QNX");
11619 #ifdef __QNX__
11620 makestr(&(optlist[noptlist++]),"__QNX__");
11621 #ifdef __16BIT__
11622 makestr(&(optlist[noptlist++]),"__16BIT__");
11623 #endif
11624 #ifdef CK_QNX16
11625 makestr(&(optlist[noptlist++]),"CK_QNX16");
11626 #endif
11627 #ifdef __32BIT__
11628 makestr(&(optlist[noptlist++]),"__32BIT__");
11629 #endif
11630 #ifdef CK_QNX32
11631 makestr(&(optlist[noptlist++]),"CK_QNX32");
11632 #endif
11633 #endif /* __QNX__ */
11634 #endif /* QNX */
11635
11636 #ifdef QNX6
11637 makestr(&(optlist[noptlist++]),"QNX6");
11638 #endif /* QNX6 */
11639
11640 #ifdef NEUTRINO
11641 makestr(&(optlist[noptlist++]),"NEUTRINO");
11642 #endif /* NEUTRINO */
11643
11644 #ifdef __STRICT_BSD__
11645 makestr(&(optlist[noptlist++]),"__STRICT_BSD__");
11646 #endif
11647 #ifdef __STRICT_ANSI__
11648 makestr(&(optlist[noptlist++]),"__STRICT_ANSI__");
11649 #endif
11650 #ifdef _ANSI_C_SOURCE
11651 makestr(&(optlist[noptlist++]),"_ANSI_C_SOURCE");
11652 #endif
11653 #ifdef __STDC__
11654 makestr(&(optlist[noptlist++]),"__STDC__");
11655 #endif
11656 #ifdef cplusplus
11657 makestr(&(optlist[noptlist++]),"cplusplus");
11658 #endif
11659 #ifdef __DECC
11660 makestr(&(optlist[noptlist++]),"__DECC");
11661 #ifdef __DECC_VER
11662 sprintf(line,"__DECC_VER=%d",__DECC_VER); /* SAFE */
11663 makestr(&(optlist[noptlist++]),line);
11664 #endif /* __DECC_VER */
11665 #endif /* __DECC */
11666 #ifdef __CRTL_VER
11667 sprintf(line,"__CRTL_VER=%d",__CRTL_VER); /* SAFE */
11668 makestr(&(optlist[noptlist++]),line);
11669 #endif /* __CRTL_VER */
11670 #ifdef __GNUC__ /* gcc in ansi mode */
11671 makestr(&(optlist[noptlist++]),"__GNUC__");
11672 #endif
11673 #ifdef GNUC /* gcc in traditional mode */
11674 makestr(&(optlist[noptlist++]),"GNUC");
11675 #endif
11676 #ifdef __EGCS__ /* egcs in ansi mode */
11677 makestr(&(optlist[noptlist++]),"__EGCS__");
11678 #endif
11679 #ifdef __egcs__ /* egcs in ansi mode */
11680 makestr(&(optlist[noptlist++]),"__egcs__");
11681 #endif
11682 #ifdef __WATCOMC__
11683 makestr(&(optlist[noptlist++]),"__WATCOMC__");
11684 #endif
11685 #ifdef CK_ANSIC
11686 makestr(&(optlist[noptlist++]),"CK_ANSIC");
11687 #endif
11688 #ifdef CK_ANSILIBS
11689 makestr(&(optlist[noptlist++]),"CK_ANSILIBS");
11690 #endif
11691 #ifdef CKCONINTB4CB
11692 makestr(&(optlist[noptlist++]),"CKCONINTB4CB");
11693 #endif /* CKCONINTB4CB */
11694 #ifdef NOTERMCAP
11695 makestr(&(optlist[noptlist++]),"NOTERMCAP");
11696 #endif /* NOTERMCAP */
11697 #ifdef __GLIBC__
11698 makestr(&(optlist[noptlist++]),"__GLIBC__");
11699 #endif
11700 #ifdef _SC_JOB_CONTROL
11701 makestr(&(optlist[noptlist++]),"_SC_JOB_CONTROL");
11702 #endif
11703 #ifdef _POSIX_JOB_CONTROL
11704 makestr(&(optlist[noptlist++]),"_POSIX_JOB_CONTROL");
11705 #endif
11706 #ifdef SIG_I
11707 makestr(&(optlist[noptlist++]),"SIG_I");
11708 #endif /* SIG_I */
11709 #ifdef SIG_V
11710 makestr(&(optlist[noptlist++]),"SIG_V");
11711 #endif /* SIG_V */
11712 #ifdef CK_POSIX_SIG
11713 makestr(&(optlist[noptlist++]),"CK_POSIX_SIG");
11714 #endif
11715 #ifdef SVR3JC
11716 makestr(&(optlist[noptlist++]),"SVR3JC");
11717 #endif
11718 #ifdef _386BSD
11719 makestr(&(optlist[noptlist++]),"_386BSD");
11720 #endif
11721 #ifdef _BSD
11722 makestr(&(optlist[noptlist++]),"_BSD");
11723 #endif
11724 #ifdef USE_MEMCPY
11725 makestr(&(optlist[noptlist++]),"USE_MEMCPY");
11726 #endif /* USE_MEMCPY */
11727 #ifdef USE_LSTAT
11728 makestr(&(optlist[noptlist++]),"USE_LSTAT");
11729 #endif /* USE_LSTAT */
11730 #ifdef TERMIOX
11731 makestr(&(optlist[noptlist++]),"TERMIOX");
11732 #endif /* TERMIOX */
11733 #ifdef STERMIOX
11734 makestr(&(optlist[noptlist++]),"STERMIOX");
11735 #endif /* STERMIOX */
11736 #ifdef CK_CURSES
11737 makestr(&(optlist[noptlist++]),"CK_CURSES");
11738 #endif /* CK_CURSES */
11739 #ifdef CK_NEWTERM
11740 makestr(&(optlist[noptlist++]),"CK_NEWTERM");
11741 #endif /* CK_NEWTERM */
11742 #ifdef CK_WREFRESH
11743 makestr(&(optlist[noptlist++]),"CK_WREFRESH");
11744 #endif /* CK_WREFRESH */
11745 #ifdef CK_PCT_BAR
11746 makestr(&(optlist[noptlist++]),"CK_PCT_BAR");
11747 #endif /* CK_PCT_BAR */
11748 #ifdef CK_DTRCD
11749 makestr(&(optlist[noptlist++]),"CK_DTRCD");
11750 #endif /* CK_DTRCD */
11751 #ifdef CK_DTRCTS
11752 makestr(&(optlist[noptlist++]),"CK_DTRCTS");
11753 #endif /* CK_DTRCTS */
11754 #ifdef CK_RTSCTS
11755 makestr(&(optlist[noptlist++]),"CK_RTSCTS");
11756 #endif /* CK_RTSCTS */
11757 #ifdef POSIX_CRTSCTS
11758 makestr(&(optlist[noptlist++]),"POSIX_CRTSCTS");
11759 #endif /* POSIX_CRTSCTS */
11760 #ifdef FIXCRTSCTS
11761 makestr(&(optlist[noptlist++]),"FIXCRTSCTS");
11762 #endif /* FIXCRTSCTS */
11763 #ifdef HWPARITY
11764 makestr(&(optlist[noptlist++]),"HWPARITY");
11765 #endif /* HWPARITY */
11766 #ifdef CK_SYSINI
11767 #ifdef CK_INI_A
11768 makestr(&(optlist[noptlist++]),"CK_INI_A");
11769 ckmakmsg(line,LINBUFSIZ,"CK_SYSINI=\"",CK_SYSINI,"\"",NULL);
11770 makestr(&(optlist[noptlist++]),line);
11771 #else
11772 #ifdef CK_INI_B
11773 makestr(&(optlist[noptlist++]),"CK_INI_B");
11774 ckmakmsg(line,LINBUFSIZ,"CK_SYSINI=\"",CK_SYSINI,"\"",NULL);
11775 makestr(&(optlist[noptlist++]),line);
11776 #else
11777 makestr(&(optlist[noptlist++]),"CK_SYSINI");
11778 #endif /* CK_INI_B */
11779 #endif /* CK_INI_A */
11780 #endif /* CK_DSYSINI */
11781 #ifdef CK_DSYSINI
11782 makestr(&(optlist[noptlist++]),"CK_DSYSINI");
11783 #endif /* CK_DSYSINI */
11784 #ifdef CK_TTGWSIZ
11785 makestr(&(optlist[noptlist++]),"CK_TTGWSIZ");
11786 #endif /* CK_TTGWSIZ */
11787 #ifdef CK_NAWS
11788 makestr(&(optlist[noptlist++]),"CK_NAWS");
11789 #endif /* CK_NAWS */
11790 #ifdef MDMHUP
11791 makestr(&(optlist[noptlist++]),"MDMHUP");
11792 #endif /* MDMHUP */
11793 #ifdef HUP_CLOSE_POSIX
11794 makestr(&(optlist[noptlist++]),"HUP_CLOSE_POSIX");
11795 #endif /* HUP_CLOSE_POSIX */
11796 #ifdef NO_HUP_CLOSE_POSIX
11797 makestr(&(optlist[noptlist++]),"NO_HUP_CLOSE_POSIX");
11798 #endif /* NO_HUP_CLOSE_POSIX */
11799 #ifdef DCMDBUF
11800 makestr(&(optlist[noptlist++]),"DCMDBUF");
11801 #endif /* DCMDBUF */
11802 #ifdef CK_RECALL
11803 makestr(&(optlist[noptlist++]),"CK_RECALL");
11804 #endif /* CK_RECALL */
11805 #ifdef BROWSER
11806 makestr(&(optlist[noptlist++]),"BROWSER");
11807 #endif /* BROWSER */
11808 #ifdef CLSOPN
11809 makestr(&(optlist[noptlist++]),"CLSOPN");
11810 #endif /* CLSOPN */
11811 #ifdef STRATUS
11812 makestr(&(optlist[noptlist++]),"STRATUS");
11813 #endif /* STRATUS */
11814 #ifdef __VOS__
11815 makestr(&(optlist[noptlist++]),"__VOS__");
11816 #endif /* __VOS__ */
11817 #ifdef STRATUSX25
11818 makestr(&(optlist[noptlist++]),"STRATUSX25");
11819 #endif /* STRATUSX25 */
11820 #ifdef OS2MOUSE
11821 makestr(&(optlist[noptlist++]),"OS2MOUSE");
11822 #endif /* OS2MOUSE */
11823 #ifdef CK_REXX
11824 makestr(&(optlist[noptlist++]),"CK_REXX");
11825 #endif /* CK_REXX */
11826 #ifdef CK_TIMERS
11827 makestr(&(optlist[noptlist++]),"CK_TIMERS");
11828 #endif /* CK_TIMERS */
11829 #ifdef TTSPDLIST
11830 makestr(&(optlist[noptlist++]),"TTSPDLIST");
11831 #endif /* TTSPDLIST */
11832 #ifdef CK_PERMS
11833 makestr(&(optlist[noptlist++]),"CK_PERMS");
11834 #endif /* CK_PERMS */
11835 #ifdef CKTUNING
11836 makestr(&(optlist[noptlist++]),"CKTUNING");
11837 #endif /* CKTUNING */
11838 #ifdef NEWFTP
11839 makestr(&(optlist[noptlist++]),"NEWFTP");
11840 #endif /* NEWFTP */
11841 #ifdef SYSFTP
11842 makestr(&(optlist[noptlist++]),"SYSFTP");
11843 #endif /* SYSFTP */
11844 #ifdef NOFTP
11845 makestr(&(optlist[noptlist++]),"NOFTP");
11846 #endif /* NOFTP */
11847 #ifdef CKHTTP
11848 makestr(&(optlist[noptlist++]),"CKHTTP");
11849 #endif /* CKHTTP */
11850 #ifdef NOHTTP
11851 makestr(&(optlist[noptlist++]),"NOHTTP");
11852 #endif /* NOHTTP */
11853 #ifdef CKROOT
11854 makestr(&(optlist[noptlist++]),"CKROOT");
11855 #endif /* CKROOT */
11856 #ifdef CKREALPATH
11857 makestr(&(optlist[noptlist++]),"CKREALPATH");
11858 #endif /* CKREALPATH */
11859 #ifdef STREAMING
11860 makestr(&(optlist[noptlist++]),"STREAMING");
11861 #endif /* STREAMING */
11862 #ifdef UNPREFIXZERO
11863 makestr(&(optlist[noptlist++]),"UNPREFIXZERO");
11864 #endif /* UNPREFIXZERO */
11865 #ifdef CKREGEX
11866 makestr(&(optlist[noptlist++]),"CKREGEX");
11867 #endif /* CKREGEX */
11868 #ifdef ZXREWIND
11869 makestr(&(optlist[noptlist++]),"ZXREWIND");
11870 #endif /* ZXREWIND */
11871 #ifdef CKSYSLOG
11872 makestr(&(optlist[noptlist++]),"CKSYSLOG");
11873 #endif /* CKSYSLOG */
11874 #ifdef SYSLOGLEVEL
11875 sprintf(line,"SYSLOGLEVEL=%d",SYSLOGLEVEL); /* SAFE */
11876 makestr(&(optlist[noptlist++]),line);
11877 #endif /* SYSLOGLEVEL */
11878 #ifdef NOSEXP
11879 makestr(&(optlist[noptlist++]),"NOSEXP");
11880 #endif /* NOSEXP */
11881 #ifdef CKLEARN
11882 makestr(&(optlist[noptlist++]),"CKLEARN");
11883 #else
11884 #ifdef NOLOEARN
11885 makestr(&(optlist[noptlist++]),"NOLOEARN");
11886 #endif /* NOLOEARN */
11887 #endif /* CKLEARN */
11888 #ifdef BETATEST
11889 makestr(&(optlist[noptlist++]),"BETATEST");
11890 #endif /* BETATEST */
11891
11892 #ifdef NOFLOAT
11893 makestr(&(optlist[noptlist++]),"NOFLOAT");
11894 #else
11895 #ifdef FNFLOAT
11896 makestr(&(optlist[noptlist++]),"FNFLOAT");
11897 #endif /* FNFLOAT */
11898 #ifdef CKFLOAT
11899 #ifdef GFTIMER
11900 makestr(&(optlist[noptlist++]),"GFTIMER");
11901 #endif /* GFTIMER */
11902 #ifdef CKFLOAT_S
11903 ckmakmsg(line,LINBUFSIZ,"CKFLOAT=",CKFLOAT_S,NULL,NULL);
11904 makestr(&(optlist[noptlist++]),line);
11905 #else
11906 makestr(&(optlist[noptlist++]),"CKFLOAT");
11907 #endif /* CKFLOAT_S */
11908 #endif /* CKFLOAT */
11909 #endif /* NOFLOAT */
11910
11911 #ifdef SSH
11912 makestr(&(optlist[noptlist++]),"SSH");
11913 #endif /* SSH */
11914 #ifdef NETDLL
11915 makestr(&(optlist[noptlist++]),"NETDLL");
11916 #endif /* NETDLL */
11917 #ifdef NETFILE
11918 makestr(&(optlist[noptlist++]),"NETFILE");
11919 #endif /* NETFILE */
11920 #ifdef CK_TAPI
11921 makestr(&(optlist[noptlist++]),"CK_TAPI");
11922 #endif /* CK_TAPI */
11923 #ifdef CK_SSL
11924 makestr(&(optlist[noptlist++]),"CK_SSL");
11925 #ifdef OPENSSL_VERSION_TEXT
11926 ckmakmsg(line,LINBUFSIZ,
11927 "OPENSSL_VERSION_TEXT=","\"",OPENSSL_VERSION_TEXT,"\"");
11928 makestr(&(optlist[noptlist++]),line);
11929 #endif /* OPENSSL_VERSION_TEXT */
11930 #endif /* CK_SSL */
11931 debug(F101,"initoptlist noptlist","",noptlist);
11932 sh_sort(optlist,NULL,noptlist,0,0,0);
11933 }
11934
11935 int
shofea()11936 shofea() {
11937 int i;
11938 int flag = 0;
11939 int lines = 1;
11940 #ifdef FNFLOAT
11941 extern int fp_digits, fp_rounding;
11942 #endif /* FNFLOAT */
11943 extern int byteorder;
11944 printf("%s\n",versio);
11945 if (inserver)
11946 return(1);
11947
11948 debug(F101,"shofea NOPTLIST","",NOPTLIST);
11949 initoptlist();
11950 debug(F101,"shofea noptlist","",noptlist);
11951 #ifdef OS2
11952 #ifdef NT
11953 #ifdef _M_ALPHA
11954 printf("Microsoft Windows Operating Systems for Alpha CPUs.\n");
11955 #else /* _M_ALPHA */
11956 #ifdef _M_PPC
11957 printf("Microsoft Windows Operating Systems for PowerPC CPUs.\n");
11958 #else /* _M_PPC */
11959 #ifdef _M_MRX000
11960 printf("Microsoft Windows Operating Systems for MIPS CPUs.\n");
11961 #else /* _M_MRX000 */
11962 #ifdef _M_IX86
11963 printf("Microsoft Windows Operating Systems for 32-bit Intel CPUs.\n");
11964 #else /* _M_IX86 */
11965 UNKNOWN WINDOWS PLATFORM
11966 #endif /* _M_IX86 */
11967 #endif /* _M_MRX000 */
11968 #endif /* _M_PPC */
11969 #endif /* _M_ALPHA */
11970 #else /* NT */
11971 #ifdef M_I286
11972 printf("IBM OS/2 16-bit.\n");
11973 #else
11974 printf("IBM OS/2 32-bit.\n");
11975 #endif /* M_I286 */
11976 #endif /* NT */
11977 lines++;
11978 #endif /* OS2 */
11979 printf("\n");
11980 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11981 printf("Major optional features included:\n");
11982 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11983
11984 if (sizeof(CK_OFF_T) == 8) {
11985 printf(" Large files and large integers (64 bits)\n");
11986 if (++lines > cmd_rows - 3) {
11987 if (!askmore()) return(1); else lines = 0;
11988 }
11989 }
11990 #ifdef NETCONN
11991 printf(" Network support (type SHOW NET for further info)\n");
11992 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11993 #ifdef IKS_OPTION
11994 printf(" Telnet Kermit Option\n");
11995 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
11996 #endif /* IKS_OPTION */
11997 #ifdef CK_AUTHENTICATION
11998 printf(" Telnet Authentication Option\n");
11999 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12000 #ifdef CK_KERBEROS
12001 #ifdef KRB4
12002 #ifdef KRB5
12003 printf(" Kerberos(TM) IV and Kerberos V authentication\n");
12004 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12005 #else /* KRB5 */
12006 printf(" Kerberos(TM) IV authentication\n");
12007 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12008 #endif /* KRB5 */
12009 #else /* KRB4 */
12010 #ifdef KRB5
12011 printf(" Kerberos(TM) V authentication\n");
12012 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12013 #endif /* KRB5 */
12014 #endif /* KRB4 */
12015 #endif /* CK_KERBEROS */
12016 #ifdef CK_SRP
12017 printf(" SRP(TM) (Secure Remote Password) authentication\n");
12018 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12019 #endif /* CK_SRP */
12020 #ifdef CK_SSL
12021 printf(" Secure Sockets Layer (SSL)\n");
12022 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12023 printf(" Transport Layer Security (TLS)\n");
12024 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12025 #endif /* CK_SSL */
12026 #ifdef SSHBUILTIN
12027 printf(" Secure Shell (SSH) [internal]\n");
12028 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12029 #endif /* SSHBUILTIN */
12030 #ifdef SSHCMD
12031 printf(" Secure Shell (SSH) [external]\n");
12032 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12033 #endif /* SSHCMD */
12034 #ifdef CK_ENCRYPTION
12035 printf(" Telnet Encryption Option\n");
12036 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12037 #ifdef CK_DES
12038 printf(" Telnet DES Encryption\n");
12039 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12040 #endif /* CK_DES */
12041 #ifdef CK_CAST
12042 printf(" Telnet CAST Encryption\n");
12043 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12044 #endif /* CK_CAST */
12045
12046 #ifdef CK_KERBEROS
12047 #ifdef KRB5
12048 #ifdef ALLOW_KRB_3DES_ENCRYPT
12049 printf(" Kerberos 3DES/AES Telnet Encryption\n");
12050 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12051 #endif /* ALLOW_KRB_3DES_ENCRYPT */
12052 #endif /* KRB5 */
12053 #endif /* CK_KERBEROS */
12054
12055 #endif /* CK_ENCRYPTION */
12056 #endif /* CK_AUTHENTICATION */
12057 #ifdef CK_FORWARD_X
12058 printf(" X Windows forwarding\n");
12059 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12060 #endif /* CK_FORWARD_X */
12061 #ifdef TN_COMPORT
12062 printf(" Telnet Remote Com Port Control Option\n");
12063 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12064 #endif /* TN_COMPORT */
12065 #ifdef CK_SOCKS
12066 #ifdef CK_SOCKS5
12067 printf(" SOCKS 5\n");
12068 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12069 #else /* CK_SOCKS5 */
12070 printf(" SOCKS 4\n");
12071 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12072 #endif /* CK_SOCKS5 */
12073 #endif /* CK_SOCKS */
12074 #ifdef NEWFTP
12075 printf(" Built-in FTP client\n");
12076 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12077 #endif /* NEWFTP */
12078 #ifdef CKHTTP
12079 printf(" Built-in HTTP client\n");
12080 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12081 #endif /* CKHTTP */
12082 #endif /* NETCONN */
12083
12084 #ifdef CK_RTSCTS
12085 printf(" Hardware flow control\n");
12086 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12087 #endif /* CK_RTSCTS */
12088
12089 #ifdef CK_XYZ
12090 #ifdef XYZ_INTERNAL
12091 printf(" Built-in XYZMODEM protocols\n");
12092 #else
12093 printf(" External XYZMODEM protocol support\n");
12094 #endif /* XYZ_INTERNAL */
12095 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12096 #endif /* CK_XYZ */
12097
12098 #ifndef NOCSETS
12099 printf(" Latin-1 (West European) character-set translation\n");
12100 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12101 #ifdef LATIN2
12102 printf(" Latin-2 (East European) character-set translation\n");
12103 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12104 #endif /* LATIN2 */
12105 #ifdef CYRILLIC
12106 printf(" Cyrillic (Russian, Ukrainian, etc) character-set translation\n");
12107 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12108 #endif /* CYRILLIC */
12109 #ifdef GREEK
12110 printf(" Greek character-set translation\n");
12111 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12112 #endif /* GREEK */
12113 #ifdef HEBREW
12114 printf(" Hebrew character-set translation\n");
12115 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12116 #endif /* HEBREW */
12117 #ifdef KANJI
12118 printf(" Japanese character-set translation\n");
12119 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12120 #endif /* KANJI */
12121 #ifdef UNICODE
12122 printf(" Unicode character-set translation\n");
12123 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12124 #endif /* UNICODE */
12125 #ifdef CKOUNI
12126 if (isunicode())
12127 printf(" Unicode support for ISO-2022 Terminal Emulation\n");
12128 else
12129 printf(" Unicode translation for Terminal Character-Sets\n");
12130 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12131 #endif /* CKOUNI */
12132 #endif /* NOCSETS */
12133
12134 #ifdef NETPTY
12135 printf(" Pseudoterminal control\n");
12136 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12137 #endif /* NETPTY */
12138
12139 #ifdef CK_REDIR
12140 printf(" REDIRECT command\n");
12141 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12142 #endif /* CK_REDIR */
12143
12144 #ifdef CK_RESEND
12145 printf(" RESEND command\n");
12146 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12147 #endif /* CK_RESEND */
12148
12149 #ifndef NOXFER
12150 #ifdef CK_CURSES
12151 printf(" Fullscreen file transfer display\n");
12152 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12153 #endif /* CK_CURSES */
12154 #endif /* NOXFER */
12155
12156 #ifdef CK_SPEED
12157 printf(" Control-character unprefixing\n");
12158 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12159 #endif /* CK_SPEED */
12160
12161 #ifdef STREAMING
12162 printf(" Streaming\n");
12163 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12164 #endif /* STREAMING */
12165
12166 #ifdef CK_AUTODL
12167 printf(" Autodownload\n");
12168 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12169 #endif /* CK_AUTODL */
12170
12171 #ifdef OS2MOUSE
12172 printf(" Mouse support\n");
12173 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12174 #endif /* OS2MOUSE */
12175
12176 #ifdef CK_REXX
12177 printf(" REXX script language interface\n");
12178 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12179 #endif /* CK_REXX */
12180
12181 #ifdef IKSD
12182 #ifdef CK_LOGIN
12183 printf(" Internet Kermit Service with user login support\n");
12184 #else /* CK_LOGIN */
12185 printf(" Internet Kermit Service without user login support\n");
12186 #endif /* CK_LOGIN */
12187 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12188 #endif /* IKSD */
12189
12190 printf("\n");
12191 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12192 printf("Major optional features not included:\n");
12193 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12194
12195 if (sizeof(CK_OFF_T) <= 4) {
12196 printf(" No large files or large integers\n");
12197 if (++lines > cmd_rows - 3) {
12198 if (!askmore()) return(1); else lines = 0;
12199 }
12200 }
12201
12202 #ifdef NOXFER
12203 printf(" No file-transfer protocols\n");
12204 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12205 flag = 1;
12206 #else
12207 #ifndef CK_CURSES
12208 #ifndef MAC
12209 printf(" No fullscreen file transfer display\n");
12210 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12211 flag = 1;
12212 #endif /* MAC */
12213 #endif /* CK_CURSES */
12214
12215 #ifdef NOSERVER
12216 printf(" No server mode\n");
12217 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12218 flag = 1;
12219 #endif /* NOSERVER */
12220
12221 #ifndef CK_SPEED
12222 printf(" No control-character unprefixing\n");
12223 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12224 flag = 1;
12225 #endif /* CK_SPEED */
12226
12227 #ifndef STREAMING
12228 printf(" No streaming\n");
12229 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12230 flag = 1;
12231 #endif /* STREAMING */
12232
12233 #ifndef CK_AUTODL
12234 printf(" No autodownload\n");
12235 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12236 flag = 1;
12237 #endif /* CK_AUTODL */
12238
12239 #ifndef CK_XYZ
12240 printf(" No built-in XYZMODEM protocols\n");
12241 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12242 flag = 1;
12243 #endif /* CK_XYZ */
12244
12245 #ifdef NOFLOAT
12246 printf(" No floating-point arithmetic\n");
12247 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12248 flag = 1;
12249 printf(" No S-Expressions (LISP interpreter)\n");
12250 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12251 flag = 1;
12252 #else
12253 #ifdef NOSEXP
12254 printf(" No S-Expressions (LISP interpreter)\n");
12255 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12256 flag = 1;
12257 #endif /* NOSEXP */
12258 #endif /* NOFLOAT */
12259
12260 #ifdef NOTLOG
12261 printf(" No transaction log\n");
12262 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12263 flag = 1;
12264 #endif /* NOTLOG */
12265 #endif /* NOXFER */
12266
12267 #ifdef NODEBUG
12268 printf(" No debugging\n");
12269 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12270 flag = 1;
12271 #endif /* NODEBUG */
12272
12273 #ifdef NOHELP
12274 printf(" No built-in help\n");
12275 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12276 flag = 1;
12277 #endif /* NOHELP */
12278
12279 #ifdef NOLOCAL
12280 printf(" No making connections\n");
12281 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12282 flag = 1;
12283 #else
12284 #ifndef NETCONN
12285 printf(" No network support\n");
12286 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12287 flag = 1;
12288 #else /* NETCONN */
12289 #ifndef IKS_OPTION
12290 printf(" No Telnet Kermit Option\n");
12291 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12292 flag = 1;
12293 #endif /* IKS_OPTION */
12294 #endif /* NETCONN */
12295
12296 #ifdef NOSSH
12297 printf(" No Secure Shell (SSH)\n");
12298 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12299 #endif /* NOSSH */
12300 #ifndef CK_AUTHENTICATION
12301 printf(" No Kerberos(TM) authentication\n");
12302 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12303 printf(" No SRP(TM) (Secure Remote Password) protocol\n");
12304 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12305 printf(" No Secure Sockets Layer (SSL) protocol\n");
12306 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12307 printf(" No Transport Layer Security (TLS) protocol\n");
12308 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12309 printf(" No encryption\n");
12310 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12311 flag = 1;
12312 #else /* CK_AUTHENTICATION */
12313 #ifndef CK_KERBEROS
12314 printf(" No Kerberos(TM) authentication\n");
12315 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12316 flag = 1;
12317 #else /* CK_KERBEROS */
12318 #ifndef KRB4
12319 printf(" No Kerberos(TM) IV authentication\n");
12320 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12321 flag = 1;
12322 #endif /* KRB4 */
12323 #ifndef KRB5
12324 printf(" No Kerberos(TM) V authentication\n");
12325 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12326 flag = 1;
12327 #endif /* KRB5 */
12328 #endif /* CK_KERBEROS */
12329 #ifndef CK_SRP
12330 printf(" No SRP(TM) (Secure Remote Password) authentication\n");
12331 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12332 flag = 1;
12333 #endif /* CK_SRP */
12334 #ifndef CK_SSL
12335 printf(" No Secure Sockets Layer (SSL) protocol\n");
12336 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12337 printf(" No Transport Layer Security (TLS) protocol\n");
12338 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12339 flag = 1;
12340 #endif /* CK_SSL */
12341 #ifndef CK_ENCRYPTION
12342 printf(" No Telnet Encryption Option\n");
12343 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12344 flag = 1;
12345 #else /* CK_ENCRYPTION */
12346 #ifndef OS2
12347 #ifndef CK_DES
12348 printf(" No Telnet DES encryption\n");
12349 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12350 flag = 1;
12351 #endif /* CK_DES */
12352 #ifndef CK_CAST
12353 printf(" No Telnet CAST encryption\n");
12354 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12355 flag = 1;
12356 #endif /* CK_CAST */
12357
12358 #ifdef COMMENT
12359 #ifdef CK_KERBEROS
12360 #ifdef KRB5
12361 #ifndef ALLOW_KRB_3DES_ENCRYPT
12362 printf(" No Kerberos 3DES/AES Telnet Encryption\n");
12363 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12364 #endif /* ALLOW_KRB_3DES_ENCRYPT */
12365 #endif /* KRB5 */
12366 #endif /* CK_KERBEROS */
12367 #endif /* COMMENT */
12368
12369 #endif /* OS2 */
12370 #endif /* CK_ENCRYPTION */
12371 #endif /* CK_AUTHENTICATION */
12372 #ifndef CK_FORWARD_X
12373 printf(" No X Windows forwarding\n");
12374 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12375 #endif /* CK_FORWARD_X */
12376 #ifndef TN_COMPORT
12377 printf(" No Telnet Remote Com Port Control Option\n");
12378 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12379 #endif /* TN_COMPORT */
12380 #ifndef CK_SOCKS
12381 printf(" No SOCKS\n");
12382 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12383 #endif /* CK_SOCKS */
12384 #ifndef NEWFTP
12385 printf(" No built-in FTP client\n");
12386 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12387 #endif /* NEWFTP */
12388 #ifdef NOHTTP
12389 printf(" No built-in HTTP client\n");
12390 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12391 #endif /* NOHTTP */
12392
12393 #ifdef NODIAL
12394 printf(" No DIAL command\n");
12395 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12396 flag = 1;
12397 #else
12398 #ifdef MINIDIAL
12399 printf(" Support for most modem types excluded\n");
12400 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12401 flag = 1;
12402 #endif /* MINIDIAL */
12403 #endif /* NODIAL */
12404 #endif /* NOLOCAL */
12405
12406 #ifndef CK_RTSCTS
12407 #ifndef MAC
12408 printf(" No hardware flow control\n");
12409 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12410 flag = 1;
12411 #endif /* MAC */
12412 #endif /* CK_RTSCTS */
12413
12414 #ifdef NOXMIT
12415 printf(" No TRANSMIT command\n");
12416 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12417 flag = 1;
12418 #endif /* NOXMIT */
12419
12420 #ifdef NOSCRIPT
12421 printf(" No SCRIPT command\n");
12422 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12423 flag = 1;
12424 #endif /* NOSCRIPT */
12425
12426 #ifdef NOSPL
12427 printf(" No script programming features\n");
12428 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12429 flag = 1;
12430 #endif /* NOSPL */
12431
12432 #ifdef NOCSETS
12433 printf(" No character-set translation\n");
12434 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12435 flag = 1;
12436 #else
12437
12438 #ifndef LATIN2
12439 printf(" No Latin-2 character-set translation\n");
12440 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12441 flag = 1;
12442 #endif /* LATIN2 */
12443
12444 #ifdef NOGREEK
12445 printf(" No Greek character-set translation\n");
12446 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12447 flag = 1;
12448 #endif /* NOGREEK */
12449
12450 #ifdef NOHEBREW
12451 printf(" No Hebrew character-set translation\n");
12452 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12453 flag = 1;
12454 #endif /* NOHEBREW */
12455
12456 #ifdef NOUNICODE
12457 printf(" No Unicode character-set translation\n");
12458 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12459 flag = 1;
12460 #endif /* NOUNICODE */
12461
12462 #ifdef NOCYRIL
12463 printf(" No Cyrillic character-set translation\n");
12464 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12465 flag = 1;
12466 #endif /* NOCYRIL */
12467
12468 #ifndef KANJI
12469 printf(" No Kanji character-set translation\n");
12470 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12471 flag = 1;
12472 #endif /* KANJI */
12473 #endif /* NOCSETS */
12474
12475 #ifdef NOCMDL
12476 printf(" No command-line arguments\n");
12477 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12478 flag = 1;
12479 #endif /* NOCMDL */
12480
12481 #ifdef NOPUSH
12482 printf(" No escape to system\n");
12483 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12484 flag = 1;
12485 #endif /* NOPUSH */
12486
12487 #ifdef NOJC
12488 #ifdef UNIX
12489 printf(" No UNIX job control\n");
12490 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12491 flag = 1;
12492 #endif /* UNIX */
12493 #endif /* NOJC */
12494
12495 #ifdef NOSETKEY
12496 printf(" No SET KEY command\n");
12497 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12498 flag = 1;
12499 #endif /* NOSETKEY */
12500
12501 #ifndef CK_REDIR
12502 printf(" No REDIRECT or PIPE command\n");
12503 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12504 flag = 1;
12505 #endif /* CK_REDIR */
12506
12507 #ifdef UNIX
12508 #ifndef NETPTY
12509 printf(" No pseudoterminal control\n");
12510 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12511 flag = 1;
12512 #endif /* NETPTY */
12513 #endif /* UNIX */
12514
12515 #ifndef CK_RESEND
12516 printf(" No RESEND command\n");
12517 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12518 flag = 1;
12519 #endif /* CK_RESEND */
12520
12521 #ifdef OS2
12522 #ifdef __32BIT__
12523 #ifndef OS2MOUSE
12524 printf(" No Mouse support\n");
12525 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12526 flag = 1;
12527 #endif /* __32BIT__ */
12528 #endif /* OS2 */
12529 #endif /* OS2MOUSE */
12530
12531 #ifdef OS2
12532 #ifndef NT
12533 #ifndef CK_REXX
12534 printf(" No REXX script language interface\n");
12535 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12536 flag = 1;
12537 #endif /* CK_REXX */
12538 #endif /* NT */
12539 #endif /* OS2 */
12540
12541 #ifndef IKSD
12542 printf(" No Internet Kermit Service\n");
12543 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12544 flag = 1;
12545 #endif /* IKSD */
12546
12547 if (flag == 0) {
12548 printf(" None\n");
12549 if (++lines > cmd_rows - 3)
12550 { if (!askmore()) return(1); else lines = 0; }
12551 }
12552 printf("\n");
12553 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12554
12555 #ifdef CK_UTSNAME
12556 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12557 printf("Host info:\n");
12558 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12559 printf(" Machine: %s\n",unm_mch[0] ? unm_mch : "(unknown)");
12560 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12561 printf(" Model: %s\n",unm_mod[0] ? unm_mod : "(unknown)");
12562 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12563 printf(" OS: %s\n",unm_nam[0] ? unm_nam : "(unknown)");
12564 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12565 printf(" OS Release: %s\n",unm_rel[0] ? unm_rel : "(unknown)");
12566 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12567 printf(" OS Version: %s\n",unm_ver[0] ? unm_ver : "(unknown)");
12568 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12569 printf("\n");
12570 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12571 #endif /* CK_UTSNAME */
12572
12573 /*
12574 Print compile-time (-D) options, as well as C preprocessor
12575 predefined symbols that might affect us...
12576 */
12577 #ifdef KTARGET
12578 {
12579 char * s; /* Makefile target */
12580 s = KTARGET;
12581 if (!s) s = "";
12582 if (!*s) s = "(unknown)";
12583 printf("\n");
12584 if (++lines > cmd_rows - 3) {
12585 if (!askmore()) return(1); else lines = 0;
12586 }
12587 printf("Target: %s\n", s);
12588 if (++lines > cmd_rows - 3) {
12589 if (!askmore()) return(1); else lines = 0;
12590 }
12591 }
12592 #endif /* KTARGET */
12593
12594 #ifdef __VERSION__
12595 #ifdef __GNUC__
12596 printf("GCC version: %s\n", __VERSION__);
12597 #else
12598 printf("Compiler version: %s\n", __VERSION__);
12599 #endif /* __GNUC__ */
12600 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12601 #endif /* __VERSION__ */
12602
12603 #ifdef __DATE__ /* GNU and other ANSI */
12604 #ifdef __TIME__
12605 printf("Compiled %s %s, options:\n", __DATE__, __TIME__);
12606 #else
12607 printf("Compiled %s, options:\n", __DATE__);
12608 #endif /* __TIME__ */
12609 #else /* !__DATE__ */
12610 printf("Compiler options:\n");
12611 #endif /* __DATE__ */
12612 if (++lines > cmd_rows - 3) { if (!askmore()) return(1); else lines = 0; }
12613
12614 for (i = 0; i < noptlist; i++) /* Print sorted option list */
12615 if (!prtopt(&lines,optlist[i]))
12616 return(0);
12617
12618 if (!prtopt(&lines,"")) return(0); /* Start a new section */
12619
12620 /* Sizes of data types */
12621
12622 ckmakmsg(line,
12623 LINBUFSIZ,
12624 "byte order: ",
12625 byteorder ? "little" : "big",
12626 " endian",
12627 NULL
12628 );
12629 {
12630 /* Whether to use %d or %ld with sizeof is a portability issue, so... */
12631 int size = 0;
12632
12633 if (!prtopt(&lines,line)) return(0);
12634 if (!prtopt(&lines,"")) return(0); /* Start a new section */
12635
12636 size = (int)sizeof(int);
12637 sprintf(line,"sizeofs: int=%d",size); /* SAFE */
12638 if (!prtopt(&lines,line)) return(0);
12639
12640 size = (int)sizeof(long);
12641 sprintf(line,"long=%d",size); /* SAFE */
12642 if (!prtopt(&lines,line)) return(0);
12643
12644 #ifndef OS2
12645 /* Windows doesn't have off_t */
12646 size = (int)sizeof(off_t);
12647 sprintf(line,"off_t=%d",size); /* SAFE */
12648 if (!prtopt(&lines,line)) return(0);
12649 #endif /* OS2 */
12650
12651 size = (int)sizeof(CK_OFF_T);
12652 sprintf(line,"CK_OFF_T=%d",size); /* SAFE */
12653 if (!prtopt(&lines,line)) return(0);
12654
12655 #ifdef BIGBUFOK
12656 size = (int)sizeof(size_t);
12657 sprintf(line,"size_t=%d",size); /* SAFE */
12658 if (!prtopt(&lines,line)) return(0);
12659 #endif /* BIGBUFOK */
12660
12661 size = (int)sizeof(short);
12662 sprintf(line,"short=%d",size); /* SAFE */
12663 if (!prtopt(&lines,line)) return(0);
12664
12665 size = (int)sizeof(char);
12666 sprintf(line,"char=%d",size); /* SAFE */
12667 if (!prtopt(&lines,line)) return(0);
12668
12669 size = (int)sizeof(char *);
12670 sprintf(line,"char*=%d",size); /* SAFE */
12671 if (!prtopt(&lines,line)) return(0);
12672
12673 size = (int)sizeof(float);
12674 sprintf(line,"float=%d",size); /* SAFE */
12675 if (!prtopt(&lines,line)) return(0);
12676
12677 size = (int)sizeof(double);
12678 sprintf(line,"double=%d",size); /* SAFE */
12679 if (!prtopt(&lines,line)) return(0);
12680 }
12681
12682 #ifdef FNFLOAT
12683 if (!prtopt(&lines,"")) return(0); /* Start a new section */
12684 if (!prtopt(&lines,"floating-point:")) return(0);
12685 sprintf(line,"precision=%d",fp_digits); /* SAFE */
12686 if (!prtopt(&lines,line)) return(0);
12687 sprintf(line,"rounding=%d",fp_rounding); /* SAFE */
12688 if (!prtopt(&lines,line)) return(0);
12689 #endif /* FNFLOAT */
12690
12691 prtopt(&lines,"");
12692 return(0);
12693 }
12694 #endif /* NOSHOW */
12695 #endif /* NOICP */
12696