Annotation of coherent/e/bin/ckermit/ckuus5.c, revision 1.1

1.1     ! root        1: #ifndef NOICP
        !             2: 
        !             3: /*  C K U U S 5 --  "User Interface" for Unix Kermit, part 5  */
        !             4:  
        !             5: /*
        !             6:   Author: Frank da Cruz ([email protected], [email protected]),
        !             7:   Columbia University Center for Computing Activities.
        !             8:   First released January 1985.
        !             9:   Copyright (C) 1985, 1992, Trustees of Columbia University in the City of New
        !            10:   York.  Permission is granted to any individual or institution to use this
        !            11:   software as long as it is not sold for profit.  This copyright notice must be
        !            12:   retained.  This software may not be included in commercial products without
        !            13:   written permission of Columbia University.
        !            14: */
        !            15: 
        !            16: /* Includes */
        !            17: 
        !            18: #include "ckcdeb.h"
        !            19: #include "ckcasc.h"
        !            20: #include "ckcker.h"
        !            21: #include "ckuusr.h"
        !            22: #include "ckcnet.h"
        !            23: #ifndef NOCSETS
        !            24: #include "ckcxla.h"
        !            25: #endif /* NOCSETS */
        !            26: #ifdef MAC
        !            27: #include "ckmasm.h"
        !            28: #endif /* MAC */
        !            29: 
        !            30: /* For formatted screens, "more?" prompting, etc. */
        !            31: 
        !            32: #define SCRNLEN 21                     /* Screen length */
        !            33: #define SCRNWID 79                     /* Screen width */
        !            34: 
        !            35: #ifdef FT18
        !            36: #define isxdigit(c) isdigit(c)
        !            37: #endif /* FT18 */
        !            38: 
        !            39: #ifdef MAC                             /* Internal MAC file routines */
        !            40: #define feof mac_feof
        !            41: #define rewind mac_rewind
        !            42: #define fgets mac_fgets
        !            43: #define fopen mac_fopen
        !            44: #define fclose mac_fclose
        !            45: 
        !            46: int mac_feof();
        !            47: void mac_rewind();
        !            48: char *mac_fgets();
        !            49: FILE *mac_fopen();
        !            50: int mac_fclose();
        !            51: #endif /* MAC */
        !            52: 
        !            53: /* External variables */
        !            54: 
        !            55: extern int carrier, cdtimo, local, backgrd, bgset, sosi, suspend,
        !            56:   displa, binary, deblog, escape, xargs, flow, cmdmsk,
        !            57:   duplex, ckxech, pktlog, seslog, tralog, what,
        !            58:   keep, warn, tlevel, cwdf, nfuncs, unkcs, msgflg,
        !            59:   mdmtyp, zincnt, cmask, rcflag, success, xitsta, pflag, lf_opts, tnlm, tn_nlm;
        !            60: 
        !            61: extern char *ccntab[];
        !            62: 
        !            63: #ifndef NOFRILLS
        !            64: extern int en_cwd, en_del, en_dir, en_fin, en_bye,
        !            65:   en_get, en_hos, en_sen, en_set, en_spa, en_typ, en_who;
        !            66: #endif /* NOFRILLS */
        !            67: extern long vernum;
        !            68: extern int srvtim, srvdis, incase, inecho, intime, insilence, nvars, verwho;
        !            69: extern char *protv, *fnsv, *cmdv, *userv, *ckxv, *ckzv, *ckzsys, *xlav,
        !            70:  *cknetv, *clcmds;
        !            71: extern char *connv, *dialv, *loginv, *nvlook();
        !            72: 
        !            73: #ifndef NOSCRIPT
        !            74: extern int secho;
        !            75: #endif /* NOSCRIPT */
        !            76: 
        !            77: #ifndef NODIAL
        !            78: extern int nmdm;
        !            79: extern struct keytab mdmtab[];
        !            80: #endif /* NODIAL */
        !            81: 
        !            82: #ifdef NETCONN
        !            83: extern int tn_init, network, ttnproto;
        !            84: #endif /* NETCONN */
        !            85: 
        !            86: #ifdef OS2
        !            87: extern int tt_type, tt_arrow, tt_keypad, tt_wrap;
        !            88: #endif /* OS2 */
        !            89: extern int tt_crd;
        !            90: 
        !            91: #ifndef NOCSETS
        !            92: extern int language, nfilc, tcsr, tcsl;
        !            93: extern struct keytab fcstab[];
        !            94: #ifndef MAC
        !            95: extern struct keytab ttcstab[];
        !            96: #endif /* MAC */
        !            97: #endif /* NOCSETS */
        !            98: 
        !            99: extern int atcapr,
        !           100:   atenci, atenco, atdati, atdato, atleni, atleno, atblki, atblko,
        !           101:   attypi, attypo, atsidi, atsido, atsysi, atsyso, atdisi, atdiso; 
        !           102: 
        !           103: extern long speed;
        !           104: 
        !           105: extern char *DIRCMD, *PWDCMD, *DELCMD;
        !           106: #ifndef NOXMIT
        !           107: extern int xmitf, xmitl, xmitp, xmitx, xmits, xmitw;
        !           108: extern char xmitbuf[];
        !           109: #endif /* NOXMIT */
        !           110: 
        !           111: extern char **xargv, *versio, *ckxsys, *dftty, *cmarg, *lp;
        !           112: 
        !           113: #ifdef DCMDBUF
        !           114: extern char *cmdbuf, *atmbuf;          /* Command buffers */
        !           115: #ifndef NOSPL
        !           116: extern char *savbuf;                   /* Command buffers */
        !           117: #endif /* NOSPL */
        !           118: #else
        !           119: extern char cmdbuf[], atmbuf[];                /* Command buffers */
        !           120: #ifndef NOSPL
        !           121: extern char savbuf[];                  /* Command buffers */
        !           122: #endif /* NOSPL */
        !           123: #endif /* DCMDBUF */
        !           124: 
        !           125: extern char toktab[], ttname[], psave[];
        !           126: extern CHAR sstate;
        !           127: extern int cmflgs, techo, terror, repars, ncmd;
        !           128: extern struct keytab cmdtab[];
        !           129: 
        !           130: #ifndef MAC
        !           131: #ifndef NOSETKEY
        !           132: KEY *keymap;
        !           133: MACRO *macrotab;
        !           134: #endif /* NOSETKEY */
        !           135: #endif /* MAC */
        !           136: 
        !           137: #ifndef NOSPL
        !           138: extern struct mtab *mactab;
        !           139: extern struct keytab vartab[], fnctab[];
        !           140: extern int cmdlvl, maclvl, nmac, mecho, merror;
        !           141: #endif /* NOSPL */
        !           142: 
        !           143: FILE *tfile[MAXTAKE];                  /* TAKE file stack */
        !           144: char *tfnam[MAXTAKE];
        !           145: 
        !           146: #ifndef NOSPL
        !           147: /* Local declarations */
        !           148: 
        !           149: int nulcmd = 0;                        /* Flag for next cmd to be ignored */
        !           150: 
        !           151: /* Definitions for built-in macros */
        !           152: 
        !           153: /* First, the single line macros, installed with addmac()... */
        !           154: 
        !           155: /* IBM-LINEMODE macro */
        !           156: char *m_ibm = "set parity mark, set dupl half, set handsh xon, set flow none";
        !           157: 
        !           158: /* FATAL macro */
        !           159: char *m_fat = "if def \\%1 echo \\%1, if not = \\v(local) 0 hangup, stop 1";
        !           160: 
        !           161: #ifdef COMMENT
        !           162: /*
        !           163:   Long macro definitions were formerly done like this.  But some compilers
        !           164:   cannot handle continued string constants, others cannot handle string
        !           165:   constants that are this long.  So these definitions have been broken up
        !           166:   into pieces and put into arrays, see below.
        !           167: */
        !           168: char *m_forx = "if def _floop ass \\%9 \\fdef(_floop),else def \\%9,\
        !           169: ass _floop { _getargs,\
        !           170: define \\\\\\%1 \\%2,:top,if \\%5 \\\\\\%1 \\%3 goto bot,\
        !           171: \\%6,:inc, incr \\\\\\%1 \\%4,goto top,:bot,_putargs,return},\
        !           172: def break goto bot, def continue goto inc,\
        !           173: do _floop \\%1 \\%2 \\%3 \\%4 { \\%5 },assign _floop \\fcont(\\%9)";
        !           174: 
        !           175: char *m_while = "if def _wloop ass \\%9 \\fdef(_wloop),\
        !           176: ass _wloop {_getargs,:wtest,\\%1,\\%2,goto wtest,:wbot,_putargs,return},\
        !           177: def break goto wbot, def continue goto wtest,\
        !           178: do _wloop,assign _wloop \\fcont(\\%9)";
        !           179: 
        !           180: char *m_xif = "ass \\%9 \\fdef(_ify),ass _ify {_getargs, \\%1, _putargs},\
        !           181: do _ify,ass _ify \\fcont(\\%9)";
        !           182: #endif /* COMMENT */
        !           183: 
        !           184: /* Now the multiline macros, defined with addmmac()... */
        !           185: 
        !           186: /* FOR macro */
        !           187: char *for_def[] = { "_assign _for\\v(cmdlevel) { _getargs,",
        !           188: "define \\\\\\%1 \\%2,:top,if \\%5 \\\\\\%1 \\%3 goto bot,",
        !           189: "\\%6,:inc,incr \\\\\\%1 \\%4,goto top,:bot,_putargs},",
        !           190: "def break goto bot, def continue goto inc,",
        !           191: "do _for\\v(cmdlevel) \\%1 \\%2 \\%3 \\%4 { \\%5 },_assign _for\\v(cmdlevel)",
        !           192: ""};
        !           193: #ifdef COMMENT
        !           194: /*
        !           195:   This one didn't work right.  When an interior loop finished executing,
        !           196:   the definition of the enclosing loop was restored, but the new definition
        !           197:   could be in a different location in memory, so its macro execution pointer
        !           198:   could (and usually was) pointing at garbage.
        !           199: */
        !           200: char *old_for_def[] = { "if def _floop ass \\%9 \\fdef(_floop),else def \\%9,",
        !           201: "ass _floop { _getargs,",
        !           202: "define \\\\\\%1 \\%2,:top,if \\%5 \\\\\\%1 \\%3 goto bot,",
        !           203: "\\%6,:inc, incr \\\\\\%1 \\%4,goto top,:bot,_putargs,return},",
        !           204: "def break goto bot, def continue goto inc,",
        !           205: "do _floop \\%1 \\%2 \\%3 \\%4 { \\%5 },assign _floop \\fcont(\\%9)",
        !           206: ""};
        !           207: #endif /* COMMENT */
        !           208: 
        !           209: /* WHILE macro */
        !           210: char *whil_def[] = { "_assign _whi\\v(cmdlevel) {_getargs,",
        !           211: ":wtest,\\%1,\\%2,goto wtest,:wbot,_putargs},",
        !           212: "def break goto wbot, def continue goto wtest,",
        !           213: "do _whi\\v(cmdlevel),_assign _whi\\v(cmdlevel)",
        !           214: ""};
        !           215: #ifdef COMMENT
        !           216: /*
        !           217:   Same deal as FOR loop...
        !           218: */
        !           219: char *old_whil_def[] = { "if def _wloop asg \\%9 \\fdef(_wloop),",
        !           220: "asg _wloop {_getargs,:wtest,\\%1,\\%2,goto wtest,:wbot,_putargs,return},",
        !           221: "def break goto wbot, def continue goto wtest,",
        !           222: "do _wloop,assign _wloop \\fcont(\\%9)",
        !           223: ""};
        !           224: #endif /* COMMENT */
        !           225: 
        !           226: /* XIF macro */
        !           227: char *xif_def[] = {
        !           228: "_assign _if\\v(cmdlevel) {_getargs,\\%1,_putargs},",
        !           229: "do _if\\v(cmdlevel),_assign _if\\v(cmdlevel)",
        !           230: ""};
        !           231: #ifdef COMMENT
        !           232: /* Same deal */
        !           233: char *old_xif_def[] = {
        !           234: "asg \\%9 \\fdef(_ify),ass _ify {_getargs, \\%1, _putargs},",
        !           235: "do _ify,ass _ify \\fcont(\\%9)",
        !           236: ""};
        !           237: #endif /* COMMENT */
        !           238: 
        !           239: /* Variables declared here for use by other ckuus*.c modules */
        !           240: /* Space is allocated here to save room in ckuusr.c */
        !           241: 
        !           242: #ifdef DCMDBUF
        !           243: struct cmdptr *cmdstk;
        !           244: int *ifcmd, *count, *iftest;
        !           245: #else
        !           246: struct cmdptr cmdstk[CMDSTKL];
        !           247: int ifcmd[CMDSTKL], count[CMDSTKL], iftest[CMDSTKL];
        !           248: #endif /* DCMDBUF */
        !           249: 
        !           250: char *m_arg[MACLEVEL][NARGS];
        !           251: char *g_var[GVARS], *macp[MACLEVEL], *mrval[MACLEVEL];
        !           252: int macargc[MACLEVEL];
        !           253: char *macx[MACLEVEL];
        !           254: extern char varnam[];
        !           255: 
        !           256: char **a_ptr[27];                      /* Array pointers, for arrays a-z */
        !           257: int a_dim[27];                         /* Dimensions for each array */
        !           258: 
        !           259: char inpbuf[INPBUFSIZ] = { NUL };      /* Buffer for INPUT and REINPUT */
        !           260: char inpbufa[2] = { NUL, NUL };                /* Null terminators for INPUT buffer */
        !           261: char inchar[2] = { NUL, NUL };         /* Last character that was INPUT */
        !           262: int  incount = 0;                      /* INPUT character count */
        !           263: 
        !           264: char lblbuf[50];                       /* Buffer for labels */
        !           265: #endif /* NOSPL */
        !           266: 
        !           267: #ifdef DCMDBUF
        !           268: char *line;                            /* Character buffer for anything */
        !           269: #else
        !           270: char line[LINBUFSIZ];
        !           271: #endif /* DCMDBUF */
        !           272: 
        !           273: #ifdef CK_CURSES
        !           274: #ifndef TRMBUFL
        !           275: #define TRMBUFL 1024
        !           276: #endif /* TRMBUFL */
        !           277: #ifdef DCMDBUF
        !           278: char *trmbuf;                          /* Character buffer for termcap */
        !           279: #else
        !           280: char trmbuf[TRMBUFL];
        !           281: #endif /* DCMDBUF */
        !           282: #endif /* CK_CURSES */
        !           283: 
        !           284: extern char pktfil[],
        !           285: #ifdef DEBUG
        !           286:   debfil[],
        !           287: #endif /* DEBUG */
        !           288: #ifdef TLOG
        !           289:   trafil[],
        !           290: #endif /* TLOG */
        !           291:   sesfil[],
        !           292:   cmdstr[];
        !           293: #ifndef NOFRILLS
        !           294: extern int rmailf, rprintf;            /* REMOTE MAIL & PRINT items */
        !           295: extern char optbuf[];
        !           296: #endif /* NOFRILLS */
        !           297: 
        !           298: char *homdir = "";                     /* Pointer to home directory string */
        !           299: 
        !           300: char tmpbuf[50], *tp;                  /* Temporary buffer */
        !           301: char numbuf[20];                       /* Buffer for numeric strings. */
        !           302: char kermrc[100];                      /* Name of initialization file */
        !           303: int noinit = 0;                                /* Flag for skipping init file */
        !           304: 
        !           305: #ifndef NOSPL
        !           306: _PROTOTYP( static long expon, (long, long) );
        !           307: _PROTOTYP( static long gcd, (long, long) );
        !           308: _PROTOTYP( static long fact, (long) );
        !           309: int                                    /* Initialize macro data structures. */
        !           310: macini() {            /* Allocate mactab and preset the first element. */
        !           311:     if (!(mactab = (struct mtab *) malloc(sizeof(struct mtab) * MAC_MAX)))
        !           312:        return(-1);
        !           313:     mactab[0].kwd = NULL;
        !           314:     mactab[0].mval = NULL;
        !           315:     mactab[0].flgs = 0;
        !           316:     return(0);
        !           317: }
        !           318: #endif /* NOSPL */
        !           319: 
        !           320: /*  C M D I N I  --  Initialize the interactive command parser  */
        !           321:  
        !           322: VOID
        !           323: cmdini() {
        !           324:     int i, x, y, z;
        !           325: #ifndef NOSPL
        !           326: /*
        !           327:   On stack in case of recursion!
        !           328: */
        !           329:     char vnambuf[VNAML];               /* Buffer for variable names */
        !           330: #endif /* NOSPL */
        !           331: 
        !           332: #ifndef MAC
        !           333: #ifndef NOSETKEY                       /* Allocate & initialize the keymap */
        !           334:     if (!(keymap = (KEY *) malloc(sizeof(KEY)*KMSIZE)))
        !           335:       fatal("cmdini: no memory for keymap");
        !           336:     if (!(macrotab = (MACRO *) malloc(sizeof(MACRO)*KMSIZE)))
        !           337:       fatal("cmdini: no memory for macrotab");
        !           338:     for ( i = 0; i < KMSIZE; i++ ) {
        !           339:        keymap[i] = i;
        !           340:        macrotab[i] = NULL;
        !           341:     }
        !           342: #ifdef OS2
        !           343:     keymapinit();
        !           344: #endif /* OS2 */
        !           345: #endif /* NOSETKEY */
        !           346: #endif /* MAC */
        !           347: 
        !           348: #ifdef DCMDBUF
        !           349:     if (cmsetup() < 0) fatal("Can't allocate command buffers!");
        !           350: #ifndef NOSPL
        !           351:     if (!(cmdstk = (struct cmdptr *) malloc(sizeof(struct cmdptr)*CMDSTKL)))
        !           352:        fatal("cmdini: no memory for cmdstk");
        !           353:     if (!(ifcmd = (int *) malloc(sizeof(int)*CMDSTKL)))
        !           354:        fatal("cmdini: no memory for ifcmd");
        !           355:     if (!(count = (int *) malloc(sizeof(int)*CMDSTKL)))
        !           356:        fatal("cmdini: no memory for count");
        !           357:     if (!(iftest = (int *) malloc(sizeof(int)*CMDSTKL)))
        !           358:        fatal("cmdini: no memory for iftest");
        !           359: #endif /* NOSPL */
        !           360: #ifdef CK_CURSES
        !           361: /*
        !           362:   Termcap buffer for fullscreen display, UNIX only.  VMS does it another way.
        !           363:   The fullscreen display is not supported on AOS/VS or OS-9, etc, yet, and
        !           364:   the Mac has its own built-in fullscreen display.
        !           365: */
        !           366: #ifdef UNIX
        !           367:     if (!(trmbuf = malloc(TRMBUFL+1)))
        !           368:        fatal("cmdini: no memory for termcap buffer");
        !           369: #endif /* UNIX */
        !           370: #endif /* CK_CURSES */
        !           371:     if (!(line = malloc(LINBUFSIZ)))
        !           372:        fatal("cmdini: no memory for line");
        !           373: #endif /* DCMDBUF */
        !           374: 
        !           375: #ifndef NOSPL
        !           376:     if (macini() < 0) fatal("Can't allocate macro buffers!");
        !           377: #endif /* NOSPL */
        !           378: 
        !           379: #ifdef AMIGA
        !           380:     if (tlevel < 0)    
        !           381:       concb(escape);
        !           382: #endif /* AMIGA */
        !           383: 
        !           384: #ifndef NOSPL
        !           385:     cmdlvl = 0;                                /* Start at command level 0 */
        !           386:     cmdstk[cmdlvl].src = CMD_KB;
        !           387:     cmdstk[cmdlvl].lvl = 0;
        !           388: #endif /* NOSPL */
        !           389: 
        !           390:     tlevel = -1;                       /* Take file level = keyboard */
        !           391:     for (i = 0; i < MAXTAKE; i++)      /* Initialize command file names */
        !           392:       tfnam[i] = NULL;
        !           393: 
        !           394: #ifdef MAC 
        !           395:     cmsetp("Mac-Kermit>");             /* Set default prompt */
        !           396: #else
        !           397:     cmsetp("C-Kermit>");               /* Set default prompt */
        !           398: #endif /* MAC */
        !           399: 
        !           400: #ifndef NOSPL
        !           401:     initmac();                         /* Initialize macro table */
        !           402: /* Add one-line macros */
        !           403:     addmac("ibm-linemode",m_ibm);      /* Add built-in macros. */
        !           404:     addmac("fatal",m_fat);             /* FATAL macro. */
        !           405: /* Add multiline macros */
        !           406:     addmmac("_forx",for_def);          /* FOR macro. */
        !           407:     addmmac("_xif",xif_def);           /* XIF macro. */
        !           408:     addmmac("_while",whil_def);                /* WHILE macro. */
        !           409: /* Fill in command line argument vector */
        !           410:     sprintf(vnambuf,"\\&@[%d]",xargs);         /* Command line argument vector */
        !           411:     y = arraynam(vnambuf,&x,&z);       /* goes in array \&@[] */
        !           412:     if (y > -1) {
        !           413:        dclarray((char)x,z);            /* Declare the array */
        !           414:        for (i = 0; i < xargs; i++) {   /* Fill it */
        !           415:            sprintf(vnambuf,"\\&@[%d]",i);
        !           416:            addmac(vnambuf,xargv[i]);
        !           417:        }
        !           418:     }
        !           419:     *vnambuf = NUL;
        !           420: #endif /* NOSPL */
        !           421: 
        !           422: /* Get our home directory now.  This needed in lots of places. */
        !           423: 
        !           424:     homdir = zhome();
        !           425: 
        !           426: /* If skipping init file ('-Y' on Kermit command line), return now. */
        !           427: 
        !           428:     if (noinit) return;
        !           429: 
        !           430: #ifdef OS2
        !           431: /*
        !           432:   The -y init file must be fully specified or in the current directory.
        !           433:   KERMRC is looked for via INIT, PATH and DPATH in that order.  Finally, our
        !           434:   own executable file path is taken and the .EXE suffix is replaced by .INI
        !           435:   and this is tried as initialization file.
        !           436: */
        !           437:     if (rcflag) {
        !           438:        strcpy(line, kermrc);
        !           439:     } else {
        !           440:        _searchenv(kermrc,"INIT",line);
        !           441:        if (line[0] == 0)
        !           442:          _searchenv(kermrc,"PATH",line);
        !           443:        if (line[0] == 0)
        !           444:          _searchenv(kermrc,"DPATH",line);
        !           445:        if (line[0] == 0) {
        !           446:            char *pgmptr = GetLoadPath();
        !           447:            if (pgmptr) {
        !           448:              lp = strrchr(pgmptr, '.');
        !           449:              strncpy(line, pgmptr, lp - pgmptr);
        !           450:              strcpy(line + (lp - pgmptr), ".ini");
        !           451:            }
        !           452:        }
        !           453:     }
        !           454:     if ((tfile[0] = fopen(line,"r")) != NULL) {
        !           455:         tlevel = 0;
        !           456:        if (tfnam[tlevel] = malloc(strlen(line)+1))
        !           457:          strcpy(tfnam[tlevel],line);
        !           458: #ifndef NOSPL
        !           459:        cmdlvl++;
        !           460:        cmdstk[cmdlvl].src = CMD_TF;
        !           461:        cmdstk[cmdlvl].lvl = tlevel;
        !           462:        ifcmd[cmdlvl] = 0;
        !           463:        iftest[cmdlvl] = 0;
        !           464:        count[cmdlvl] = 0;
        !           465: #endif /* NOSPL */
        !           466:         debug(F110,"init file",line,0);
        !           467:     } else {
        !           468:         debug(F100,"no init file","",0);
        !           469:     }
        !           470: #else /* not OS2 */
        !           471:     lp = line;
        !           472:     lp[0] = '\0';
        !           473: #ifdef GEMDOS
        !           474:     zkermini(line,rcflag, kermrc);
        !           475: #else
        !           476: #ifdef VMS
        !           477:     zkermini(line,LINBUFSIZ,kermrc);
        !           478: #else /* not VMS */
        !           479:     if (rcflag) {                      /* If init file name from cmd line */
        !           480:        strcpy(lp,kermrc);              /* use it */
        !           481:     } else {                           /* otherwise */
        !           482:        if (homdir) {                   /* look in home directory for it */
        !           483:            strcpy(lp,homdir);
        !           484:            if (lp[0] == '/') strcat(lp,"/");
        !           485:        }
        !           486:        strcat(lp,kermrc);              /* and use the default name */
        !           487:     }
        !           488: #endif /* VMS */
        !           489: #endif /* GEMDOS */
        !           490: 
        !           491: #ifdef AMIGA
        !           492:     reqoff();                          /* disable requestors */
        !           493: #endif /* AMIGA */
        !           494: 
        !           495:     debug(F110,"ini file is",line,0);
        !           496:     if ((tfile[0] = fopen(line,"r")) != NULL) {
        !           497:        tlevel = 0;
        !           498:        if (tfnam[tlevel] = malloc(strlen(line)+1))
        !           499:          strcpy(tfnam[tlevel],line);
        !           500: #ifndef NOSPL
        !           501:        cmdlvl++;
        !           502:        ifcmd[cmdlvl] = 0;
        !           503:        iftest[cmdlvl] = 0;
        !           504:        count[cmdlvl] = 0;
        !           505:        debug(F101,"open ok","",cmdlvl);
        !           506:        cmdstk[cmdlvl].src = CMD_TF;
        !           507:        cmdstk[cmdlvl].lvl = tlevel;
        !           508: #endif /* NOSPL */
        !           509:        debug(F110,"init file",line,0);
        !           510:     }
        !           511:     if (homdir && (tlevel < 0)) {
        !           512:        strcpy(lp,kermrc);
        !           513:        if ((tfile[0] = fopen(line,"r")) != NULL) {
        !           514:            tlevel = 0;
        !           515:        if (tfnam[tlevel] = malloc(strlen(line)+1))
        !           516:          strcpy(tfnam[tlevel],line);
        !           517: #ifndef NOSPL
        !           518:            cmdlvl++;
        !           519:            cmdstk[cmdlvl].src = CMD_TF;
        !           520:            cmdstk[cmdlvl].lvl = tlevel;
        !           521:            ifcmd[cmdlvl] = 0;
        !           522:            iftest[cmdlvl] = 0;
        !           523:            count[cmdlvl] = 0;
        !           524: #endif /* NOSPL */
        !           525:        }
        !           526:     }
        !           527: #endif /* OS2 */
        !           528: #ifdef AMIGA
        !           529:     reqpop();                          /* Restore requestors */
        !           530: #endif /* AMIGA */
        !           531: }
        !           532: 
        !           533: #ifndef NOSPL
        !           534: /*
        !           535:   G E T N C M
        !           536: 
        !           537:   Get next command from current macro definition.
        !           538: 
        !           539:   Moved to a separate routine in edit 181 to allow multiline GET
        !           540:   to work when issued in a macro.
        !           541: 
        !           542:   Command is copied into string pointed to by argument s, max length n.
        !           543:   Returns:
        !           544:    0 if a string was copied, -1 if there was no string to copy.
        !           545: */
        !           546: int
        !           547: getncm(s,n) char *s; int n; {
        !           548:     int y, kp = 0, pp = 0;
        !           549:     char *s2;
        !           550:     
        !           551:     s2 = s;
        !           552:     *s = NUL;                          /* Copy next cmd to command buffer. */
        !           553:     
        !           554:     debug(F111,"getncm",s,n);
        !           555: 
        !           556:     for (y = 0;
        !           557:         macp[maclvl] && *macp[maclvl] && y < n;
        !           558:         y++, s++, macp[maclvl]++) {
        !           559:        
        !           560:        *s = *macp[maclvl];             /* Get next character */
        !           561:        debug(F000,"char","",*s);
        !           562: /*
        !           563:   Allow braces around macro definition to prevent commas from being turned to
        !           564:   end-of-lines and also treat any commas within parens as text so that
        !           565:   multiple-argument functions won't cause the command to break prematurely.
        !           566: */
        !           567:        if (*s == '{') kp++;            /* Count braces */
        !           568:        if (*s == '}') kp--;
        !           569:        if (*s == '(') pp++;            /* Count parentheses. */
        !           570:        if (*s == ')') pp--;
        !           571:        if (*s == ',' && pp <= 0 && kp <= 0) {
        !           572:            macp[maclvl]++;
        !           573:            debug(F110,"next cmd",s,0);
        !           574:            kp = pp = 0;
        !           575:            break;
        !           576:        }
        !           577:     }                                  /* Reached end. */
        !           578:     if (*s2 == NUL) {                  /* If nothing was copied, */
        !           579:        debug(F100,"getncm eom","",0);
        !           580:        popclvl();                      /* pop command level. */
        !           581:        return(-1);
        !           582:     } else {                           /* otherwise, tack CR onto end */
        !           583:        *s++ = CR;
        !           584:        *s = '\0';
        !           585:        if (mecho && pflag)
        !           586:          printf("%s\n",s2);
        !           587:        debug(F101,"getncm returns ptr to",s2,0);
        !           588:     }
        !           589:     return(0);
        !           590: }
        !           591: #endif /* NOSPL */
        !           592: 
        !           593: /*
        !           594:   G E T N C T
        !           595: 
        !           596:   Get next command from current TAKE file.
        !           597: 
        !           598:   Moved to a separate routine in edit 181 to allow multiline GET
        !           599:   to work when issued in a macro.
        !           600: 
        !           601:   Command is copied into string pointed to by argument s, max length n.
        !           602:   Returns:
        !           603:    0 if a string was copied,
        !           604:   -1 on EOF,
        !           605:   -2 on malloc failure
        !           606:   -3 if line not properly terminated
        !           607: */
        !           608: int
        !           609: getnct(s,n) char *s; int n; {
        !           610:     int i, j;
        !           611:     char c, *s2, *lp, *lp2;
        !           612: 
        !           613:     s2 = s;                            /* Remember original pointer */
        !           614: 
        !           615:     debug(F101,"getnct","",n);
        !           616:     if (!(lp2 = (char *) malloc(n+1))) { /* Get a temporary buffer */
        !           617:        debug(F101,"getnct malloc failure","",0);
        !           618:        return(-2);
        !           619:     }
        !           620:     lp = lp2;                          /* Make a working pointer */
        !           621:                                        /* (lp2 must not change!) */
        !           622: 
        !           623:     while (1) {                                /* Loop to read lines from file */
        !           624:     
        !           625:        if (fgets(lp2,n,tfile[tlevel]) == NULL) { /* EOF */
        !           626:            free(lp2);                  /* Free temporary storage */
        !           627:            *s = NUL;                   /* Make destination be empty */
        !           628:            return(-1);                 /* Return failure code */
        !           629:        }
        !           630:        debug(F110,"Line from TAKE file",lp2,0); /* Got a line */
        !           631:        if (techo && pflag)             /* If TAKE ECHO ON, */
        !           632:          printf("%s",lp2);             /* echo it. */
        !           633: 
        !           634:        lp = lp2;                       /* Make a working pointer */
        !           635: 
        !           636: /* Trim trailing whitespace */
        !           637: 
        !           638:        j = strlen(lp2) - 1;            /* Position of line terminator */
        !           639:        if (j < 0) j = 0;
        !           640:        c = lp2[j];                     /* Value of line terminator */
        !           641:        if (c < LF || c > CR) {         /* It's not a terminator */
        !           642:            debug(F111,"getnct bad line",lp2,c);
        !           643:            if (feof(tfile[tlevel]) && j > 0 && j < n) {
        !           644:                printf("Warning: Last line of TAKE file lacks terminator\n");
        !           645:                c = lp2[++j] = '\n';
        !           646:            } else return(-3);
        !           647:        }
        !           648:        for (i = j - 1; i > -1; i--)    /* Back up over spaces and tabs */
        !           649:          if (lp2[i] != SP && lp2[i] != HT && lp2[i] != NUL)
        !           650:            break;
        !           651:        lp2[i+1] = c;                   /* Move after last nonblank char */
        !           652:        lp2[i+2] = NUL;                 /* Terminate the string */
        !           653:        while (*s++ = *lp++) {          /* Copy result to target buffer */
        !           654:            if (--n < 2) {
        !           655:                printf("?Command too long, maximum length: %d.\n",CMDBL);
        !           656:                free(lp2);
        !           657:                return(dostop());
        !           658:            }
        !           659: 
        !           660: /* Check for trailing comment, " ;" or " #" */
        !           661: 
        !           662:            if ((s > s2 + 1) &&
        !           663:                (*(s-1) == ';' || *(s-1) == '#') &&
        !           664:                (*(s-2) == SP  || *(s-2) == HT)) {
        !           665:                debug(F100,"Trailing comment","",0);
        !           666:                s -= 2;                 /* Got one, back up buffer pointer */
        !           667:                n += 2;                 /* and adjust free space count. */
        !           668:                while ((s >= s2)        /* Trim whitespace again. */
        !           669:                       && (*s == SP || *s == HT))
        !           670:                  s--, n++;
        !           671:                s++;                    /* Point after last character */
        !           672:                *s++ = c;               /* Put back line terminator */
        !           673:                *s++ = NUL;             /* and string terminator */
        !           674:                n -= 3;                 /* Adjust free count */
        !           675:                debug(F110,"Comment trimmed & terminated",s2,0);
        !           676:                break;
        !           677:            }
        !           678:        }
        !           679: 
        !           680: /* Check whether this line is continued */
        !           681: 
        !           682:        debug(F000,"Last char in line","",*(s-3));
        !           683:        if (*(s - 3) != CMDQ && *(s - 3) != '-') /* Line continued? */
        !           684:          break;                                 /* No, done. */
        !           685:        s -= 3;                                  /* No, back up pointer */
        !           686:        debug(F100,"Got continue char","",0);    /* and continue */
        !           687:     }
        !           688:     untab(s2);                         /* Done, convert tabs to spaces */
        !           689:     free(lp2);                         /* Free temporary storage */
        !           690:     return(0);                         /* Return success */
        !           691: }
        !           692: 
        !           693: /*  P A R S E R  --  Top-level interactive command parser.  */
        !           694:  
        !           695: /*
        !           696:   Call with:
        !           697:     m = 0 for normal behavior: keep parsing and executing commands
        !           698:           until an action command is parsed, then return with a
        !           699:           Kermit start-state as the value of this function.
        !           700:     m = 1 to parse only one command, can also be used to call parser()
        !           701:           recursively.
        !           702:     m = 2 to read but do not execute one command.
        !           703:   In all cases, parser() returns:
        !           704:     0     if no Kermit protocol action required
        !           705:     > 0   with a Kermit protocol start-state.
        !           706:     < 0   upon error.
        !           707: */
        !           708: int
        !           709: parser(m) int m; {
        !           710:     int tfcode, xx, yy, zz;            /* Workers */
        !           711: 
        !           712: #ifndef NOSPL
        !           713:     int inlevel;                       /* Level we were called at */
        !           714: #endif /* NOSPL */
        !           715:     char *cbp;                         /* Command buffer pointer */
        !           716: #ifdef MAC
        !           717:     extern char *lfiles;               /* Fake extern cast */
        !           718: #endif /* MAC */
        !           719: 
        !           720: #ifdef AMIGA
        !           721:     reqres();                  /* restore AmigaDOS requestors */
        !           722: #endif /* AMIGA */
        !           723: 
        !           724:     what = W_COMMAND;          /* Now we're parsing commands. */
        !           725: #ifndef NOSPL
        !           726:     if (cmdlvl == 0)           /* If at top (interactive) level, */
        !           727: #else
        !           728:     if (tlevel < 0)
        !           729: #endif /* NOSPL */
        !           730:       concb((char)escape);     /* put console in cbreak mode. */
        !           731: 
        !           732: #ifndef NOSPL
        !           733:     ifcmd[0] = 0;              /* Command-level related variables */
        !           734:     iftest[0] = 0;             /* initialize variables at top level */
        !           735:     count[0] = 0;              /* of stack... */
        !           736:     inlevel = cmdlvl;          /* Current macro level */
        !           737:     debug(F101,"&parser entry maclvl","",maclvl);
        !           738:     debug(F101,"&parser entry inlevel","",inlevel);
        !           739:     debug(F101,"&parser entry tlevel","",tlevel);
        !           740:     debug(F101,"&parser entry cmdlvl","",cmdlvl);
        !           741:     debug(F101,"&parser entry m","",m);
        !           742: #endif /* NOSPL */
        !           743: 
        !           744: /*
        !           745:   sstate becomes nonzero when a command has been parsed that requires some
        !           746:   action from the protocol module.  Any non-protocol actions, such as local
        !           747:   directory listing or terminal emulation, are invoked directly from below.
        !           748: */
        !           749: #ifdef COMMENT
        !           750:     if (local && pflag)                        /* Just returned from connect? */
        !           751:       printf("\n");
        !           752: #endif /* COMMENT */
        !           753:     sstate = 0;                                /* Start with no start state. */
        !           754: #ifndef NOFRILLS
        !           755:     rmailf = rprintf = 0;              /* MAIL and PRINT modifiers for SEND */
        !           756:     *optbuf = NUL;                     /* MAIL and PRINT options */
        !           757: #endif /* NOFRILLS */
        !           758:     while (sstate == 0) {              /* Parse cmds until action requested */
        !           759:        debug(F100,"top of parse loop","",0);
        !           760: 
        !           761:     /* Take requested action if there was an error in the previous command */
        !           762: 
        !           763: #ifndef MAC
        !           764:        conint(trap,stptrap);           /* In case we were just fg'd */
        !           765:        bgchk();                        /* Check background status */
        !           766: #endif /* MAC */
        !           767: 
        !           768:        debug(F101,"tlevel","",tlevel);
        !           769: #ifndef NOSPL                          /* In case we just reached top level */
        !           770:        debug(F101,"cmdlvl","",cmdlvl);
        !           771:        if (cmdlvl == 0) concb((char)escape);
        !           772: #else
        !           773:        if (tlevel < 0) concb((char)escape);
        !           774: #endif /* NOSPL */
        !           775: 
        !           776: #ifndef NOSPL
        !           777:        if (success == 0) {
        !           778:            if (cmdstk[cmdlvl].src == CMD_TF && terror) {
        !           779:                printf("Command error: take file terminated.\n");
        !           780:                popclvl();
        !           781:                if (cmdlvl == 0) return(0);
        !           782:            }
        !           783:            if (cmdstk[cmdlvl].src == CMD_MD && merror) {
        !           784:                printf("Command error: macro terminated.\n");
        !           785:                popclvl();
        !           786:                if (m && (cmdlvl < inlevel))
        !           787:                  return((int) sstate);
        !           788:            }
        !           789:        }
        !           790: 
        !           791:        nulcmd = (m == 2);
        !           792: #else
        !           793:        if (success == 0 && tlevel > -1 && terror) {
        !           794:            printf("Command error: take file terminated.\n");
        !           795:            popclvl();
        !           796:            cmini(ckxech);              /* Clear the cmd buffer. */
        !           797:            if (tlevel < 0)             /* Just popped out of cmd files? */
        !           798:              return(0);                /* End of init file or whatever. */
        !           799:        }
        !           800: #endif /* NOSPL */
        !           801: 
        !           802: #ifdef MAC
        !           803:        /* Check for TAKE initiated by menu. */
        !           804:        if ((tlevel == -1) && lfiles)
        !           805:            startlfile();
        !           806: #endif /* MAC */
        !           807: 
        !           808:         /* If in TAKE file, check for EOF */
        !           809: #ifndef NOSPL
        !           810: #ifdef MAC
        !           811:        if
        !           812: #else
        !           813:        while
        !           814: #endif /* MAC */
        !           815:          ((cmdstk[cmdlvl].src == CMD_TF)  /* If end of take file */
        !           816:               && (tlevel > -1)
        !           817:               && feof(tfile[tlevel])) {
        !           818:            popclvl();                  /* pop command level */
        !           819:            cmini(ckxech);              /* and clear the cmd buffer. */
        !           820:            if (cmdlvl == 0)            /* Just popped out of all cmd files? */
        !           821:              return(0);                /* End of init file or whatever. */
        !           822:        }
        !           823: #ifdef MAC
        !           824:        miniparser(1);
        !           825:        if (sstate == 'a') {            /* if cmd-. cancel */
        !           826:            debug(F100, "parser: cancel take due to sstate", "", sstate);
        !           827:            sstate = '\0';
        !           828:            dostop();
        !           829:            return(0);                  /* End of init file or whatever. */
        !           830:        }
        !           831: #endif /*  MAC */
        !           832: 
        !           833: #else /* NOSPL */
        !           834:        if ((tlevel > -1) && feof(tfile[tlevel])) { /* If end of take */
        !           835:            popclvl();                  /* Pop up one level. */
        !           836:            cmini(ckxech);              /* and clear the cmd buffer. */
        !           837:            if (tlevel < 0)             /* Just popped out of cmd files? */
        !           838:              return(0);                /* End of init file or whatever. */
        !           839:        }
        !           840: #endif /* NOSPL */
        !           841: 
        !           842: #ifndef NOSPL
        !           843:         if (cmdstk[cmdlvl].src == CMD_MD) { /* Executing a macro? */
        !           844:            debug(F100,"parser macro","",0);
        !           845:            maclvl = cmdstk[cmdlvl].lvl; /* Get current level */
        !           846:            debug(F101,"parser maclvl","",maclvl);
        !           847:            cbp = cmdbuf;               /* Copy next cmd to command buffer. */
        !           848:            *cbp = NUL;
        !           849:            if (*savbuf) {              /* In case then-part of 'if' command */
        !           850:                strcpy(cbp,savbuf);     /* was saved, restore it. */
        !           851:                *savbuf = '\0';
        !           852:            } else {                    /* Else get next cmd from macro def */
        !           853:                if (getncm(cbp,CMDBL) < 0) {
        !           854:                    if (m && (cmdlvl < inlevel))
        !           855:                      return((int) sstate);
        !           856:                    else /* if (!m) */ continue;
        !           857:                }
        !           858:            }
        !           859:            debug(F110,"cmdbuf from macro",cmdbuf,0);
        !           860: 
        !           861:        } else if (cmdstk[cmdlvl].src == CMD_TF)
        !           862: #else
        !           863:          if (tlevel > -1)  
        !           864: #endif /* NOSPL */
        !           865:          {
        !           866: #ifndef NOSPL
        !           867:            if (*savbuf) {              /* In case THEN-part of IF command */
        !           868:                strcpy(cmdbuf,savbuf);  /* was saved, restore it. */
        !           869:                *savbuf = '\0';
        !           870:            } else
        !           871: #endif /* NOSPL */
        !           872: 
        !           873:              /* Get next line from TAKE file */
        !           874: 
        !           875:              if ((tfcode = getnct(cmdbuf,CMDBL)) < 0) {
        !           876:                  if (tfcode < -1) {    /* Error */
        !           877:                      printf("?Error in TAKE command file: %s\n",
        !           878:                             (tfcode == -2) ? "Memory allocation failure" :
        !           879:                             "Line too long or contains NUL characters"
        !           880:                             );
        !           881:                      popclvl();
        !           882:                  }
        !           883:                  continue;             /* -1 means EOF */
        !           884:              }     
        !           885: 
        !           886:         /* If interactive, get next command from user. */
        !           887: 
        !           888:        } else {                        /* User types it in. */
        !           889:            if (pflag) prompt(xxstring);
        !           890:            cmini(ckxech);
        !           891:        }
        !           892: 
        !           893:         /* Now know where next command is coming from. Parse and execute it. */
        !           894: 
        !           895:        repars = 1;                     /* 1 = command needs parsing */
        !           896:        displa = 0;                     /* Assume no file transfer display */
        !           897: 
        !           898:        while (repars) {                /* Parse this cmd until entered. */
        !           899:            debug(F101,"parser top of while loop","",0);
        !           900:            cmres();                    /* Reset buffer pointers. */
        !           901:            xx = cmkey2(cmdtab,ncmd,"Command","",toktab,xxstring);
        !           902:            debug(F101,"top-level cmkey2","",xx);
        !           903:            if (xx == -5) {
        !           904:                yy = chktok(toktab);
        !           905:                debug(F101,"top-level cmkey token","",yy);
        !           906:                ungword();
        !           907:                switch (yy) {
        !           908: #ifndef NOPUSH
        !           909:                  case '!': xx = XXSHE; break; /* Shell escape */
        !           910: #endif /* NOPUSH */
        !           911:                  case '#': xx = XXCOM; break; /* Comment */
        !           912:                  case ';': xx = XXCOM; break; /* Comment */
        !           913: #ifndef NOSPL
        !           914:                  case ':': xx = XXLBL; break; /* GOTO label */
        !           915: #endif /* NOSPL */
        !           916: #ifndef NOPUSH
        !           917:                   case '@': xx = XXSHE; break; /* Shell (DCL) escape */
        !           918: #endif /* NOPUSH */
        !           919:                  default: 
        !           920:                    printf("\n?Invalid - %s\n",cmdbuf);
        !           921:                    xx = -2;
        !           922:                }
        !           923:            }
        !           924: 
        !           925: #ifndef NOSPL
        !           926:             /* Special handling for IF..ELSE */
        !           927: 
        !           928:            if (ifcmd[cmdlvl])          /* Count stmts after IF */
        !           929:              ifcmd[cmdlvl]++;
        !           930:            if (ifcmd[cmdlvl] > 2 && xx != XXELS && xx != XXCOM)
        !           931:              ifcmd[cmdlvl] = 0;
        !           932: 
        !           933:            /* Execute the command and take action based on return code. */
        !           934: 
        !           935:            if (nulcmd) {               /* Ignoring this command? */
        !           936:                xx = XXCOM;             /* Make this command a comment. */
        !           937:            }
        !           938: #endif /* NOSPL */
        !           939: 
        !           940:            zz = docmd(xx);     /* Parse rest of command & execute. */
        !           941:            debug(F101,"docmd returns","",zz);
        !           942: #ifdef MAC
        !           943:            if (tlevel > -1) {
        !           944:                if (sstate == 'a') {    /* if cmd-. cancel */
        !           945:                    debug(F110, "parser: cancel take, sstate:", "a", 0);
        !           946:                    sstate = '\0';
        !           947:                    dostop();
        !           948:                    return(0);          /* End of init file or whatever. */
        !           949:                }
        !           950:            }
        !           951: #endif /* MAC */
        !           952:            switch (zz) {
        !           953:                case -4:                /* EOF (e.g. on redirected stdin) */
        !           954:                    doexit(GOOD_EXIT,xitsta); /* ...exit successfully */
        !           955:                case -1:                /* Reparse needed */
        !           956:                    repars = 1;         /* Just set reparse flag and  */
        !           957:                    continue;
        !           958:                case -6:                /* Invalid command given w/no args */
        !           959:                case -2:                /* Invalid command given w/args */
        !           960: #ifdef COMMENT
        !           961: #ifndef NOSPL
        !           962:                    /* This is going to be really ugly... */
        !           963:                    yy = mlook(mactab,atmbuf,nmac); /* Look in macro table */
        !           964:                    if (yy > -1) {                  /* If it's there */
        !           965:                        if (zz == -2) {             /* insert "do" */
        !           966:                            char *mp;
        !           967:                            mp = malloc((int)strlen(cmdbuf) + 5);
        !           968:                            if (!mp) {
        !           969:                                printf("?malloc error 1\n");
        !           970:                                return(-2);
        !           971:                            }
        !           972:                            sprintf(mp,"do %s ",cmdbuf);
        !           973:                            strcpy(cmdbuf,mp);
        !           974:                            free(mp);
        !           975:                        } else sprintf(cmdbuf,"do %s %c",atmbuf, CR);
        !           976:                        if (ifcmd[cmdlvl] == 2) /* This one doesn't count! */
        !           977:                          ifcmd[cmdlvl]--;
        !           978:                        debug(F111,"stuff cmdbuf",cmdbuf,zz);
        !           979:                        repars = 1;     /* go for reparse */
        !           980:                        continue;
        !           981:                    } else {
        !           982:                        char *p;
        !           983:                        int n;
        !           984:                        p = cmdbuf;
        !           985:                        lp = line;     
        !           986:                        n = LINBUFSIZ;
        !           987:                        if (cmflgs == 0) printf("\n");
        !           988:                        if (xxstring(p,&lp,&n) > -1) 
        !           989:                          printf("?Invalid: %s\n",line);
        !           990:                        else
        !           991:                          printf("?Invalid: %s\n",cmdbuf);
        !           992:                    } /* (fall thru...) */
        !           993: #else
        !           994:                    printf("?Invalid: %s\n",cmdbuf);
        !           995: #endif /* NOSPL */
        !           996: #else
        !           997:                    printf("?Invalid: %s\n",cmdbuf);
        !           998: #endif /* COMMENT */
        !           999: 
        !          1000:                case -9:                /* Bad, error message already done */
        !          1001:                    success = 0;
        !          1002:                    debug(F110,"top-level cmkey failed",cmdbuf,0);
        !          1003:                    if (pflag == 0)     /* if background, terminate */
        !          1004:                      fatal("Kermit command error in background execution");
        !          1005:                    cmini(ckxech);      /* (fall thru) */
        !          1006: 
        !          1007:                case -3:                /* Empty command OK at top level */
        !          1008:                    repars = 0;         /* Don't need to reparse. */
        !          1009:                    continue;           /* Go back and get another command. */
        !          1010: 
        !          1011:                default:                /* Command was successful. */
        !          1012: #ifndef NOSPL
        !          1013:                    debug(F101,"parser preparing to continue","",maclvl);
        !          1014: #endif /* NOSPL */
        !          1015:                    repars = 0;         /* Don't need to reparse. */
        !          1016:                    continue;           /* Go back and get another command. */
        !          1017:                }
        !          1018:        }
        !          1019: #ifndef NOSPL
        !          1020:        debug(F101,"parser breaks out of while loop","",maclvl);
        !          1021:        if (m && (cmdlvl < inlevel))  return((int) sstate);
        !          1022: #endif /* NOSPL */
        !          1023:     }
        !          1024: 
        !          1025: /* Got an action command, return start state. */
        !          1026:  
        !          1027: #ifdef COMMENT
        !          1028:     /* This is done in ckcpro.w instead, no need to do it twice. */
        !          1029:     /* Interrupts off only if remote */
        !          1030:     if (!local) connoi();
        !          1031: #endif /* COMMENT */
        !          1032:     return((int) sstate);
        !          1033: }
        !          1034: 
        !          1035: #ifndef NOSPL
        !          1036: /* OUTPUT command */
        !          1037: 
        !          1038: int                                    /* This could easily become a macro */
        !          1039: #ifdef CK_ANSIC
        !          1040: xxout(char c)
        !          1041: #else
        !          1042: xxout(c) char c; 
        !          1043: #endif /* CK_ANSIC */
        !          1044: /* xxout */ {                          /* Function to output a character. */
        !          1045:     debug(F101,"xxout","",c);
        !          1046:     if (local)                         /* If in local mode */
        !          1047:       return(ttoc(c));                 /* then to the external line */
        !          1048:     else return(conoc(c));             /* otherwise to the console. */
        !          1049: }
        !          1050: 
        !          1051: /* Returns 0 on failure, 1 on success */
        !          1052: 
        !          1053: int
        !          1054: dooutput(s) char *s; {
        !          1055:     int x, y, quote;
        !          1056: 
        !          1057:     if (local) {                       /* Condition external line */
        !          1058:        y = ttvt(speed,flow);
        !          1059:        if (y < 0) return(0);
        !          1060:     }
        !          1061:     quote = 0;                         /* Initialize backslash (\) quote */
        !          1062: 
        !          1063: #ifdef COMMENT
        !          1064: /* This is done automatically in ttopen() now... */
        !          1065: #ifdef TNCODE
        !          1066:     if (network && ttnproto == NP_TELNET) /* If telnet connection, */
        !          1067:       if (!tn_init++) tn_ini();           /* initialize it if necessary */
        !          1068: #endif /* TNCODE */
        !          1069: #endif /* COMMENT */
        !          1070:     while (x = *s++) {                 /* Loop through the string */
        !          1071:        y = 0;                          /* Error code, 0 = no error. */
        !          1072:        if (x == CMDQ) {                /* Look for \b or \B in string */
        !          1073:             quote++;                   /* Got \ */
        !          1074:            continue;                   /* Get next character */
        !          1075:        } else if (quote) {             /* This character is quoted */
        !          1076:            if (quote == 1 && (x == 'b' || x == 'B')) { /* If \b or \B */
        !          1077:                debug(F100,"OUTPUT BREAK","",0);
        !          1078:                ttsndb();               /* send BREAK signal */
        !          1079:                quote = 0;              /* Turn off quote flag */
        !          1080:                continue;               /* and not the b or B */
        !          1081: #ifdef CK_LBRK
        !          1082:            } else if (quote == 1 && (x == 'l' || x == 'L')) { /* \l or \L */
        !          1083:                debug(F100,"OUTPUT Long BREAK","",0);
        !          1084:                ttsndlb();              /* send Long BREAK signal */
        !          1085:                quote = 0;              /* Turn off quote flag */
        !          1086:                continue;               /* and not the l or L */
        !          1087: #endif /* CK_LBRK */
        !          1088:            } else {                    /* if \ not followed by b or B */
        !          1089:                y = xxout(dopar(CMDQ)); /* output the backslash. */
        !          1090:                quote = 0;              /* Turn off quote flag */
        !          1091:            }
        !          1092:        } else quote = 0;               /* Turn off quote flag */
        !          1093:        y = xxout(dopar((char)x));      /* Output this character */
        !          1094:        if (y < 0) {
        !          1095:            printf("output error.\n");
        !          1096:            return(0);
        !          1097:        }
        !          1098:        if (x == '\015') {              /* User typed carriage return */
        !          1099:            if (tnlm                    /* If TERMINAL NEWLINE-MODE is ON */
        !          1100: #ifdef TNCODE
        !          1101:                || (network &&          /* Or we have a network connection */
        !          1102:                    ttnproto == NP_TELNET && /* using TELNET protocol */
        !          1103:                    tn_nlm              /* and TELNET NEWLINE-MODE is ON */
        !          1104:                    )
        !          1105: #endif /* TNCODE */
        !          1106:                )
        !          1107:              xxout(dopar('\012'));     /* Send LF too (CR => CRLF) */
        !          1108:        }
        !          1109:        if (seslog && duplex)
        !          1110:          if (zchout(ZSFILE,(char)x) < 0) seslog = 0;
        !          1111:     }
        !          1112:     return(1);
        !          1113: }
        !          1114: #endif /* NOSPL */
        !          1115: 
        !          1116: 
        !          1117: /* Display version herald and initial prompt */
        !          1118: 
        !          1119: VOID
        !          1120: herald() {
        !          1121:     int x = 0;
        !          1122:     if (bgset > 0 || (bgset != 0 && backgrd != 0)) x = 1;
        !          1123:     debug(F101,"herald","",backgrd);
        !          1124:     if (x == 0)
        !          1125: #ifdef datageneral
        !          1126:       printf("%s,%s\nType ? or HELP for help\n",versio,ckxsys);
        !          1127: #else
        !          1128:       printf("%s,%s\n\rType ? or HELP for help\n",versio,ckxsys);
        !          1129: #endif /* datageneral */
        !          1130: }
        !          1131: #ifndef NOSPL
        !          1132: /*  M L O O K  --  Lookup the macro name in the macro table  */
        !          1133:  
        !          1134: /*
        !          1135:  Call this way:  v = mlook(table,word,n);
        !          1136:  
        !          1137:    table - a 'struct mtab' table.
        !          1138:    word  - the target string to look up in the table.
        !          1139:    n     - the number of elements in the table.
        !          1140:  
        !          1141:  The keyword table must be arranged in ascending alphabetical order, and
        !          1142:  all letters must be lowercase.
        !          1143:  
        !          1144:  Returns the table index, 0 or greater, if the name was found, or:
        !          1145:  
        !          1146:   -3 if nothing to look up (target was null),
        !          1147:   -2 if ambiguous,
        !          1148:   -1 if not found.
        !          1149:  
        !          1150:  A match is successful if the target matches a keyword exactly, or if
        !          1151:  the target is a prefix of exactly one keyword.  It is ambiguous if the
        !          1152:  target matches two or more keywords from the table.
        !          1153: */
        !          1154: int
        !          1155: mlook(table,cmd,n) struct mtab table[]; char *cmd; int n; {
        !          1156:  
        !          1157:     int i, v, cmdlen;
        !          1158:  
        !          1159: /* Lowercase & get length of target, if it's null return code -3. */
        !          1160:  
        !          1161:     if ((((cmdlen = lower(cmd))) == 0) || (n < 1)) return(-3);
        !          1162:  
        !          1163: /* Not null, look it up */
        !          1164:  
        !          1165:     for (i = 0; i < n-1; i++) {
        !          1166:         if (!strcmp(table[i].kwd,cmd) ||
        !          1167:            ((v = !strncmp(table[i].kwd,cmd,cmdlen)) &&
        !          1168:              strncmp(table[i+1].kwd,cmd,cmdlen))) {
        !          1169:                 return(i);
        !          1170:              }
        !          1171:         if (v) return(-2);
        !          1172:     }   
        !          1173:  
        !          1174: /* Last (or only) element */
        !          1175:  
        !          1176:     if (!strncmp(table[n-1].kwd,cmd,cmdlen)) {
        !          1177:         return(n-1);
        !          1178:     } else return(-1);
        !          1179: }
        !          1180: 
        !          1181: /* mxlook is like mlook, but an exact full-length match is required */
        !          1182: 
        !          1183: int
        !          1184: mxlook(table,cmd,n) char *cmd; struct mtab table[]; int n; {
        !          1185:     int i, cmdlen;
        !          1186:     if ((((cmdlen = lower(cmd))) == 0) || (n < 1)) return(-3);
        !          1187:     for (i = 0; i < n; i++)
        !          1188:       if (((int)strlen(table[i].kwd) == cmdlen) &&
        !          1189:          (!strncmp(table[i].kwd,cmd,cmdlen))) return(i);
        !          1190:     return(-1);
        !          1191: }
        !          1192: 
        !          1193: /*
        !          1194:   This routine is for the benefit of those compilers that can't handle
        !          1195:   long string constants or continued lines within them.  Long predefined
        !          1196:   macros like FOR, WHILE, and XIF have their contents broken up into
        !          1197:   arrays of string pointers.  This routine concatenates them back into a
        !          1198:   single string again, and then calls the real addmac() routine to enter
        !          1199:   the definition into the macro table.
        !          1200: */
        !          1201: int
        !          1202: addmmac(nam,s) char *nam, *s[]; {      /* Add a multiline macro definition */
        !          1203:     int i, x, y; char *p;
        !          1204:     x = 0;                             /* Length counter */
        !          1205:     for (i = 0; (y = (int)strlen(s[i])) > 0; i++) { /* Add up total length */
        !          1206:        debug(F111,"addmmac line",s[i],y);      
        !          1207:        x += y;
        !          1208:     }
        !          1209:     debug(F101,"addmmac lines","",i);
        !          1210:     debug(F101,"addmmac loop exit","",y);
        !          1211:     debug(F111,"addmmac length",nam,x);
        !          1212:     if (x < 0) return(-1);
        !          1213: 
        !          1214:     p = malloc(x+1);                   /* Allocate space for all of it. */
        !          1215:     if (!p) {
        !          1216:        printf("?addmmac malloc error: %s\n",nam);
        !          1217:        debug(F110,"addmmac malloc error",nam,0);
        !          1218:        return(-1);
        !          1219:     }
        !          1220:     *p = '\0';                         /* Start off with null string. */
        !          1221:     for (i = 0; *s[i]; i++)            /* Concatenate them all together. */
        !          1222:       strcat(p,s[i]);
        !          1223:     y = (int)strlen(p);                        /* Final precaution. */
        !          1224:     debug(F111,"addmmac constructed string",p,y);
        !          1225:     if (y == x) {
        !          1226:        y = addmac(nam,p);              /* Add result to the macro table. */
        !          1227:     } else {
        !          1228:        debug(F100,"addmmac length mismatch","",0);
        !          1229:        printf("\n!addmmac internal error!\n");
        !          1230:        y = -1;
        !          1231:     }
        !          1232:     free(p);                           /* Free the temporary copy. */
        !          1233:     return(y); 
        !          1234: }
        !          1235: 
        !          1236: /* Here is the real addmac routine. */
        !          1237: 
        !          1238: int
        !          1239: addmac(nam,def) char *nam, *def; {     /* Add a macro to the macro table */
        !          1240:     int i, x, y, z, namlen, deflen;
        !          1241:     char *p, c;
        !          1242: 
        !          1243:     if (!nam) return(-1);
        !          1244:     namlen = (int)strlen(nam);         /* Get argument lengths */
        !          1245:     debug(F111,"addmac nam",nam,namlen);
        !          1246:     if (!def) {                                /* Watch out for null pointer */
        !          1247:        deflen = 0;
        !          1248:        debug(F111,"addmac def","(null pointer)",deflen);
        !          1249:     } else {
        !          1250:        deflen = (int)strlen(def);
        !          1251:        debug(F111,"addmac def",def,deflen);
        !          1252:     }
        !          1253:     if (deflen < 0) return(-1);                /* strlen() failure, fail. */
        !          1254:     if (namlen < 1) return(-1);                /* No name given, fail. */
        !          1255: 
        !          1256:     if (*nam == CMDQ) nam++;           /* Backslash quote? */
        !          1257:     if (*nam == '%') {                 /* Yes, if it's a variable name, */
        !          1258:        delmac(nam);                    /* Delete any old value. */
        !          1259:        if (!(c = *(nam + 1))) return(-1); /* Variable name letter or digit */
        !          1260:        if (deflen < 1) {               /* Null definition */
        !          1261:            p = NULL;                   /* Better not malloc or strcpy! */
        !          1262:        } else {                        /* A substantial definition */
        !          1263:            p = malloc(deflen + 1);     /* Allocate space for it */
        !          1264:            if (!p) {
        !          1265:                printf("?addmac malloc error 2\n");
        !          1266:                return(-1);
        !          1267:            } else strcpy(p,def);       /* Copy definition into new space */
        !          1268:        }
        !          1269: 
        !          1270:        /* Now p points to the definition, or is a null pointer */
        !          1271: 
        !          1272:        if (p)
        !          1273:          debug(F110,"addmac p",p,0);
        !          1274:        else
        !          1275:          debug(F110,"addmac p","(null pointer)",0);
        !          1276: 
        !          1277:        if (c >= '0' && c <= '9') {     /* Digit variable */
        !          1278:            if (maclvl < 0) {           /* Are we calling or in a macro? */
        !          1279:                g_var[c] = p;           /* No, it's a global "top level" one */
        !          1280:                debug(F101,"addmac numeric global maclvl","",maclvl);
        !          1281:            } else {                    /* Yes, it's a macro argument */
        !          1282:                m_arg[maclvl][c - '0'] = p;
        !          1283:                debug(F101,"addmac macro arg maclvl","",maclvl);
        !          1284:            }
        !          1285:        } else {                        /* It's a global variable */
        !          1286:            if (c < 33 || c > GVARS) return(-1);
        !          1287:            if (isupper(c)) c = tolower(c);
        !          1288:            g_var[c] = p;               /* Put pointer in global-var table */
        !          1289:            debug(F100,"addmac global","",0);
        !          1290:        }
        !          1291:        return(0);
        !          1292:     } else if (*nam == '&') {          /* An array reference? */
        !          1293:        char **q;
        !          1294:        if ((y = arraynam(nam,&x,&z)) < 0) /* If syntax is bad */
        !          1295:          return(-1);                   /* return -1. */
        !          1296:        if (chkarray(x,z) < 0)          /* If array not declared or */
        !          1297:          return(-2);                   /* subscript out of range, ret -2 */
        !          1298:        delmac(nam);                    /* Delete any current definition. */
        !          1299:        x -= 96;                        /* Convert name letter to index. */
        !          1300:        if ((q = a_ptr[x]) == NULL)     /* If array not declared, */
        !          1301:          return(-3);                   /* return -3. */
        !          1302:        if (deflen > 0) {
        !          1303:            if ((p = malloc(deflen+1)) == NULL) { /* Allocate space */
        !          1304:                printf("addmac macro error 7: %s\n",nam);
        !          1305:                return(-4);             /* for new def, return -4 on fail. */
        !          1306:            }
        !          1307:            strcpy(p,def);              /* Copy definition into new space. */
        !          1308:        } else p = NULL;
        !          1309:        q[z] = p;                       /* Store pointer to it. */
        !          1310:        return(0);                      /* Done. */
        !          1311:     } else debug(F110,"addmac macro def",nam,0);
        !          1312: 
        !          1313: /* Not a macro argument or a variable, so it's a macro definition */
        !          1314: 
        !          1315:     lower(nam);                                /* Lowercase the name */
        !          1316:     if (mxlook(mactab,nam,nmac) > -1)  /* Look up, requiring exact match */
        !          1317:       delmac(nam);                     /* if it's there, delete it. */
        !          1318:     debug(F111,"addmac table size",nam,nmac);
        !          1319:     for (y = 0;                                /* Find the alphabetical slot */
        !          1320:         y < MAC_MAX && mactab[y].kwd != NULL && strcmp(nam,mactab[y].kwd) > 0;
        !          1321:         y++) ;
        !          1322:     if (y == MAC_MAX) {                        /* No more room. */
        !          1323:        debug(F101,"addmac table overflow","",y);
        !          1324:        return(-1);
        !          1325:     } else debug(F111,"addmac position",nam,y);
        !          1326:     if (mactab[y].kwd != NULL) {       /* Must insert */
        !          1327:        for (i = nmac; i > y; i--) {    /* Move the rest down one slot */
        !          1328:            mactab[i].kwd = mactab[i-1].kwd;
        !          1329:            mactab[i].mval = mactab[i-1].mval;
        !          1330:            mactab[i].flgs = mactab[i-1].flgs;
        !          1331:        }
        !          1332:     }
        !          1333:     p = malloc(namlen + 1);            /* Allocate space for name */
        !          1334:     if (!p) {
        !          1335:        printf("?addmac malloc error 3: %s\n",nam);
        !          1336:        return(-1);
        !          1337:     }
        !          1338:     strcpy(p,nam);                     /* Copy name into new space */
        !          1339:     mactab[y].kwd = p;                 /* Add pointer to table */
        !          1340: 
        !          1341:     if (deflen > 0) {                  /* Same deal for definition */
        !          1342:        p = malloc(deflen + 1);         /* but watch out for null pointer */
        !          1343:        if (p == NULL) {
        !          1344:            printf("?addmac malloc error 5: %s\n", nam);
        !          1345:            free(mactab[y].kwd);
        !          1346:            mactab[y].kwd = NULL;
        !          1347:            return(-1);
        !          1348:        } else strcpy(p,def);           /* Copy the definition */
        !          1349:     } else p = NULL;
        !          1350:     mactab[y].mval = p;
        !          1351:     mactab[y].flgs = 0;
        !          1352:     nmac++;                            /* Count this macro */
        !          1353:     return(y);
        !          1354: }
        !          1355: 
        !          1356: int
        !          1357: delmac(nam) char *nam; {               /* Delete the named macro */
        !          1358:     int i, x, z;
        !          1359:     char *p, c;
        !          1360: 
        !          1361:     if (!nam) return(0);               /* Watch out for null pointer */
        !          1362:     debug(F110,"delmac nam",nam,0);
        !          1363:     if (*nam == CMDQ) nam++;
        !          1364:     if (*nam == '%') {                 /* If it's a variable name */
        !          1365:        if (!(c = *(nam+1))) return(0); /* Get variable name letter or digit */
        !          1366:        p = (char *)0;                  /* Initialize value pointer */
        !          1367:        if (maclvl > -1 && c >= '0' && c <= '9') { /* Digit? */
        !          1368:            p = m_arg[maclvl][c - '0']; /* Get pointer from macro-arg table */
        !          1369:            m_arg[maclvl][c - '0'] = NULL; /* Zero the table pointer */
        !          1370:        } else {                        /* It's a global variable */
        !          1371:            if (c < 33 || c > GVARS) return(0);
        !          1372:            p = g_var[c];               /* Get pointer from global-var table */
        !          1373:            g_var[c] = NULL;            /* Zero the table entry */
        !          1374:        }
        !          1375:        if (p) {
        !          1376:            debug(F110,"delmac def",p,0);
        !          1377:            free(p);                    /* Free the storage */
        !          1378:        } else debug(F110,"delmac def","(null pointer)",0);
        !          1379:        return(0);
        !          1380:     }
        !          1381:            
        !          1382:     if (*nam == '&') {                 /* An array reference? */
        !          1383:        char **q;
        !          1384:        if (arraynam(nam,&x,&z) < 0)    /* If syntax is bad */
        !          1385:          return(-1);                   /* return -1. */
        !          1386:        x -= 96;                        /* Convert name to number. */
        !          1387:        if ((q = a_ptr[x]) == NULL)     /* If array not declared, */
        !          1388:          return(-2);                   /* return -2. */
        !          1389:        if (z > a_dim[x])               /* If subscript out of range, */
        !          1390:          return(-3);                   /* return -3. */
        !          1391:        if (q[z]) {                     /* If there is an old value, */
        !          1392:            debug(F110,"delman def",q[z],0);
        !          1393:            free(q[z]);                 /* delete it. */
        !          1394:            q[z] = NULL;
        !          1395:        } else debug(F110,"delmac def","(null pointer)",0);
        !          1396:     }
        !          1397: 
        !          1398:    /* Not a variable or an array, so it must be a macro. */
        !          1399: 
        !          1400:     if ((x = mlook(mactab,nam,nmac)) < 0) { /* Look it up */
        !          1401:        debug(F111,"delmac mlook",nam,x);
        !          1402:        return(x);
        !          1403:     }
        !          1404:     if (mactab[x].kwd)                 /* Free the storage for the name */
        !          1405:       free(mactab[x].kwd);
        !          1406:     if (mactab[x].mval)                        /* and for the definition */
        !          1407:       free(mactab[x].mval);
        !          1408: 
        !          1409:     for (i = x; i < nmac; i++) {       /* Now move up the others. */
        !          1410:        mactab[i].kwd = mactab[i+1].kwd;
        !          1411:        mactab[i].mval = mactab[i+1].mval;
        !          1412:        mactab[i].flgs = mactab[i+1].flgs;
        !          1413:     }
        !          1414:     nmac--;                            /* One less macro */
        !          1415:     mactab[nmac].kwd = NULL;           /* Delete last item from table */
        !          1416:     mactab[nmac].mval = NULL;
        !          1417:     mactab[nmac].flgs = 0;
        !          1418:     return(0);
        !          1419: }
        !          1420: 
        !          1421: VOID
        !          1422: initmac() {                            /* Init macro & variable tables */
        !          1423:     int i, j;
        !          1424: 
        !          1425:     nmac = 0;                          /* No macros */
        !          1426:     for (i = 0; i < MAC_MAX; i++) {    /* Initialize the macro table */
        !          1427:        mactab[i].kwd = NULL;
        !          1428:        mactab[i].mval = NULL;
        !          1429:        mactab[i].flgs = 0;
        !          1430:     }
        !          1431:     for (i = 0; i < MACLEVEL; i++) {   /* Init the macro argument tables */
        !          1432:        mrval[i] = NULL;
        !          1433:        for (j = 0; j < 10; j++) {
        !          1434:            m_arg[i][j] = NULL;
        !          1435:        }
        !          1436:     }
        !          1437:     for (i = 0; i < GVARS; i++) {      /* And the global variables table */
        !          1438:        g_var[i] = NULL;
        !          1439:     }
        !          1440:     for (i = 0; i < 26; i++) {         /* And the table of arrays */
        !          1441:        a_ptr[i] = (char **) NULL;      /* Null pointer for each */
        !          1442:        a_dim[i] = 0;                   /* and a dimension of zero */
        !          1443:     }
        !          1444: }
        !          1445: 
        !          1446: int
        !          1447: popclvl() {                            /* Pop command level, return cmdlvl */
        !          1448:     if (cmdlvl < 1) {                  /* If we're already at top level */
        !          1449:        cmdlvl = 0;                     /* just make sure all the */
        !          1450:        tlevel = -1;                    /* stack pointers are set right */
        !          1451:        maclvl = -1;                    /* and return */
        !          1452:     } else if (cmdstk[cmdlvl].src == CMD_TF) { /* Reading from TAKE file? */
        !          1453:        if (tlevel > -1) {              /* Yes, */
        !          1454:            if (tfnam[tlevel]) {
        !          1455:                free(tfnam[tlevel]);
        !          1456:                tfnam[tlevel] = NULL;
        !          1457:            }
        !          1458:            fclose(tfile[tlevel--]);    /* close it and pop take level */
        !          1459:            cmdlvl--;                   /* pop command level */
        !          1460:        } else tlevel = -1;
        !          1461:     } else if (cmdstk[cmdlvl].src == CMD_MD) { /* In a macro? */
        !          1462:        if (maclvl > -1) {              /* Yes, */
        !          1463:            debug(F111,"popclvl before",macx[maclvl],maclvl);
        !          1464:            macp[maclvl] = "";          /* set macro pointer to null string */
        !          1465:            *cmdbuf = '\0';             /* clear the command buffer */
        !          1466:            if (mrval[maclvl+1]) {      /* Free any deeper return values. */
        !          1467:                free(mrval[maclvl+1]);
        !          1468:                mrval[maclvl+1] = NULL;
        !          1469:            }
        !          1470:            maclvl--;                   /* pop macro level */
        !          1471:            cmdlvl--;                   /* and command level */
        !          1472:            debug(F111,"popclvl after ",
        !          1473:                  macx[maclvl] ? macx[maclvl] : "",maclvl);
        !          1474:        } else maclvl = -1;
        !          1475:     }
        !          1476: #ifndef MAC
        !          1477:     if (cmdlvl < 1) {                  /* If back at top level */
        !          1478:        conint(trap,stptrap);           /* Fix interrupts */
        !          1479:        bgchk();                        /* Check background status */
        !          1480:        concb((char)escape);            /* Go into cbreak mode */
        !          1481:     }
        !          1482: #endif /* MAC */
        !          1483:     return(cmdlvl < 1 ? 0 : cmdlvl);   /* Return command level */
        !          1484: }
        !          1485: #else /* No script programming language */
        !          1486: int popclvl() {                                /* Just close current take file. */
        !          1487:     if (tlevel > -1) {                 /* if any... */
        !          1488:        if (tfnam[tlevel]) {
        !          1489:            free(tfnam[tlevel]);
        !          1490:            tfnam[tlevel] = NULL;
        !          1491:        }
        !          1492:        fclose(tfile[tlevel--]);
        !          1493:     }
        !          1494:     if (tlevel == -1) {                        /* And if back at top level */
        !          1495:        conint(trap,stptrap);           /* check and set interrupts */
        !          1496:         bgchk();                       /* and background status */
        !          1497:         concb((char)escape);           /* and go back into cbreak mode. */
        !          1498:     }
        !          1499:     return(tlevel + 1);
        !          1500: }
        !          1501: #endif /* NOSPL */
        !          1502: 
        !          1503: /* STOP - get back to C-Kermit prompt, no matter where from. */
        !          1504: 
        !          1505: int
        !          1506: dostop() {
        !          1507:     while ( popclvl() )  ;     /* Pop all macros & take files */
        !          1508: #ifndef NOSPL
        !          1509:     while (cmpop() > -1) ;     /* And all recursive cmd pkg invocations */
        !          1510: #endif /* NOSPL */
        !          1511:     cmini(ckxech);             /* Clear the command buffer. */
        !          1512:     return(0);
        !          1513: }
        !          1514: 
        !          1515: 
        !          1516: /* Close the given log */
        !          1517: 
        !          1518: int
        !          1519: doclslog(x) int x; {
        !          1520:     int y;
        !          1521:     switch (x) {
        !          1522: #ifdef DEBUG
        !          1523:        case LOGD:
        !          1524:            if (deblog == 0) {
        !          1525:                printf("?Debugging log wasn't open\n");
        !          1526:                return(0);
        !          1527:            }
        !          1528:            *debfil = '\0';
        !          1529:            deblog = 0;
        !          1530:            return(zclose(ZDFILE));
        !          1531: #endif /* DEBUG */
        !          1532: 
        !          1533:        case LOGP:
        !          1534:            if (pktlog == 0) {
        !          1535:                printf("?Packet log wasn't open\n");
        !          1536:                return(0);
        !          1537:            }
        !          1538:            *pktfil = '\0';
        !          1539:            pktlog = 0;
        !          1540:            return(zclose(ZPFILE));
        !          1541:  
        !          1542:        case LOGS:
        !          1543:            if (seslog == 0) {
        !          1544:                printf("?Session log wasn't open\n");
        !          1545:                return(0);
        !          1546:            }
        !          1547:            *sesfil = '\0';
        !          1548:            seslog = 0;
        !          1549:            return(zclose(ZSFILE));
        !          1550:  
        !          1551: #ifdef TLOG
        !          1552:        case LOGT:
        !          1553:            if (tralog == 0) {
        !          1554:                printf("?Transaction log wasn't open\n");
        !          1555:                return(0);
        !          1556:            }
        !          1557:            *trafil = '\0';
        !          1558:            tralog = 0;
        !          1559:            return(zclose(ZTFILE));
        !          1560: #endif /* TLOG */
        !          1561:  
        !          1562: #ifndef NOSPL
        !          1563:           case LOGW:                   /* WRITE file */
        !          1564:          case LOGR:                    /* READ file */
        !          1565:            y = (x == LOGR) ? ZRFILE : ZWFILE;
        !          1566:            if (chkfn(y) < 1)           /* If no file to close */
        !          1567:              return(1);                /* succeed silently. */
        !          1568:            return(zclose(y));          /* Otherwise, close the file. */
        !          1569: #endif /* NOSPL */
        !          1570: 
        !          1571:        default:
        !          1572:            printf("\n?Unexpected log designator - %ld\n", x);
        !          1573:            return(0);
        !          1574:        }
        !          1575: }
        !          1576: 
        !          1577: #ifndef NOSERVER
        !          1578: #ifndef NOFRILLS
        !          1579: static char *nm[] = { "disabled", "enabled" };
        !          1580: #endif /* NOFRILLS */
        !          1581: #endif /* NOSERVER */
        !          1582: 
        !          1583: static int slc = 0;                    /* Screen line count */
        !          1584: 
        !          1585: #ifndef NOSHOW
        !          1586: #ifndef NOFRILLS
        !          1587: #define xxdiff(v,sys) strncmp(v,sys,strlen(sys))
        !          1588: VOID
        !          1589: shover() {
        !          1590:     printf("\nVersions:\n %s\n Numeric: %ld",versio,vernum);
        !          1591:     if (verwho) printf("-%d",verwho);
        !          1592:     printf(xxdiff(ckxv,ckxsys) ? "\n %s for%s\n" : "\n %s\n",ckxv,ckxsys);
        !          1593:     printf(xxdiff(ckzv,ckzsys) ? " %s for%s\n" : " %s\n",ckzv,ckzsys);
        !          1594:     printf(" %s\n",protv);
        !          1595:     printf(" %s\n",fnsv);
        !          1596:     printf(" %s\n %s\n",cmdv,userv);
        !          1597: #ifndef NOCSETS
        !          1598:     printf(" %s\n",xlav);
        !          1599: #endif /* NOCSETS */
        !          1600: #ifndef MAC
        !          1601:     printf(" %s\n",connv);
        !          1602: #endif /* MAC */
        !          1603: #ifndef NODIAL
        !          1604:     printf(" %s\n",dialv);
        !          1605: #endif /* NODIAL */
        !          1606: #ifndef NOSCRIPT
        !          1607:     printf(" %s\n",loginv);
        !          1608: #endif /* NOSCRIPT */
        !          1609: #ifdef NETCONN
        !          1610:     printf(" %s\n",cknetv);
        !          1611: #endif /* NETCONN */
        !          1612:     printf("\n");
        !          1613: }
        !          1614: 
        !          1615: VOID
        !          1616: shofea() {
        !          1617: #ifdef OS2
        !          1618: #ifdef M_I286
        !          1619:     printf("\nOS/2 16-bit.\n");
        !          1620: #else
        !          1621:     printf("\nOS/2 32-bit.\n");
        !          1622: #endif /* M_I286 */
        !          1623: #endif /* OS2 */
        !          1624:     printf("\nSpecial features:\n");
        !          1625: #ifdef NETCONN
        !          1626:     printf(" Network support (type SHOW NET for further info)\n");
        !          1627: #endif /* NETCONN */
        !          1628: #ifndef NOCSETS
        !          1629:     printf(" Latin-1 (West European) character-set translation\n");
        !          1630: #ifdef LATIN2
        !          1631:     printf(" Latin-2 (East European) character-set translation\n");
        !          1632: #endif /* LATIN2 */
        !          1633: #ifdef CYRILLIC
        !          1634:     printf(" Cyrillic (Russian, Ukrainian, etc) character-set translation\n");
        !          1635: #endif /* CYRILLIC */
        !          1636: #ifdef KANJI
        !          1637:     printf(" Kanji (Japanese) character-set translation\n");
        !          1638: #endif /* KANJI */
        !          1639: #endif /* NOCSETS */
        !          1640: 
        !          1641: #ifdef CK_CURSES
        !          1642:     printf(" Fullscreen file transfer display\n");
        !          1643: #endif /* CK_CURSES */
        !          1644: 
        !          1645:     printf("\nFeatures not included:\n");
        !          1646: #ifndef CK_CURSES
        !          1647: #ifndef MAC
        !          1648:     printf(" No fullscreen file transfer display\n");
        !          1649: #endif /* MAC */
        !          1650: #endif /* CK_CURSES */
        !          1651: #ifdef NOSERVER
        !          1652:     printf(" No server mode\n");
        !          1653: #endif /* NOSERVER */
        !          1654: #ifdef NODEBUG
        !          1655:     printf(" No debugging\n");
        !          1656: #endif /* NODEBUG */
        !          1657: #ifdef NOTLOG
        !          1658:     printf(" No transaction log\n");
        !          1659: #endif /* NOTLOG */
        !          1660: #ifdef NOHELP
        !          1661:     printf(" No built-in help\n");
        !          1662: #endif /* NOHELP */
        !          1663: #ifndef NETCONN
        !          1664:     printf(" No network support\n");
        !          1665: #endif /* NETCONN */
        !          1666: #ifdef NOMSEND
        !          1667:     printf(" No MSEND command\n");
        !          1668: #endif /* NOMSEND */
        !          1669: #ifdef NODIAL
        !          1670:     printf(" No DIAL command\n");
        !          1671: #else
        !          1672: #ifdef MINIDIAL
        !          1673:     printf(" DIAL command for modems other than Hayes, CCITT, and Unknown\n");
        !          1674: #endif /* MINIDIAL */
        !          1675: #endif /* NODIAL */
        !          1676: #ifdef NOXMIT
        !          1677:     printf(" No TRANSMIT command\n");
        !          1678: #endif /* NOXMIT */
        !          1679: #ifdef NOSCRIPT
        !          1680:     printf(" No SCRIPT command\n");
        !          1681: #endif /* NOSCRIPT */
        !          1682: #ifdef NOSPL
        !          1683:     printf(" No script programming features\n");
        !          1684: #endif /* NOSPL */
        !          1685: #ifdef NOCSETS
        !          1686:     printf(" No character-set translation\n");
        !          1687: #else
        !          1688: #ifndef LATIN2
        !          1689:     printf(" No Latin-2 character-set translation\n");
        !          1690: #endif /* LATIN2 */
        !          1691: #ifdef NOCYRIL
        !          1692:     printf(" No Cyrillic character-set translation\n");
        !          1693: #endif /* NOCYRIL */
        !          1694: #ifndef KANJI
        !          1695:     printf(" No Kanji character-set translation\n");
        !          1696: #endif /* KANJI */
        !          1697: #endif /* NOCSETS */
        !          1698: #ifdef NOCMDL
        !          1699:     printf(" No command-line arguments\n");
        !          1700: #endif /* NOCMDL */
        !          1701: #ifdef NOFRILLS
        !          1702:     printf(" No frills\n");
        !          1703: #endif /* NOFRILLS */
        !          1704: #ifdef NOPUSH
        !          1705:     printf(" No escape to system\n");
        !          1706: #endif /* NOPUSH */
        !          1707: #ifdef NOJC
        !          1708: #ifdef UNIX
        !          1709:     printf(" No UNIX job control\n");
        !          1710: #endif /* UNIX */
        !          1711: #endif /* NOJC */
        !          1712: #ifdef NOSETKEY
        !          1713:     printf(" No SET KEY command\n");
        !          1714: #endif /* NOSETKEY */
        !          1715: #ifdef NOESCSEQ
        !          1716:     printf(" No ANSI escape sequence recognition\n");
        !          1717: #endif /* NOESCSEQ */
        !          1718: #ifndef PARSENSE
        !          1719:     printf(" No automatic parity detection\n");
        !          1720: #endif /* PARSENSE */
        !          1721: /*
        !          1722:   Print all of Kermit's compile-time options, as well as C preprocessor
        !          1723:   predefined symbols that might affect us...
        !          1724: */
        !          1725:     printf("\nCompiler options:\n");
        !          1726: #ifdef DEBUG
        !          1727: #ifdef IFDEBUG
        !          1728:     prtopt(" IFDEBUG");
        !          1729: #else
        !          1730:     prtopt(" DEBUG");
        !          1731: #endif /* IFDEBUG */
        !          1732: #endif /* DEBUG */
        !          1733: #ifdef TLOG
        !          1734:     prtopt(" TLOG");
        !          1735: #endif /* TLOG */
        !          1736: #ifdef NODIAL
        !          1737:     prtopt(" NODIAL");
        !          1738: #endif /* NODIAL */
        !          1739: #ifdef MINIDIAL
        !          1740:     prtopt(" MINIDIAL");
        !          1741: #endif /* MINIDIAL */
        !          1742: #ifdef DYNAMIC
        !          1743:     prtopt(" DYNAMIC");
        !          1744: #endif /* IFDEBUG */
        !          1745: #ifndef NOSPL
        !          1746:     sprintf(line," CMDDEP=%d",CMDDEP);
        !          1747:     prtopt(line);
        !          1748: #endif /* NOSPL */
        !          1749: #ifdef UNIX
        !          1750:     prtopt(" UNIX");
        !          1751: #endif /* UNIX */
        !          1752: #ifdef VMS
        !          1753:     prtopt(" VMS");
        !          1754: #endif /* VMS */
        !          1755: #ifdef vms
        !          1756:     prtopt(" vms");
        !          1757: #endif /* vms */
        !          1758: #ifdef VMSSHARE
        !          1759:     prtopt(" VMSSHARE");
        !          1760: #endif /* VMSSHARE */
        !          1761: #ifdef datageneral
        !          1762:     prtopt(" datageneral");
        !          1763: #endif /* datageneral */
        !          1764: #ifdef apollo
        !          1765:     prtopt(" apollo");
        !          1766: #endif /* apollo */
        !          1767: #ifdef aegis
        !          1768:     prtopt(" aegis");
        !          1769: #endif /* aegis */
        !          1770: #ifdef A986
        !          1771:     prtopt(" A986");
        !          1772: #endif /* A986 */
        !          1773: #ifdef AMIGA
        !          1774:     prtopt(" AMIGA");
        !          1775: #endif /* AMIGA */
        !          1776: #ifdef CONVEX9
        !          1777:     prtopt(" CONVEX9");
        !          1778: #endif /* CONVEX9 */
        !          1779: #ifdef MAC
        !          1780:     prtopt(" MAC");
        !          1781: #endif /* MAC */
        !          1782: #ifdef AUX
        !          1783:     prtopt(" AUX");
        !          1784: #endif /* AUX */
        !          1785: #ifdef OS2
        !          1786:     prtopt(" OS2");
        !          1787: #endif /* OS2 */
        !          1788: #ifdef OS9
        !          1789:     prtopt(" OS9");
        !          1790: #endif /* OS9 */
        !          1791: #ifdef MSDOS
        !          1792:     prtopt(" MSDOS");
        !          1793: #endif /* MSDOS */
        !          1794: #ifdef DIRENT
        !          1795:     prtopt(" DIRENT");
        !          1796: #endif /* DIRENT */
        !          1797: #ifdef SDIRENT
        !          1798:     prtopt(" SDIRENT");
        !          1799: #endif /* SDIRENT */
        !          1800: #ifdef NDIR
        !          1801:     prtopt(" NDIR");
        !          1802: #endif /* NDIR */
        !          1803: #ifdef XNDIR
        !          1804:     prtopt(" XNDIR");
        !          1805: #endif /* XNDIR */
        !          1806: #ifdef MATCHDOT
        !          1807:     prtopt(" MATCHDOT");
        !          1808: #endif /* MATCHDOT */
        !          1809: #ifdef SAVEDUID
        !          1810:     prtopt(" SAVEDUID");
        !          1811: #endif /* SAVEDUID */
        !          1812: #ifdef NOCCTRAP
        !          1813:     prtopt(" NOCCTRAP");
        !          1814: #endif /* NOCCTRAP */
        !          1815: #ifdef SUNX25
        !          1816:     prtopt(" SUNX25");
        !          1817: #endif /* SUNX25 */
        !          1818: #ifdef DECNET
        !          1819:     prtopt(" DECNET");
        !          1820: #endif /* DECNET */
        !          1821: #ifdef ATT7300
        !          1822:     prtopt(" ATT7300");
        !          1823: #endif /* ATT7300 */
        !          1824: #ifdef ATT6300
        !          1825:     prtopt(" ATT6300");
        !          1826: #endif /* ATT6300 */
        !          1827: #ifdef HDBUUCP
        !          1828:     prtopt(" HDBUUCP");
        !          1829: #endif /* HDBUUCP */
        !          1830: #ifdef NOUUCP
        !          1831:     prtopt(" NOUUCP");
        !          1832: #endif /* NOUUCP */
        !          1833: #ifdef LONGFN
        !          1834:     prtopt(" LONGFN");
        !          1835: #endif /* LONGFN */
        !          1836: #ifdef RDCHK
        !          1837:     prtopt(" RDCHK");
        !          1838: #endif /* RDCHK */
        !          1839: #ifdef NAP
        !          1840:     prtopt(" NAP");
        !          1841: #endif /* NAP */
        !          1842: #ifdef NAPHACK
        !          1843:     prtopt(" NAPHACK");
        !          1844: #endif /* NAPHACK */
        !          1845: #ifdef NOIEXTEN
        !          1846:     prtopt(" NOIEXTEN");
        !          1847: #endif /* NOIEXTEN */
        !          1848: #ifdef EXCELAN
        !          1849:     prtopt(" EXCELAN");
        !          1850: #endif /* EXCELAN */
        !          1851: #ifdef PARAMH
        !          1852:     prtopt(" PARAMH");
        !          1853: #endif /* PARAMH */
        !          1854: #ifdef INTERLAN
        !          1855:     prtopt(" INTERLAN");
        !          1856: #endif /* INTERLAN */
        !          1857: #ifdef NOFILEH
        !          1858:     prtopt(" NOFILEH");
        !          1859: #endif /* NOFILEH */
        !          1860: #ifdef NOSYSIOCTLH
        !          1861:     prtopt(" NOSYSIOCTLH");
        !          1862: #endif /* NOSYSIOCTLH */
        !          1863: #ifdef DCLPOPEN
        !          1864:     prtopt(" DCLPOPEN");
        !          1865: #endif /* DCLPOPEN */
        !          1866: #ifdef NOSETBUF
        !          1867:     prtopt(" NOSETBUF");
        !          1868: #endif /* NOSETBUF */
        !          1869: #ifdef NOFDZERO
        !          1870:     prtopt(" NOFDZERO");
        !          1871: #endif /* NOFDZERO */
        !          1872: #ifdef NOPOPEN
        !          1873:     prtopt(" NOPOPEN");
        !          1874: #endif /* NOPOPEN */
        !          1875: #ifdef NOPARTIAL
        !          1876:     prtopt(" NOPARTIAL");
        !          1877: #endif /* NOPARTIAL */
        !          1878: #ifdef NOSETREU
        !          1879:     prtopt(" NOSETREU");
        !          1880: #endif /* NOSETREU */
        !          1881: #ifdef _POSIX_SOURCE
        !          1882:     prtopt(" _POSIX_SOURCE");
        !          1883: #endif /* _POSIX_SOURCE */
        !          1884: #ifdef LCKDIR
        !          1885:     prtopt(" LCKDIR");
        !          1886: #endif /* LCKDIR */
        !          1887: #ifdef ACUCNTRL
        !          1888:     prtopt(" ACUCNTRL");
        !          1889: #endif /* ACUCNTRL */
        !          1890: #ifdef BSD4
        !          1891:     prtopt(" BSD4");
        !          1892: #endif /* BSD4 */
        !          1893: #ifdef BSD44
        !          1894:     prtopt(" BSD44");
        !          1895: #endif /* BSD44 */
        !          1896: #ifdef BSD41
        !          1897:     prtopt(" BSD41");
        !          1898: #endif /* BSD41 */
        !          1899: #ifdef BSD43
        !          1900:     prtopt(" BSD43");
        !          1901: #endif /* BSD43 */
        !          1902: #ifdef BSD29
        !          1903:     prtopt(" BSD29");
        !          1904: #endif /* BSD29 */
        !          1905: #ifdef V7
        !          1906:     prtopt(" V7");
        !          1907: #endif /* V7 */
        !          1908: #ifdef AIX370
        !          1909:     prtopt(" AIX370");
        !          1910: #endif /* AIX370 */
        !          1911: #ifdef RTAIX
        !          1912:     prtopt(" RTAIX");
        !          1913: #endif /* RTAIX */
        !          1914: #ifdef HPUX
        !          1915:     prtopt(" HPUX");
        !          1916: #endif /* HPUX */
        !          1917: #ifdef HPUXPRE65
        !          1918:     prtopt(" HPUXPRE65");
        !          1919: #endif /* HPUXPRE65 */
        !          1920: #ifdef DGUX
        !          1921:     prtopt(" DGUX");
        !          1922: #endif /* DGUX */
        !          1923: #ifdef DGUX430
        !          1924:     prtopt(" DGUX430");
        !          1925: #endif /* DGUX430 */
        !          1926: #ifdef DGUX540
        !          1927:     prtopt(" DGUX540");
        !          1928: #endif /* DGUX540 */
        !          1929: #ifdef sony_news
        !          1930:     prtopt(" sony_news");
        !          1931: #endif /* sony_news */
        !          1932: #ifdef CIE
        !          1933:     prtopt(" CIE");
        !          1934: #endif /* CIE */
        !          1935: #ifdef XENIX
        !          1936:     prtopt(" XENIX");
        !          1937: #endif /* XENIX */
        !          1938: #ifdef SCO_XENIX
        !          1939:     prtopt(" SCO_XENIX");
        !          1940: #endif /* SCO_XENIX */
        !          1941: #ifdef ISIII
        !          1942:     prtopt(" ISIII");
        !          1943: #endif /* ISIII */
        !          1944: #ifdef I386IX
        !          1945:     prtopt(" I386IX");
        !          1946: #endif /* I386IX */
        !          1947: #ifdef RTU
        !          1948:     prtopt(" RTU");
        !          1949: #endif /* RTU */
        !          1950: #ifdef PROVX1
        !          1951:     prtopt(" PROVX1");
        !          1952: #endif /* PROVX1 */
        !          1953: #ifdef TOWER1
        !          1954:     prtopt(" TOWER1");
        !          1955: #endif /* TOWER1 */
        !          1956: #ifdef UTEK
        !          1957:     prtopt(" UTEK");
        !          1958: #endif /* UTEK */
        !          1959: #ifdef ZILOG
        !          1960:     prtopt(" ZILOG");
        !          1961: #endif /* ZILOG */
        !          1962: #ifdef TRS16
        !          1963:     prtopt(" TRS16");
        !          1964: #endif /* TRS16 */
        !          1965: #ifdef MINIX
        !          1966:     prtopt(" MINIX");
        !          1967: #endif /* MINIX */
        !          1968: #ifdef C70
        !          1969:     prtopt(" C70");
        !          1970: #endif /* C70 */
        !          1971: #ifdef AIXPS2
        !          1972:     prtopt(" AIXPS2");
        !          1973: #endif /* AIXPS2 */
        !          1974: #ifdef AIXRS
        !          1975:     prtopt(" AIXRS");
        !          1976: #endif /* AIXRS */
        !          1977: #ifdef UTSV
        !          1978:     prtopt(" UTSV");
        !          1979: #endif /* UTSV */
        !          1980: #ifdef ATTSV
        !          1981:     prtopt(" ATTSV");
        !          1982: #endif /* ATTSV */
        !          1983: #ifdef SVR3
        !          1984:     prtopt(" SVR3");
        !          1985: #endif /* SVR3 */
        !          1986: #ifdef SVR4
        !          1987:     prtopt(" SVR4");
        !          1988: #endif /* SVR4 */
        !          1989: #ifdef DELL_SVR4
        !          1990:     prtopt(" DELL_SVR4");
        !          1991: #endif /* DELL_SVR4 */
        !          1992: #ifdef ICL_SVR4
        !          1993:     prtopt(" ICL_SVR4");
        !          1994: #endif /* ICL_SVR4 */
        !          1995: #ifdef OSF
        !          1996:     prtopt(" OSF");
        !          1997: #endif /* OSF */
        !          1998: #ifdef PTX
        !          1999:     prtopt(" PTX");
        !          2000: #endif /* PTX */
        !          2001: #ifdef POSIX
        !          2002:     prtopt(" POSIX");
        !          2003: #endif /* POSIX */
        !          2004: #ifdef SOLARIS
        !          2005:     prtopt(" SOLARIS");
        !          2006: #endif /* SOLARIS */
        !          2007: #ifdef SUNOS4
        !          2008:     prtopt(" SUNOS4");
        !          2009: #endif /* SUNOS4 */
        !          2010: #ifdef SUN4S5
        !          2011:     prtopt(" SUN4S5");
        !          2012: #endif /* SUN4S5 */
        !          2013: #ifdef ENCORE
        !          2014:     prtopt(" ENCORE");
        !          2015: #endif /* ENCORE */
        !          2016: #ifdef ultrix
        !          2017:     prtopt(" ultrix");
        !          2018: #endif
        !          2019: #ifdef sxaE50
        !          2020:     prtopt(" sxaE50");
        !          2021: #endif
        !          2022: #ifdef mips
        !          2023:     prtopt(" mips");
        !          2024: #endif
        !          2025: #ifdef MIPS
        !          2026:     prtopt(" MIPS");
        !          2027: #endif
        !          2028: #ifdef vax
        !          2029:     prtopt(" vax");
        !          2030: #endif
        !          2031: #ifdef VAX
        !          2032:     prtopt(" VAX");
        !          2033: #endif
        !          2034: #ifdef sun
        !          2035:     prtopt(" sun");
        !          2036: #endif
        !          2037: #ifdef sun3
        !          2038:     prtopt(" sun3");
        !          2039: #endif
        !          2040: #ifdef sun386
        !          2041:     prtopt(" sun386");
        !          2042: #endif
        !          2043: #ifdef _SUN
        !          2044:     prtopt(" _SUN");
        !          2045: #endif
        !          2046: #ifdef sun4
        !          2047:     prtopt(" sun4");
        !          2048: #endif
        !          2049: #ifdef sparc
        !          2050:     prtopt(" sparc");
        !          2051: #endif
        !          2052: #ifdef NEXT
        !          2053:     prtopt(" NEXT");
        !          2054: #endif
        !          2055: #ifdef NeXT
        !          2056:     prtopt(" NeXT");
        !          2057: #endif
        !          2058: #ifdef sgi
        !          2059:     prtopt(" sgi");
        !          2060: #endif
        !          2061: #ifdef M_SYS5
        !          2062:     prtopt(" M_SYS5");
        !          2063: #endif
        !          2064: #ifdef __SYSTEM_FIVE
        !          2065:     prtopt(" __SYSTEM_FIVE");
        !          2066: #endif
        !          2067: #ifdef sysV
        !          2068:     prtopt(" sysV");
        !          2069: #endif
        !          2070: #ifdef M_XENIX                         /* SCO Xenix V and UNIX/386 */
        !          2071:     prtopt(" M_XENIX");
        !          2072: #endif 
        !          2073: #ifdef M_UNIX
        !          2074:     prtopt(" M_UNIX");
        !          2075: #endif
        !          2076: #ifdef M_I386
        !          2077:     prtopt(" M_I386");
        !          2078: #endif
        !          2079: #ifdef _M_I386
        !          2080:     prtopt(" _M_I386");
        !          2081: #endif
        !          2082: #ifdef i386
        !          2083:     prtopt(" i386");
        !          2084: #endif
        !          2085: #ifdef i286
        !          2086:     prtopt(" i286");
        !          2087: #endif
        !          2088: #ifdef M_I286
        !          2089:     prtopt(" M_I286");
        !          2090: #endif
        !          2091: #ifdef mc68000
        !          2092:     prtopt(" mc68000");
        !          2093: #endif
        !          2094: #ifdef mc68010
        !          2095:     prtopt(" mc68010");
        !          2096: #endif
        !          2097: #ifdef mc68020
        !          2098:     prtopt(" mc68020");
        !          2099: #endif
        !          2100: #ifdef mc68030
        !          2101:     prtopt(" mc68030");
        !          2102: #endif
        !          2103: #ifdef mc68040
        !          2104:     prtopt(" mc68040");
        !          2105: #endif
        !          2106: #ifdef M_68000
        !          2107:     prtopt(" M_68000");
        !          2108: #endif
        !          2109: #ifdef M_68010
        !          2110:     prtopt(" M_68010");
        !          2111: #endif
        !          2112: #ifdef M_68020
        !          2113:     prtopt(" M_68020");
        !          2114: #endif
        !          2115: #ifdef M_68030
        !          2116:     prtopt(" M_68030");
        !          2117: #endif
        !          2118: #ifdef M_68040
        !          2119:     prtopt(" M_68040");
        !          2120: #endif
        !          2121: #ifdef m68k
        !          2122:     prtopt(" m68k");
        !          2123: #endif
        !          2124: #ifdef m88k
        !          2125:     prtopt(" m88k");
        !          2126: #endif
        !          2127: #ifdef pdp11
        !          2128:     prtopt(" pdp11");
        !          2129: #endif
        !          2130: #ifdef iAPX
        !          2131:     prtopt(" iAPX");
        !          2132: #endif
        !          2133: #ifdef __hp9000s800
        !          2134:     prtopt(" __hp9000s800");
        !          2135: #endif
        !          2136: #ifdef __hp9000s500
        !          2137:     prtopt(" __hp9000s500");
        !          2138: #endif
        !          2139: #ifdef __hp9000s300
        !          2140:     prtopt(" __hp9000s300");
        !          2141: #endif
        !          2142: #ifdef __hp9000s200
        !          2143:     prtopt(" __hp9000s200");
        !          2144: #endif
        !          2145: #ifdef AIX
        !          2146:     prtopt(" AIX");
        !          2147: #endif
        !          2148: #ifdef _AIXFS
        !          2149:     prtopt(" _AIXFS");
        !          2150: #endif
        !          2151: #ifdef u370
        !          2152:     prtopt(" u370");
        !          2153: #endif
        !          2154: #ifdef u3b
        !          2155:     prtopt(" u3b");
        !          2156: #endif
        !          2157: #ifdef u3b2
        !          2158:     prtopt(" u3b2");
        !          2159: #endif
        !          2160: #ifdef multimax
        !          2161:     prtopt(" multimax");
        !          2162: #endif
        !          2163: #ifdef balance
        !          2164:     prtopt(" balance");
        !          2165: #endif
        !          2166: #ifdef ibmrt
        !          2167:     prtopt(" ibmrt");
        !          2168: #endif
        !          2169: #ifdef _IBMRT
        !          2170:     prtopt(" _IBMRT");
        !          2171: #endif
        !          2172: #ifdef ibmrs6000
        !          2173:     prtopt(" ibmrs6000");
        !          2174: #endif
        !          2175: #ifdef _AIX
        !          2176:     prtopt(" _AIX");
        !          2177: #endif /* _AIX */
        !          2178: #ifdef _IBMR2
        !          2179:     prtopt(" _IBMR2");
        !          2180: #endif
        !          2181: #ifdef __STRICT_BSD__
        !          2182:     prtopt(" __STRICT_BSD__");
        !          2183: #endif
        !          2184: #ifdef __STRICT_ANSI__
        !          2185:     prtopt(" __STRICT_ANSI__");
        !          2186: #endif
        !          2187: #ifdef _ANSI_C_SOURCE
        !          2188:     prtopt(" _ANSI_C_SOURCE");
        !          2189: #endif
        !          2190: #ifdef __STDC__
        !          2191:     prtopt(" __STDC__");
        !          2192: #endif
        !          2193: #ifdef __GNUC__                                /* gcc in ansi mode */
        !          2194:     prtopt(" __GNUC__");
        !          2195: #endif
        !          2196: #ifdef GNUC                            /* gcc in traditional mode */
        !          2197:     prtopt(" GNUC");
        !          2198: #endif
        !          2199: #ifdef CK_ANSIC
        !          2200:     prtopt(" CK_ANSIC");
        !          2201: #endif
        !          2202: #ifdef CK_ANSILIBS
        !          2203:     prtopt(" CK_ANSILIBS");
        !          2204: #endif
        !          2205: #ifdef _XOPEN_SOURCE
        !          2206:     prtopt(" _XOPEN_SOURCE");
        !          2207: #endif
        !          2208: #ifdef _ALL_SOURCE
        !          2209:     prtopt(" _ALL_SOURCE");
        !          2210: #endif
        !          2211: #ifdef _SC_JOB_CONTROL
        !          2212:     prtopt(" _SC_JOB_CONTROL");
        !          2213: #endif
        !          2214: #ifdef _POSIX_JOB_CONTROL
        !          2215:     prtopt(" _POSIX_JOB_CONTROL");
        !          2216: #endif
        !          2217: #ifdef SVR3JC
        !          2218:     prtopt(" SVR3JC");
        !          2219: #endif
        !          2220: #ifdef _386BSD
        !          2221:     prtopt(" _386BSD");
        !          2222: #endif
        !          2223: #ifdef _BSD
        !          2224:     prtopt(" _BSD");
        !          2225: #endif
        !          2226: #ifdef TERMIOX
        !          2227:     prtopt(" TERMIOX");
        !          2228: #endif /* TERMIOX */
        !          2229: #ifdef STERMIOX
        !          2230:     prtopt(" STERMIOX");
        !          2231: #endif /* STERMIOX */
        !          2232: #ifdef CK_CURSES
        !          2233:     prtopt(" CK_CURSES");
        !          2234: #endif /* CK_CURSES */
        !          2235: #ifdef CK_DTRCD
        !          2236:     prtopt(" CK_DTRCD");
        !          2237: #endif /* CK_DTRCD */
        !          2238: #ifdef CK_DTRCTS
        !          2239:     prtopt(" CK_DTRCTS");
        !          2240: #endif /* CK_DTRCTS */
        !          2241: #ifdef CK_RTSCTS
        !          2242:     prtopt(" CK_RTSCTS");
        !          2243: #endif /* CK_RTSCTS */
        !          2244:     prtopt((char *)0);
        !          2245:     printf("\n\n");
        !          2246: }
        !          2247: #endif /* NOFRILLS */
        !          2248: #endif /* NOSHOW */
        !          2249: 
        !          2250: #ifdef VMS
        !          2251: int
        !          2252: sholbl() {
        !          2253:     printf("VMS Labeled File Features:\n");
        !          2254:     printf(" acl %s (ACL info %s)\n",
        !          2255:           lf_opts & LBL_ACL ? "on " : "off",
        !          2256:           lf_opts & LBL_ACL ? "preserved" : "discarded");
        !          2257:     printf(" backup-date %s (backup date/time %s)\n",
        !          2258:           lf_opts & LBL_BCK ? "on " : "off",
        !          2259:           lf_opts & LBL_BCK ? "preserved" : "discarded");
        !          2260:     printf(" name %s (original filename %s)\n",
        !          2261:           lf_opts & LBL_NAM ? "on " : "off",
        !          2262:           lf_opts & LBL_NAM ? "preserved" : "discarded");
        !          2263:     printf(" owner %s (original file owner id %s)\n",
        !          2264:           lf_opts & LBL_OWN ? "on " : "off",
        !          2265:           lf_opts & LBL_OWN ? "preserved" : "discarded");
        !          2266:     printf(" path %s (original file's disk:[directory] %s)\n",
        !          2267:           lf_opts & LBL_PTH ? "on " : "off",
        !          2268:           lf_opts & LBL_PTH ? "preserved" : "discarded");
        !          2269: }
        !          2270: #endif /* VMS */
        !          2271: 
        !          2272: #ifndef NOSHOW
        !          2273: VOID
        !          2274: shotcs(cs1,cs2) int cs1, cs2; {                /* Show terminal character set */
        !          2275: #ifndef NOCSETS
        !          2276: #ifndef MAC
        !          2277:     int y;
        !          2278:     char *s;
        !          2279: #ifdef CK_ANSIC
        !          2280:     int gettcs(int, int);
        !          2281: #else
        !          2282:     int gettcs();
        !          2283: #endif /* CK_ANSIC */
        !          2284: 
        !          2285:     printf(" Terminal character-set");
        !          2286:     if (cs1 == cs2) {
        !          2287:        printf(": transparent\n");
        !          2288:     } else {
        !          2289:        s = "unknown";
        !          2290:        for (y = 0; y <= nfilc; y++)    /* Look up name in keyword table */
        !          2291:          if (ttcstab[y].kwval == cs2) {
        !          2292:              if (ttcstab[y].flgs & CM_INV) /* Skip synonyms */
        !          2293:                continue;
        !          2294:              s = ttcstab[y].kwd;
        !          2295:              break;
        !          2296:          }
        !          2297:        printf("s:\n   Remote: %s\n   Local:  ",s);
        !          2298:        s = "unknown";
        !          2299:        for (y = 0; y <= nfilc; y++)
        !          2300:          if (ttcstab[y].kwval == cs1) {
        !          2301:                if (ttcstab[y].flgs & CM_INV) /* Skip synonyms */
        !          2302:                  continue;
        !          2303:                s = ttcstab[y].kwd;
        !          2304:              break;
        !          2305:          }
        !          2306:        printf("%s",s);
        !          2307:        if (cs2 != cs1) {
        !          2308:            switch(gettcs(cs2,cs1)) {
        !          2309:              case TC_USASCII:  s = "ascii";        break;
        !          2310:              case TC_1LATIN:   s = "latin1-iso";   break;
        !          2311:              case TC_2LATIN:   s = "latin2-iso";   break;
        !          2312:              case TC_CYRILL:   s = "cyrillic-iso"; break;
        !          2313:              case TC_JEUC:     s = "japanese-euc"; break;
        !          2314:              default:          s = "transparent";  break;
        !          2315:            }
        !          2316:            printf("\n   Via:    %s\n",s);
        !          2317:        }
        !          2318:     }
        !          2319: #endif /* MAC */
        !          2320: #endif /* NOCSETS */
        !          2321: }
        !          2322: #endif /* NOSHOW */
        !          2323: 
        !          2324: #ifndef NOSHOW
        !          2325: int
        !          2326: doshow(x) int x; {
        !          2327:     int y, i; long zz;
        !          2328:     char *s;
        !          2329: 
        !          2330: #ifndef NOSETKEY
        !          2331:     if (x == SHKEY) {                  /* SHOW KEY */
        !          2332:        int c;
        !          2333:        KEY ch;
        !          2334:        CHAR *s;
        !          2335: 
        !          2336:        if ((y = cmcfm()) < 0) return(y);           
        !          2337: #ifdef MAC
        !          2338:        printf("Not implemented\n");
        !          2339:        return(0);
        !          2340: #else /* Not MAC */
        !          2341:        printf(" Press key: ");
        !          2342: #ifdef UNIX
        !          2343: #ifdef NOSETBUF
        !          2344:        fflush(stdout);
        !          2345: #endif /* NOSETBUF */
        !          2346: #endif /* UNIX */
        !          2347:        conbin((char)escape);           /* Put terminal in binary mode */
        !          2348:        c = congks(0);                  /* Get character or scan code */
        !          2349:        concb((char)escape);            /* Restore terminal to cbreak mode */
        !          2350:        if (c < 0) {                    /* Check for error */
        !          2351:            printf("?Error reading key\n");
        !          2352:            return(0);
        !          2353:        }
        !          2354: #ifndef OS2
        !          2355: /*
        !          2356:   Do NOT mask when it can be a raw scan code, perhaps > 255
        !          2357: */
        !          2358:        c &= cmdmsk;                    /* Apply command mask */
        !          2359: #endif /* OS2 */
        !          2360:        printf("\n Key code \\%d => ",c);
        !          2361:         if (macrotab[c]) {             /* See if there's a macro */
        !          2362:            printf("String: ");         /* If so, display its definition */
        !          2363:             s = macrotab[c];
        !          2364:            while (ch = *s++)
        !          2365:              if (ch < 32 || ch == 127
        !          2366: /*
        !          2367:   Systems whose native character sets have graphic characters in C1...
        !          2368: */
        !          2369: #ifndef NEXT                           /* NeXT */
        !          2370: #ifndef AUX                            /* Macintosh */
        !          2371: #ifndef XENIX                          /* IBM PC */
        !          2372: #ifndef OS2                            /* IBM PC */
        !          2373:                  || (ch > 127 && ch < 160)
        !          2374: #endif /* OS2 */
        !          2375: #endif /* XENIX */
        !          2376: #endif /* AUX */
        !          2377: #endif /* NEXT */
        !          2378:                  )
        !          2379:                 printf("\\{%d}",ch);   /* Display control characters */
        !          2380:              else putchar((char) ch);  /* in backslash notation */
        !          2381:            printf("\n");
        !          2382:         } else {                       /* No macro, show single character */
        !          2383:            printf("Character: ");
        !          2384:            ch = keymap[c];
        !          2385:            if (ch < 32 || ch == 127 || ch > 255
        !          2386: #ifndef NEXT
        !          2387: #ifndef AUX
        !          2388: #ifndef XENIX
        !          2389: #ifndef OS2
        !          2390:                  || (ch > 127 && ch < 160)
        !          2391: #endif /* OS2 */
        !          2392: #endif /* XENIX */
        !          2393: #endif /* AUX */
        !          2394: #endif /* NEXT */
        !          2395:                )
        !          2396:              printf("\\%d",(unsigned int) ch);
        !          2397:            else printf("%c \\%d",ch,(unsigned int) ch);
        !          2398:        }
        !          2399:        if (ch == (KEY) c)
        !          2400:          printf(" (self, no translation)\n");
        !          2401:        else printf("\n");
        !          2402:        return(1);
        !          2403: #endif /* MAC */
        !          2404:     }
        !          2405: #endif /* NOSETKEY */
        !          2406: 
        !          2407: #ifndef NOSPL
        !          2408:     if (x == SHMAC) {                  /* SHOW MACRO */
        !          2409:        x = cmfld("Macro name, or carriage return to see them all","",&s,
        !          2410:                  NULL);
        !          2411:        if (x == -3)                    /* This means they want see all */
        !          2412:          *line = '\0';
        !          2413:        else if (x < 0)                 /* Otherwise negative = parse error */
        !          2414:          return(x);
        !          2415:        else                            /* 0 or greater */
        !          2416:          strcpy(line,s);               /* means they typed something */
        !          2417:        if ((y = cmcfm()) < 0) return(y); /* Get confirmation */
        !          2418:        if (*line) {
        !          2419:            slc = 0;                    /* Initial SHO MAC line number */
        !          2420:            x = mlook(mactab,s,nmac);   /* Look up what they typed */
        !          2421:            switch (x) {
        !          2422:              case -3:                  /* Nothing to look up */
        !          2423:                return(0);
        !          2424:              case -1:                  /* Not found */
        !          2425:                printf("%s - not found\n",s);
        !          2426:                return(0);
        !          2427:              case -2:                  /* Ambiguous, matches more than one */
        !          2428:                y = (int)strlen(line);
        !          2429:                slc = 1;
        !          2430:                for (x = 0; x < nmac; x++)
        !          2431:                  if (!strncmp(mactab[x].kwd,line,y))
        !          2432:                    if (shomac(mactab[x].kwd,mactab[x].mval) < 0) break;
        !          2433:                return(1);
        !          2434:              default:                  /* Matches one exactly */
        !          2435:                shomac(mactab[x].kwd,mactab[x].mval);
        !          2436:                return(1);
        !          2437:            }
        !          2438:        } else {                        /* They want to see them all */
        !          2439:            printf("Macros:\n");
        !          2440:            slc = 1;
        !          2441:            for (y = 0; y < nmac; y++)
        !          2442:              if (shomac(mactab[y].kwd,mactab[y].mval) < 0) break;
        !          2443:            return(1);
        !          2444:        }
        !          2445:     }
        !          2446: #endif /* NOSPL */
        !          2447: 
        !          2448: /*
        !          2449:   Other SHOW commands only have two fields.  Get command confirmation here,
        !          2450:   then handle with big switch() statement.
        !          2451: */
        !          2452:     if ((y = cmcfm()) < 0) return(y);
        !          2453:     switch (x) {
        !          2454: 
        !          2455: #ifdef SUNX25
        !          2456:         case SHPAD:
        !          2457:             shopad();
        !          2458:             break;
        !          2459: #endif /* SUNX25 */
        !          2460: 
        !          2461: #ifdef NETCONN
        !          2462:        case SHNET:
        !          2463:            shonet();
        !          2464:            break;
        !          2465: #endif /* NETCONN */
        !          2466: 
        !          2467:        case SHPAR:
        !          2468:            shopar();
        !          2469:            break;
        !          2470:  
        !          2471:         case SHATT:
        !          2472:            shoatt();
        !          2473:            break;
        !          2474:  
        !          2475: #ifndef NOSPL
        !          2476:        case SHCOU:
        !          2477:            printf(" %d\n",count[cmdlvl]);
        !          2478:            break;
        !          2479: #endif /* NOSPL */
        !          2480: 
        !          2481: #ifndef NOSERVER
        !          2482:         case SHSER:                    /* Show Server */
        !          2483: #ifndef NOFRILLS
        !          2484:            printf("Function           Status:\n");
        !          2485:            printf(" GET                %s\n",nm[en_get]);
        !          2486:            printf(" SEND               %s\n",nm[en_sen]);          
        !          2487:            printf(" REMOTE CD/CWD      %s\n",nm[en_cwd]);
        !          2488:            printf(" REMOTE DELETE      %s\n",nm[en_del]);
        !          2489:            printf(" REMOTE DIRECTORY   %s\n",nm[en_dir]);
        !          2490:            printf(" REMOTE HOST        %s\n",nm[en_hos]);          
        !          2491:            printf(" REMOTE SET         %s\n",nm[en_set]);          
        !          2492:            printf(" REMOTE SPACE       %s\n",nm[en_spa]);          
        !          2493:            printf(" REMOTE TYPE        %s\n",nm[en_typ]);          
        !          2494:            printf(" REMOTE WHO         %s\n",nm[en_who]);
        !          2495:            printf(" BYE                %s\n",nm[en_bye]);
        !          2496:             printf(" FINISH             %s\n",nm[en_fin]);
        !          2497: #endif /* NOFRILLS */
        !          2498:            printf("Server timeout: %d\n",srvtim);
        !          2499:            printf("Server display: %s\n\n", srvdis ? "on" : "off");
        !          2500:            break;
        !          2501: #endif /* NOSERVER */
        !          2502: 
        !          2503:         case SHSTA:                    /* Status of last command */
        !          2504:            printf( " %s\n", success ? "SUCCESS" : "FAILURE" );
        !          2505:            return(0);                  /* Don't change it */
        !          2506: 
        !          2507: #ifdef MAC
        !          2508:        case SHSTK: {                   /* Stack for MAC debugging */
        !          2509:            long sp;
        !          2510: 
        !          2511:            sp = -1;
        !          2512:            loadA0 ((char *)&sp);       /* set destination address */
        !          2513:            SPtoaA0();                  /* move SP to destination */
        !          2514:            printf("Stack at 0x%x\n", sp);
        !          2515:            show_queue();               /* more debugging */
        !          2516:            break; 
        !          2517:        }
        !          2518: #endif /* MAC */
        !          2519: 
        !          2520:        case SHTER:
        !          2521:            printf(" Command bytesize:  %d bits\n",
        !          2522:                   (cmdmsk == 0377) ? 8 : 7);
        !          2523:            printf(" Terminal bytesize: %d bits\n",
        !          2524:                   (cmask == 0377) ? 8 : 7);
        !          2525: #ifdef OS2
        !          2526:            printf(" Terminal type: %s\n",
        !          2527:                   (tt_type == TT_VT102) ? "VT102" : "VT52");
        !          2528: 
        !          2529: #endif /* OS2 */
        !          2530:            printf(" Terminal echo: %s\n", duplex ? "local" : "remote");
        !          2531:            printf(" Terminal locking-shift: %s\n", sosi ? "on" : "off");
        !          2532:            printf(" Terminal newline-mode:  %s\n", tnlm ? "on" : "off");
        !          2533:            printf(" Terminal cr-display:    %s\n",
        !          2534:                   tt_crd ? "crlf" : "normal");
        !          2535: #ifdef OS2
        !          2536: /* Should show cursor and colors here too... */
        !          2537:            printf(" Terminal arrow-keys:    %s\n",
        !          2538:                   tt_arrow ? "cursor" : "application");
        !          2539:            printf(" Terminal keypad-mode:   %s\n",
        !          2540:                   tt_keypad ? "numeric" : "application");
        !          2541:            printf(" Terminal wrap:          %s\n", tt_wrap ? "on" : "off");
        !          2542: #endif /* OS2 */
        !          2543: 
        !          2544: #ifndef NOCSETS
        !          2545:            shotcs(tcsl,tcsr);
        !          2546: #endif /* NOCSETS */
        !          2547:            printf(" CONNECT-mode escape character: %d (Ctrl-%c, %s)\n",
        !          2548:             escape,ctl(escape),(escape == 127 ? "DEL" : ccntab[escape]));
        !          2549: #ifdef UNIX
        !          2550:            printf(" Suspend: %s\n", suspend ? "on" : "off");
        !          2551: #endif /* UNIX */
        !          2552:            break;
        !          2553: 
        !          2554: #ifndef NOFRILLS
        !          2555:        case SHVER:
        !          2556:            shover();
        !          2557:            break;
        !          2558: #endif /* NOFRILLS */
        !          2559:  
        !          2560: #ifndef NOSPL
        !          2561:        case SHBUI:                     /* Built-in variables */
        !          2562:            i = 0;
        !          2563:            for (y = 0; y < nvars; y++) {
        !          2564:                printf(" \\v(%s) = %s\n",vartab[y].kwd,nvlook(vartab[y].kwd));
        !          2565:                if (++i > SCRNLEN) {    /* More than a screenful... */
        !          2566:                    if (!askmore())
        !          2567:                      break;
        !          2568:                    else
        !          2569:                      i = 0;
        !          2570:                }
        !          2571:            }
        !          2572:             break;
        !          2573: 
        !          2574:        case SHFUN:                     /* Functions */
        !          2575:            for (y = 0; y < nfuncs; y++)
        !          2576:              printf(" \\f%s()\n",fnctab[y].kwd);
        !          2577:            break;
        !          2578: 
        !          2579:         case SHVAR:                    /* Global variables */
        !          2580:            x = 0;                      /* Variable count */
        !          2581:            slc = 1;                    /* Screen line count for "more?" */
        !          2582:            for (y = 33; y < GVARS; y++)
        !          2583:              if (g_var[y]) {
        !          2584:                  if (x++ == 0) printf("Global variables:\n");
        !          2585:                  sprintf(line," \\%%%c",y);
        !          2586:                  if (shomac(line,g_var[y]) < 0) break;
        !          2587:              }
        !          2588:            if (!x) printf(" No variables defined\n");
        !          2589:            break;
        !          2590: 
        !          2591:         case SHARG:                    /* Args */
        !          2592:            if (maclvl > -1) {
        !          2593:                printf("Macro arguments at level %d\n",maclvl);
        !          2594:                for (y = 0; y < 10; y++)
        !          2595:                  if (m_arg[maclvl][y])
        !          2596:                    printf(" \\%%%d = %s\n",y,m_arg[maclvl][y]);
        !          2597:            } else {
        !          2598:                printf(" No macro arguments at top level\n");
        !          2599:            }
        !          2600:            break;
        !          2601: 
        !          2602:         case SHARR:                    /* Arrays */
        !          2603:            x = 0;
        !          2604:            for (y = 0; y < 27; y++)
        !          2605:              if (a_ptr[y]) {
        !          2606:                  if (x == 0) printf("Declared arrays:\n");
        !          2607:                  x = 1;
        !          2608:                  printf(" \\&%c[%d]\n",(y == 0) ? 64 : y + 96, a_dim[y]);
        !          2609:              }
        !          2610:            if (!x) printf(" No arrays declared\n");
        !          2611:            break;
        !          2612: #endif /* NOSPL */
        !          2613: 
        !          2614:        case SHPRO:                     /* Protocol parameters */
        !          2615:            shoparp();
        !          2616:            printf("\n");
        !          2617:            break;
        !          2618: 
        !          2619:        case SHCOM:                     /* Communication parameters */
        !          2620:            printf("\n");
        !          2621:            shoparc();
        !          2622: #ifndef NODIAL
        !          2623:            printf("\n");
        !          2624: #ifdef NETCONN
        !          2625:            if (!network)
        !          2626: #endif /* NETCONN */
        !          2627:              shodial();
        !          2628: #endif /* NODIAL */
        !          2629:            printf("\n");
        !          2630:            shomdm();
        !          2631:            printf("\n");
        !          2632:            break;
        !          2633: 
        !          2634:        case SHFIL:                     /* File parameters */
        !          2635:            shoparf();
        !          2636:            printf("\n");
        !          2637:            break;
        !          2638: 
        !          2639: #ifndef NOCSETS
        !          2640:        case SHLNG:                     /* Languages */
        !          2641:            shoparl();
        !          2642:            break;
        !          2643: #endif /* NOCSETS */
        !          2644: 
        !          2645: #ifndef NOSPL
        !          2646:        case SHSCR:                     /* Scripts */
        !          2647:            printf(" Take  Echo:     %s\n", techo  ? "On" : "Off");
        !          2648:            printf(" Take  Error:    %s\n", terror ? "On" : "Off");
        !          2649:            printf(" Macro Echo:     %s\n", mecho  ? "On" : "Off");
        !          2650:            printf(" Macro Error:    %s\n", merror ? "On" : "Off");
        !          2651:            printf(" Input Case:     %s\n", incase ? "Observe" : "Ignore");
        !          2652:            printf(" Input Echo:     %s\n", inecho ? "On" : "Off");
        !          2653:             printf(" Input Silence:  %d\n", insilence);
        !          2654:            printf(" Input Timeout:  %s\n", intime ? "Quit" : "Proceed");
        !          2655: #ifndef NOSCRIPT
        !          2656:            printf(" Script Echo:    %s\n", secho  ? "On" : "Off");
        !          2657: #endif /* NOSCRIPT */
        !          2658:            break;
        !          2659: #endif /* NOSPL */
        !          2660: 
        !          2661: #ifndef NOXMIT
        !          2662:          case SHXMI:
        !          2663:            printf(" File type: %s\n", binary ? "binary" : "text");
        !          2664: #ifndef NOCSETS
        !          2665:            shotcs(tcsl,tcsr);
        !          2666: #endif /* NOCSETS */
        !          2667:            printf(" Terminal echo: %s\n", duplex ? "local" : "remote");
        !          2668:             printf(" Transmit EOF: ");
        !          2669:            if (*xmitbuf == NUL) {
        !          2670:                printf("none\n");
        !          2671:            } else {
        !          2672:                char *p;
        !          2673:                p = xmitbuf;
        !          2674:                while (*p) {
        !          2675:                    if (*p < SP)
        !          2676:                      printf("^%c",ctl(*p));
        !          2677:                    else
        !          2678:                      printf("%c",*p);
        !          2679:                    p++;
        !          2680:                }
        !          2681:                printf("\n");
        !          2682:            }
        !          2683:            if (xmitf)
        !          2684:              printf(" Transmit Fill: %d (fill character for blank lines)\n",
        !          2685:                   xmitf);
        !          2686:            else printf(" Transmit Fill: none\n");
        !          2687:            printf(" Transmit Linefeed: %s\n",
        !          2688:                   xmitl ? "on (send linefeeds too)" : "off");
        !          2689:            if (xmitp) 
        !          2690:              printf(" Transmit Prompt: %d (host line end character)\n",xmitp);
        !          2691:            else printf(" Transmit Prompt: none\n");
        !          2692:            printf(" Transmit Echo: %s\n",
        !          2693:                   xmitx ? "on" : "off");
        !          2694:            printf(" Transmit Locking-Shift: %s\n",xmits ? "on" : "off");
        !          2695:            printf(" Transmit Pause: %d milliseconds\n", xmitw);
        !          2696:            break;
        !          2697: #endif /* NOXMIT */
        !          2698: 
        !          2699:          case SHMOD:                   /* SHOW MODEM */
        !          2700:            shmdmlin();
        !          2701:            printf("\n");
        !          2702:            shomdm();
        !          2703:            break;
        !          2704: 
        !          2705: #ifndef MAC
        !          2706:           case SHDFLT:
        !          2707:            zsyscmd(PWDCMD);
        !          2708:             break;
        !          2709: #endif /* MAC */
        !          2710: 
        !          2711:           case SHESC:
        !          2712:            printf(" Escape character: Ctrl-%c (ASCII %d, %s)\r\n",
        !          2713:               ctl(escape), escape, (escape == 127 ? "DEL" : ccntab[escape]));
        !          2714:            break;
        !          2715: 
        !          2716: #ifndef NODIAL
        !          2717:          case SHDIA:
        !          2718:            shmdmlin();
        !          2719:            printf(", speed: ");
        !          2720:            if ((zz = ttgspd()) < 0) {
        !          2721:                printf("unknown\n");
        !          2722:            } else {
        !          2723:                if (zz == 8880) printf("75/1200\n"); else printf("%ld\n",zz);
        !          2724:            }
        !          2725:            doshodial();
        !          2726:            if (carrier == CAR_OFF) s = "off";
        !          2727:            else if (carrier == CAR_ON) s = "on";
        !          2728:            else if (carrier == CAR_AUT) s = "auto";
        !          2729:            else s = "unknown";
        !          2730:            printf(" Carrier: %s", s);
        !          2731:            if (carrier == CAR_ON) {
        !          2732:                if (cdtimo) printf(", timeout: %d sec", cdtimo);
        !          2733:                else printf(", timeout: none");
        !          2734:            }
        !          2735:            if (local
        !          2736: #ifdef NETCONN
        !          2737:                && !network
        !          2738: #endif /* NETCONN */
        !          2739:                ) {
        !          2740:                printf("\n%s modem signals:\n",ttname);
        !          2741:                shomdm();
        !          2742:            } else printf("\n");
        !          2743:            break;
        !          2744: #endif /* NODIAL */
        !          2745: 
        !          2746: #ifdef VMS
        !          2747:        case SHLBL:                     /* Labeled file info */
        !          2748:            sholbl();
        !          2749:            break;
        !          2750: #endif /* VMS */           
        !          2751: 
        !          2752:        case SHCSE:                     /* Character sets */
        !          2753: #ifdef NOCSETS
        !          2754:            printf(
        !          2755: " Character set translation is not supported in this version of C-Kermit\n");
        !          2756: #else
        !          2757:            shocharset();
        !          2758:             printf("\n Unknown-Char-Set: %s\n",
        !          2759:                   unkcs ? "Keep" : "Discard");
        !          2760:            shotcs(tcsl,tcsr);
        !          2761:            printf("\n");
        !          2762: #endif /* NOCSETS */
        !          2763:            break;
        !          2764: 
        !          2765: #ifndef NOFRILLS
        !          2766:          case SHFEA:                   /* Features */
        !          2767:            shofea();
        !          2768:            break;
        !          2769: #endif /* NOFRILLS */
        !          2770: 
        !          2771:        default:
        !          2772:            printf("\nNothing to show...\n");
        !          2773:            return(-2);
        !          2774:     }
        !          2775:     return(success = 1);
        !          2776: }
        !          2777: 
        !          2778: VOID
        !          2779: shmdmlin() {                           /* Briefly show modem & line */
        !          2780:     int i;
        !          2781: #ifndef NODIAL
        !          2782: #ifndef MINIDIAL
        !          2783:     extern int tbmodel;
        !          2784:     _PROTOTYP( char * gtbmodel, (void) );
        !          2785: #endif /* MINIDIAL */
        !          2786: #endif /* NODIAL */
        !          2787:     if (local)
        !          2788:       printf(" Line: %s, Modem: ",ttname);
        !          2789:     else
        !          2790:       printf(" Communication device not yet selected with SET LINE\n Modem: ");
        !          2791: #ifndef NODIAL
        !          2792:     for (i = 0; i < nmdm; i++) {
        !          2793:        if (mdmtab[i].kwval == mdmtyp) {
        !          2794:            printf("%s",mdmtab[i].kwd);
        !          2795:            break;
        !          2796:        }
        !          2797:     }
        !          2798: #ifndef MINIDIAL
        !          2799:     if (tbmodel) printf(" (%s)",gtbmodel()); /* Telebit model info */
        !          2800: #endif /* MINIDIAL */
        !          2801: #else
        !          2802:     printf("(disabled)");
        !          2803: #endif /* NODIAL */
        !          2804: }
        !          2805: #endif /* NOSHOW */
        !          2806: 
        !          2807: #ifdef GEMDOS
        !          2808: isxdigit(c) int c; {
        !          2809:     return(isdigit(c) ||
        !          2810:           (c >= 'a' && c <= 'f') ||
        !          2811:           (c >= 'A' && c <= 'F'));
        !          2812: }
        !          2813: #endif /* GEMDOS */
        !          2814: 
        !          2815: #ifndef NOSHOW
        !          2816: #ifndef NOSPL
        !          2817: int                                    /* SHO MACROS */
        !          2818: shomac(s1, s2) char *s1, *s2; {
        !          2819:     int x, n, pp;
        !          2820:     pp = 0;                            /* Parenthesis counter */
        !          2821: 
        !          2822:     if (!s1)
        !          2823:       return(0);
        !          2824:     else
        !          2825:       printf("\n%s = ",s1);            /* Print blank line and macro name */
        !          2826:     slc++;                             /* Count the line */
        !          2827:     n = (int)strlen(s1) + 4;           /* Width of current line */
        !          2828:     if (!s2) s2 = "(null definition)";
        !          2829: 
        !          2830:     while (x = *s2++) {                        /* Loop thru definition */
        !          2831:        if (x == '(') pp++;             /* Treat commas within parens */
        !          2832:        if (x == ')') pp--;             /* as ordinary text */
        !          2833:        if (pp < 0) pp = 0;             /* Outside parens, */
        !          2834:        if (x == ',' && pp == 0) {      /* comma becomes comma-dash-NL. */
        !          2835:            putchar(',');
        !          2836:            putchar('-');
        !          2837:            x = '\n';
        !          2838:        }
        !          2839:        putchar(x);                     /* Output the character */
        !          2840:        if (x == '\n') {                /* If it was a newline */
        !          2841: #ifdef UNIX
        !          2842: #ifdef NOSETBUF
        !          2843:            fflush(stdout);
        !          2844: #endif /* NOSETBUF */
        !          2845: #endif /* UNIX */
        !          2846:            putchar(' ');               /* Indent the next line 1 space */
        !          2847:            while(*s2 == ' ') s2++;     /* skip past leading blanks */
        !          2848:            n = 2;                      /* restart the character counter */
        !          2849:            slc++;                      /* and increment the line counter. */
        !          2850:        } else if (++n > SCRNWID) {     /* If line is too wide */
        !          2851:            putchar('-');               /* output a dash */
        !          2852:            putchar(NL);                /* and a newline */
        !          2853: #ifdef UNIX
        !          2854: #ifdef NOSETBUF
        !          2855:            fflush(stdout);
        !          2856: #endif /* NOSETBUF */
        !          2857: #endif /* UNIX */
        !          2858:            n = 1;                      /* and restart the char counter */
        !          2859:            slc++;                      /* and increment the line counter */
        !          2860:        }
        !          2861:        if (n < 3 && slc > SCRNLEN) {   /* If new line and screen is full */
        !          2862:            if (!askmore()) return(-1); /* ask if they want more. */
        !          2863:            n = 1;                      /* They do, start a new line */
        !          2864:            slc = 0;                    /* and restart line counter */
        !          2865:        }
        !          2866:     }
        !          2867:     putchar(NL);                       /* End of definition */
        !          2868:     if (++slc > SCRNLEN) {
        !          2869:        if (!askmore()) return(-1);
        !          2870:        slc = 0;
        !          2871:     }
        !          2872:     return(0);
        !          2873: }
        !          2874: #endif /* NOSPL */
        !          2875: #endif /* NOSHOW */
        !          2876: 
        !          2877: #ifndef NOSHOW
        !          2878: int
        !          2879: shoatt() {
        !          2880:     printf("Attributes: %s\n", atcapr ? "On" : "Off");
        !          2881:     if (!atcapr) return(0);
        !          2882:     printf(" Blocksize: %s\n", atblki ? "On" : "Off");
        !          2883:     printf(" Date: %s\n", atdati ? "On" : "Off");
        !          2884:     printf(" Disposition: %s\n", atdisi ? "On" : "Off");
        !          2885:     printf(" Encoding (Character Set): %s\n", atenci ? "On" : "Off");
        !          2886:     printf(" Length: %s\n", atleni ? "On" : "Off");
        !          2887:     printf(" Type (text/binary): %s\n", attypi ? "On" : "Off");
        !          2888:     printf(" System ID: %s\n", atsidi ? "On" : "Off");
        !          2889:     printf(" System Info: %s\n", atsysi ? "On" : "Off");
        !          2890:     return(0);
        !          2891: }
        !          2892: #endif /* NOSHOW */
        !          2893: 
        !          2894: #ifndef NOSPL
        !          2895: /* Evaluate an arithmetic expression. */
        !          2896: /* Code adapted from ev, by Howie Kaye of Columbia U & others. */
        !          2897: 
        !          2898: static int xerror;
        !          2899: static char *cp;
        !          2900: static long tokval;
        !          2901: static char curtok;
        !          2902: static long expval;
        !          2903: 
        !          2904: #define LONGBITS (8*sizeof (long))
        !          2905: #define NUMBER 'N'
        !          2906: #define EOT 'E'
        !          2907: 
        !          2908: /*
        !          2909:  Replacement for strchr() and index(), neither of which seem to be universal.
        !          2910: */
        !          2911: 
        !          2912: static char *
        !          2913: #ifdef CK_ANSIC
        !          2914: windex(char * s, char c)
        !          2915: #else
        !          2916: windex(s,c) char *s, c;
        !          2917: #endif /* CK_ANSIC */
        !          2918: /* windex */ {
        !          2919:     while (*s != NUL && *s != c) s++;
        !          2920:     if (*s == c) return(s); else return(NULL);
        !          2921: }
        !          2922: 
        !          2923: /*
        !          2924:  g e t t o k
        !          2925: 
        !          2926:  Returns the next token.  If token is a NUMBER, sets tokval appropriately.
        !          2927: */
        !          2928: static char
        !          2929: gettok() {
        !          2930:     while (isspace(*cp)) cp++ ;
        !          2931:     switch(*cp) {
        !          2932:       case '$':                                /* ??? */
        !          2933:       case '+':                                /* Add */
        !          2934:       case '-':                                /* Subtract or Negate */
        !          2935:       case '@':                                /* Greatest Common Divisor */
        !          2936:       case '*':                                /* Multiply */
        !          2937:       case '/':                                /* Divide */
        !          2938:       case '%':                                /* Modulus */
        !          2939:       case '<':                                /* Left shift */
        !          2940:       case '>':                                /* Right shift */
        !          2941:       case '&':                                /* And */
        !          2942:       case '|':                                /* Or */
        !          2943:       case '#':                                /* Exclusive Or */
        !          2944:       case '~':                                /* Not */
        !          2945:       case '^':                                /* Exponent */
        !          2946:       case '!':                                /* Factorial */
        !          2947:       case '(':                                /* Parens for grouping */
        !          2948:       case ')': return(*cp++);         /* operator, just return it */
        !          2949:       case '\n':
        !          2950:       case '\0': return(EOT);          /* end of line, return that */
        !          2951:     }
        !          2952:     if (isxdigit(*cp)) {               /* digit, must be a number */
        !          2953:        char tbuf[80],*tp;              /* buffer to accumulate number */
        !          2954:        int radix = 10;                 /* default radix */
        !          2955:        for (tp=tbuf; isxdigit(*cp); cp++)
        !          2956:          *tp++ = isupper(*cp) ? tolower(*cp) : *cp;
        !          2957:        *tp = '\0';                     /* end number */
        !          2958:        switch(isupper(*cp) ? tolower(*cp) : *cp) { /* examine break char */
        !          2959:          case 'h':
        !          2960:          case 'x': radix = 16; cp++; break; /* if radix signifier... */
        !          2961:          case 'o':
        !          2962:          case 'q': radix = 8; cp++; break;
        !          2963:          case 't': radix = 2; cp++; break;
        !          2964:        }
        !          2965:        for (tp=tbuf,tokval=0; *tp != '\0'; tp++)  {
        !          2966:            int dig;
        !          2967:            dig = *tp - '0';            /* convert number */
        !          2968:            if (dig > 10) dig -= 'a'-'0'-10;
        !          2969:            if (dig >= radix) {
        !          2970:                xerror = 1;
        !          2971:                if (cmdlvl == 0)
        !          2972:                  printf("invalid digit '%c' in number\n",*tp);
        !          2973:                return(NUMBER);
        !          2974:            }
        !          2975:            tokval = radix*tokval + dig;
        !          2976:        }
        !          2977:        return(NUMBER);
        !          2978:     }
        !          2979:     if (cmdlvl == 0)
        !          2980:       printf("Invalid character '%c' in input\n",*cp);
        !          2981:     xerror = 1;
        !          2982:     cp++;
        !          2983:     return(gettok());
        !          2984: }
        !          2985: 
        !          2986: static long
        !          2987: #ifdef CK_ANSIC
        !          2988: expon(long x, long y)
        !          2989: #else
        !          2990: expon(x,y) long x,y;
        !          2991: #endif /* CK_ANSIC */
        !          2992: /* expon */ {
        !          2993:     long result = 1;
        !          2994:     int sign = 1;
        !          2995:     if (y < 0) return(0);
        !          2996:     if (x < 0) {
        !          2997:        x = -x;
        !          2998:        if (y & 1) sign = -1;
        !          2999:     }
        !          3000:     while (y != 0) {
        !          3001:        if (y & 1) result *= x;
        !          3002:        y >>= 1;
        !          3003:        if (y != 0) x *= x;
        !          3004:   }
        !          3005:   return(result * sign);
        !          3006: }
        !          3007: 
        !          3008: /*
        !          3009:  * factor ::= simple | simple ^ factor
        !          3010:  *
        !          3011:  */
        !          3012: _PROTOTYP( static VOID simple, (void) );
        !          3013: 
        !          3014: static VOID
        !          3015: factor() {
        !          3016:     long oldval;
        !          3017:     simple();
        !          3018:     if (curtok == '^') {
        !          3019:        oldval = expval;
        !          3020:        curtok = gettok();
        !          3021:        factor();
        !          3022:        expval = expon(oldval,expval);
        !          3023:     }
        !          3024: }
        !          3025: 
        !          3026: /*
        !          3027:  * termp ::= NULL | {*,/,%,&} factor termp
        !          3028:  *
        !          3029:  */
        !          3030: static VOID
        !          3031: termp() {
        !          3032:     while (curtok == '*' || curtok == '/' || curtok == '%' || curtok == '&') {
        !          3033:        long oldval;
        !          3034:        char op;
        !          3035:        op = curtok;
        !          3036:        curtok = gettok();              /* skip past operator */
        !          3037:        oldval = expval;
        !          3038:        factor();
        !          3039:        switch(op) {
        !          3040:          case '*': expval = oldval * expval; break;
        !          3041:          case '/':
        !          3042:            if (expval == 0) expval = -1; /* don't divide by 0 */
        !          3043:            else expval = oldval / expval; break;
        !          3044:          case '%': expval = oldval % expval; break;
        !          3045:          case '&': expval = oldval & expval; break;
        !          3046:        }
        !          3047:     }
        !          3048: }
        !          3049: 
        !          3050: static long
        !          3051: #ifdef CK_ANSIC
        !          3052: fact(long x)
        !          3053: #else
        !          3054: fact(x) long x;
        !          3055: #endif /* CK_ANSIC */
        !          3056: /* fact */ {                           /* factorial */
        !          3057:     long result = 1;
        !          3058:     while (x > 1)
        !          3059:       result *= x--;
        !          3060:     return(result);
        !          3061: }
        !          3062: 
        !          3063: /*
        !          3064:  * term ::= factor termp
        !          3065:  *
        !          3066:  */
        !          3067: static VOID
        !          3068: term() {
        !          3069:     factor();
        !          3070:     termp();
        !          3071: }
        !          3072: 
        !          3073: static long
        !          3074: #ifdef CK_ANSIC
        !          3075: gcd(long x, long y)
        !          3076: #else
        !          3077: gcd(x,y) long x,y;
        !          3078: #endif /* CK_ANSIC */
        !          3079: /* gcd */ {                            /* Greatest Common Divisor */
        !          3080:     int nshift = 0;
        !          3081:     if (x < 0) x = -x;
        !          3082:     if (y < 0) y = -y;                 /* validate arguments */
        !          3083:     if (x == 0 || y == 0) return(x + y);    /* this is bogus */
        !          3084:     
        !          3085:     while (!((x & 1) | (y & 1))) {     /* get rid of powers of 2 */
        !          3086:        nshift++;
        !          3087:        x >>= 1;
        !          3088:        y >>= 1;
        !          3089:     }
        !          3090:     while (x != 1 && y != 1 && x != 0 && y != 0) {
        !          3091:        while (!(x & 1)) x >>= 1;       /* eliminate unnecessary */
        !          3092:        while (!(y & 1)) y >>= 1;       /* powers of 2 */
        !          3093:        if (x < y) {                    /* force x to be larger */
        !          3094:            long t;
        !          3095:            t = x;
        !          3096:            x = y;
        !          3097:            y = t;
        !          3098:        }
        !          3099:        x -= y;
        !          3100:     }
        !          3101:     if (x == 0 || y == 0) return((x + y) << nshift); /* gcd is non-zero one */
        !          3102:     else return((long) 1 << nshift);   /* else gcd is 1 */
        !          3103: }
        !          3104: 
        !          3105: /*
        !          3106:  * exprp ::= NULL | {+,-,|,...} term exprp
        !          3107:  *
        !          3108:  */
        !          3109: static VOID
        !          3110: exprp() {
        !          3111:     while (windex("+-|<>#@",curtok) != NULL) {
        !          3112:        long oldval;
        !          3113:        char op;
        !          3114:        op = curtok;
        !          3115:        curtok = gettok();              /* skip past operator */
        !          3116:        oldval = expval;
        !          3117:        term();
        !          3118:        switch(op) {
        !          3119:          case '+' : expval = oldval + expval; break;
        !          3120:          case '-' : expval = oldval - expval; break;
        !          3121:          case '|' : expval = oldval | expval; break;
        !          3122:          case '#' : expval = oldval ^ expval; break;
        !          3123:          case '@' : expval = gcd(oldval,expval); break;
        !          3124:          case '<' : expval = oldval << expval; break;
        !          3125:          case '>' : expval = oldval >> expval; break;
        !          3126:        }
        !          3127:     }
        !          3128: }
        !          3129: 
        !          3130: /*
        !          3131:  * expr ::= term exprp
        !          3132:  *
        !          3133:  */
        !          3134: static VOID
        !          3135: expr() {
        !          3136:     term();
        !          3137:     exprp();
        !          3138: }
        !          3139: 
        !          3140: static long
        !          3141: xparse() {
        !          3142:     curtok = gettok();
        !          3143:     expr();
        !          3144: #ifdef COMMENT
        !          3145:     if (curtok == '$') {
        !          3146:        curtok = gettok();
        !          3147:        if (curtok != NUMBER) {
        !          3148:            if (cmdlvl == 0) printf("illegal radix\n");
        !          3149:            return(0);
        !          3150:        }
        !          3151:        curtok = gettok();
        !          3152:     }
        !          3153: #endif /* COMMENT */
        !          3154:     if (curtok != EOT) {
        !          3155:        if (cmdlvl == 0)
        !          3156:          printf("extra characters after expression\n");
        !          3157:        xerror = 1;
        !          3158:     }
        !          3159:     return(expval);
        !          3160: }
        !          3161: 
        !          3162: char *
        !          3163: evala(s) char *s; {
        !          3164:     char *p;                           /* Return pointer */
        !          3165:     long v;                            /* Numeric value */
        !          3166: 
        !          3167:     xerror = 0;                                /* Start out with no error */
        !          3168:     cp = s;                            /* Make the argument global */
        !          3169:     v = xparse();                      /* Parse the string */
        !          3170:     p = numbuf;                                /* Convert long number to string */
        !          3171:     sprintf(p,"%ld",v);
        !          3172:     return(xerror ? "" : p);           /* Return empty string on error */
        !          3173: }
        !          3174: 
        !          3175: /*
        !          3176:  * simplest ::= NUMBER | ( expr )
        !          3177:  *
        !          3178:  */
        !          3179: static VOID
        !          3180: simplest() {
        !          3181:     if (curtok == NUMBER) expval = tokval;
        !          3182:     else if (curtok == '(') {
        !          3183:        curtok = gettok();              /* skip over paren */
        !          3184:        expr();
        !          3185:        if (curtok != ')') {
        !          3186:            if (cmdlvl == 0) printf("missing right parenthesis\n");
        !          3187:            xerror = 1;
        !          3188:        }
        !          3189:     }
        !          3190:     else {
        !          3191:        if (cmdlvl == 0) printf("operator unexpected\n");
        !          3192:        xerror = 1;
        !          3193:     }
        !          3194:     curtok = gettok();
        !          3195: }
        !          3196: 
        !          3197: /*
        !          3198:  * simpler ::= simplest | simplest !
        !          3199:  *
        !          3200:  */
        !          3201: static VOID
        !          3202: simpler() {
        !          3203:     simplest();
        !          3204:     if (curtok == '!') {
        !          3205:        curtok = gettok();
        !          3206:        expval = fact(expval);
        !          3207:     }
        !          3208: }
        !          3209: 
        !          3210: /*
        !          3211:  * simple ::= {-,~} simpler | simpler
        !          3212:  *
        !          3213:  */
        !          3214: 
        !          3215: static VOID
        !          3216: simple() {
        !          3217:     if (curtok == '-' || curtok == '~') {
        !          3218:        int op = curtok;
        !          3219:        curtok = gettok();              /* skip over - sign */
        !          3220:        simpler();                      /* parse the factor again */
        !          3221:        expval = op == '-' ? -expval : ~expval;
        !          3222:     } else simpler();
        !          3223: }
        !          3224: #endif /* NOSPL */
        !          3225: 
        !          3226: #ifndef NOSPL
        !          3227: /*  D C L A R R A Y  --  Declare an array  */
        !          3228: 
        !          3229: int                                    /* Declare an array of size n */
        !          3230: #ifdef CK_ANSIC
        !          3231: dclarray(char a, int n)
        !          3232: #else
        !          3233: dclarray(a,n) char a; int n;
        !          3234: #endif /* CK_ANSIC */
        !          3235: /* dclarray */ {
        !          3236:     char **p; int i, n2;
        !          3237: 
        !          3238:     if (a > 63 && a < 96) a += 32;     /* Convert to lowercase */
        !          3239:     if (a < 96 || a > 122) return(-1); /* Verify name */
        !          3240:     a -= 96;                           /* Convert name to number */
        !          3241:     if ((p = a_ptr[a]) != NULL) {      /* Delete old array of same name */
        !          3242:        n2 = a_dim[a];
        !          3243:        for (i = 0; i <= n2; i++)       /* First delete its elements */
        !          3244:          if (p[i]) free(p[i]);
        !          3245:        free(a_ptr[a]);                 /* Then the element list */
        !          3246:        a_ptr[a] = (char **) NULL;      /* Remove pointer to element list */
        !          3247:        a_dim[a] = 0;                   /* Set dimension at zero. */
        !          3248:     }
        !          3249:     if (n == 0) return(0);             /* If dimension 0, just deallocate. */
        !          3250: 
        !          3251:     p = (char **) malloc((n+1) * sizeof(char **)); /* Allocate for new array */
        !          3252:     if (p == NULL) return(-1);         /* Check */
        !          3253:     a_ptr[a] = p;                      /* Save pointer to member list */
        !          3254:     a_dim[a] = n;                      /* Save dimension */
        !          3255:     for (i = 0; i <= n; i++)           /* Initialize members to null */
        !          3256:       p[i] = NULL;
        !          3257:     return(0);
        !          3258: }
        !          3259: 
        !          3260: /*  A R R A Y N A M  --  Parse an array name  */
        !          3261: 
        !          3262: /*
        !          3263:   Call with pointer to string that starts with the array reference.
        !          3264:   String may begin with either \& or just &.
        !          3265:   On success,
        !          3266:     Returns letter ID (always lowercase) in argument c,
        !          3267:       which can also be accent grave (` = 96; '@' is converted to grave);
        !          3268:     Dimension or subscript in argument n;
        !          3269:     IMPORTANT: These arguments must be provided by the caller as addresses
        !          3270:     of ints (not chars), for example:
        !          3271:       char *s; int x, y;
        !          3272:       arraynam(s,&x,&y);
        !          3273:   On failure, returns a negative number, with args n and c set to zero.
        !          3274: */
        !          3275: int
        !          3276: arraynam(ss,c,n) char *ss; int *c; int *n; {
        !          3277:     int i, y, pp;
        !          3278:     char x;
        !          3279:     char *s, *p, *sx, *vnp;
        !          3280:     char vnbuf[VNAML+1];               /* On stack to allow for */
        !          3281:     char ssbuf[VNAML+1];               /* recursive calls... */
        !          3282:     char sxbuf[VNAML+1];
        !          3283: 
        !          3284:     *c = *n = 0;                       /* Initialize return values */
        !          3285:     for (i = 0; i < (int)strlen(ss); i++) /* Check length */
        !          3286:       if (ss[i] == ']')
        !          3287:        break;
        !          3288:     if (i > VNAML) {
        !          3289:        printf("?Array reference too long - %s\n",ss);
        !          3290:        return(-9);
        !          3291:     }
        !          3292:     strncpy(vnbuf,ss,VNAML);
        !          3293:     vnp = vnbuf;
        !          3294:     if (vnbuf[0] == CMDQ && vnbuf[1] == '&') vnp++;
        !          3295:     if (*vnp != '&') {
        !          3296:        printf("?Not an array - %s\n",vnbuf);
        !          3297:        return(-9);
        !          3298:     }
        !          3299:     x = *(vnp + 1);                    /* Fold case of array name */
        !          3300:     /* We don't use isupper & tolower here on purpose because these */
        !          3301:     /* would produce undesired effects with accented letters. */
        !          3302:     if (x > 63 && x < 91) x  = *(vnp +1) = x + 32;
        !          3303:     if ((x < 96) || (x > 122) || (*(vnp+2) != '[')) {
        !          3304:        printf("?Invalid format for array name - %s\n",vnbuf);
        !          3305:        return(-9);
        !          3306:     }
        !          3307:     *c = x;                            /* Return the array name */
        !          3308:     s = vnp+3;                         /* Get dimension */
        !          3309:     p = ssbuf;    
        !          3310:     pp = 1;                            /* Bracket counter */
        !          3311:     for (i = 0; i < VNAML && *s != NUL; i++) { /* Copy up to ] */
        !          3312:        if (*s == '[') pp++;
        !          3313:        if (*s == ']' && --pp == 0) break;
        !          3314:        *p++ = *s++;
        !          3315:     }
        !          3316:     if (*s != ']') {
        !          3317:        printf("?No closing bracket on array dimension - %s\n",vnbuf);
        !          3318:        return(-9);
        !          3319:     }
        !          3320:     *p = NUL;                          /* Terminate subscript with null */
        !          3321:     p = ssbuf;                         /* Point to beginning of subscript */
        !          3322:     sx = sxbuf;                                /* Where to put expanded subscript */
        !          3323:     y = VNAML-1;
        !          3324:     xxstring(p,&sx,&y);                        /* Convert variables, etc. */
        !          3325:     if (!chknum(sxbuf)) {              /* Make sure it's all digits */
        !          3326:        printf("?Array dimension or subscript must be numeric - %s\n",sxbuf);
        !          3327:        return(-9);
        !          3328:     }
        !          3329:     if ((y = atoi(sxbuf)) < 0) {
        !          3330:         if (cmflgs == 0) printf("\n");
        !          3331:         printf("?Array dimension or subscript must be positive or zero - %s\n",
        !          3332:               sxbuf);
        !          3333:        return(-9);
        !          3334:     }
        !          3335:     *n = y;                            /* Return the subscript or dimension */
        !          3336:     return(0);
        !          3337: }
        !          3338: 
        !          3339: int
        !          3340: chkarray(a,i) int a, i; {              /* Check if array is declared */
        !          3341:     int x;                             /* and if subscript is in range */
        !          3342:     if (a == 64) a = 96;               /* Convert atsign to grave accent */
        !          3343:     x = a - 96;                                /* Values must be in range 96-122 */
        !          3344:     if (x < 0 || x > 26) return(-2);   /* Not in range */
        !          3345:     if (a_ptr[x] == NULL) return(-1);  /* Not declared */
        !          3346:     if (i > a_dim[x]) return(-2);      /* Declared but out of range. */
        !          3347:     return(a_dim[x]);                  /* All ok, return dimension */
        !          3348: }
        !          3349: 
        !          3350: char *
        !          3351: arrayval(a,i) int a, i; {              /* Return value of \&a[i] */
        !          3352:     int x; char **p;                   /* (possibly NULL) */
        !          3353: 
        !          3354:     if (a == 64) a = 96;               /* Convert atsign to grave accent */
        !          3355:     x = a - 96;                                /* Values must be in range 96-122 */
        !          3356:     if (x < 0 || x > 26) return(NULL); /* Not in range */
        !          3357:     if ((p = a_ptr[x]) == NULL)                /* Array not declared */
        !          3358:       return(NULL);
        !          3359:     if (i > a_dim[x])                  /* Subscript out of range. */
        !          3360:       return(NULL);
        !          3361:     return(p[i]);                      /* All ok, return pointer to value. */
        !          3362: }
        !          3363: #endif /* NOSPL */
        !          3364: 
        !          3365: #ifndef NOSPL
        !          3366: /*  P A R S E V A R  --  Parse a variable name or array reference.  */
        !          3367: /*
        !          3368:  Call with:
        !          3369:    s  = pointer to candidate variable name or array reference.
        !          3370:    *c = address of integer in which to return variable ID.
        !          3371:    *i = address of integer in which to return array subscript.
        !          3372:  Returns:
        !          3373:    -2:  syntax error in variable name or array reference.
        !          3374:     1:  successful parse of a simple variable, with ID in c.
        !          3375:     2:  successful parse of an array reference, w/ID in c and subscript in i.
        !          3376: */
        !          3377: int
        !          3378: parsevar(s,c,i) char *s; int *c, *i; {
        !          3379:     char *p;
        !          3380:     int x,y,z;
        !          3381: 
        !          3382:     p = s;
        !          3383:     if (*s == CMDQ) s++;               /* Point after backslash */
        !          3384: 
        !          3385:     if (*s != '%' && *s != '&') {      /* Make sure it's % or & */
        !          3386:        printf("?Not a variable name - %s\n",p);
        !          3387:        return(-9);
        !          3388:     }
        !          3389:     if ((int)strlen(s) < 2) {
        !          3390:        printf("?Incomplete variable name - %s\n",p);
        !          3391:        return(-9);
        !          3392:     }
        !          3393:     if (*s == '%' && *(s+2) != '\0') {
        !          3394:        printf("?Only one character after '%%' in variable name, please\n");
        !          3395:        return(-9);
        !          3396:     }
        !          3397:     if (*s == '&' && *(s+2) != '[') {
        !          3398:        printf("?Array subscript expected - %s\n",p);
        !          3399:        return(-9);
        !          3400:     }
        !          3401:     if (*s == '%') {                   /* Simple variable. */
        !          3402:        y = *(s+1);                     /* Get variable ID letter/char */
        !          3403:        if (isupper(y)) y -= ('a'-'A'); /* Convert upper to lower case */
        !          3404:        *c = y;                         /* Set the return values. */
        !          3405:        *i = -1;                        /* No array subscript. */
        !          3406:        return(1);                      /* Return 1 = simple variable */
        !          3407:     }
        !          3408:     if (*s == '&') {                   /* Array reference. */
        !          3409:        if (arraynam(s,&x,&z) < 0) { /* Go parse it. */
        !          3410:            printf("?Invalid array reference - %s\n",p);
        !          3411:            return(-9);
        !          3412:        }
        !          3413:        if (chkarray(x,z) < 0) {        /* Check if declared, etc. */
        !          3414:            printf("?Array not declared or subscript out of range\n");
        !          3415:            return(-9);
        !          3416:        }
        !          3417:        *c = x;                         /* Return array letter */
        !          3418:        *i = z;                         /* and subscript. */
        !          3419:        return(2);
        !          3420:     }    
        !          3421:     return(-2);                                /* None of the above. */
        !          3422: }
        !          3423: 
        !          3424: #define VALN 20
        !          3425: 
        !          3426: /* Get the numeric value of a variable */
        !          3427: /*
        !          3428:   Call with pointer to variable name, pointer to int for return value.
        !          3429:   Returns:
        !          3430:     0 on success with second arg containing the value.
        !          3431:    -1 on failure (bad variable syntax, variable not defined or not numeric).
        !          3432: */
        !          3433: int
        !          3434: varval(s,v) char *s; int *v; {
        !          3435:     char valbuf[VALN+1];               /* s is pointer to variable name */
        !          3436:     char *p;
        !          3437:     int y;
        !          3438: 
        !          3439:     p = valbuf;                                /* Expand variable into valbuf. */
        !          3440:     y = VALN;
        !          3441:     if (xxstring(s,&p,&y) < 0) return(-1);
        !          3442:     p = valbuf;                                /* Make sure value is numeric */
        !          3443:     if (!chknum(p)) return(-1);
        !          3444:     *v = atoi(p);                      /* Convert numeric string to int */
        !          3445:     return(0);    
        !          3446: }
        !          3447: 
        !          3448: /* Increment or decrement a variable */
        !          3449: /* Returns -1 on failure, 0 on success, with 4th argument set to result */
        !          3450: 
        !          3451: int
        !          3452: incvar(s,x,z,r) char *s; int x, z, *r; { /* Increment a numeric variable */
        !          3453:     char valbuf[VALN+1];               /* s is pointer to variable name */
        !          3454:                                        /* x is amount to increment by */
        !          3455:     int n;                             /* z != 0 means add */
        !          3456:                                        /* z = 0 means subtract */
        !          3457: 
        !          3458:     if (varval(s,&n) < 0)              /* Convert numeric string to int */
        !          3459:       return(-1);
        !          3460:     if (z)                             /* Increment it by the given amount */
        !          3461:       n += x;
        !          3462:     else                               /* or decrement as requested. */
        !          3463:       n -= x;
        !          3464:     sprintf(valbuf,"%d",n);            /* Convert back to numeric string */
        !          3465:     addmac(s,valbuf);                  /* Replace old variable */
        !          3466:     *r = n;                            /* Return the integer value */
        !          3467:     return(0);
        !          3468: }
        !          3469: #endif /* NOSPL */
        !          3470: 
        !          3471: /* Functions moved here from ckuusr.c to even out the module sizes... */
        !          3472: 
        !          3473: #ifndef NOSPL                          /* Need xwords() function to break */
        !          3474: #define XWORDS                         /* string up into words. */
        !          3475: #endif /* NOSPL */
        !          3476: #ifndef NODIAL
        !          3477: #ifndef XWORDS
        !          3478: #define XWORDS
        !          3479: #endif /* XWORDS */
        !          3480: #endif /* NODIAL */
        !          3481: 
        !          3482: #ifdef XWORDS
        !          3483: /*
        !          3484:   Breaks string s up into a list of up to max words.
        !          3485:   Pointers to each word go into the array list[].
        !          3486:   If list is NULL, then they are added to the macro table.
        !          3487: */
        !          3488: 
        !          3489: VOID
        !          3490: xwords(s,max,list) char *s; int max; char *list[]; {
        !          3491:     char *p;
        !          3492:     int b, k, y, z;
        !          3493: #ifndef NOSPL
        !          3494:     int macro;
        !          3495:     macro = (list == NULL);
        !          3496:     debug(F101,"xwords macro","",macro);
        !          3497: #endif /* NOSPL */
        !          3498: 
        !          3499:     p = s;                             /* Pointer to beginning of string */
        !          3500:     b = 0;                             /* Flag for outer brace removal */
        !          3501:     k = 0;                             /* Flag for in-word */
        !          3502:     y = 0;                             /* Brace nesting level */
        !          3503:     z = 0;                             /* Argument counter, 0 thru max */
        !          3504: 
        !          3505:     while (1) {                                /* Go thru argument list */
        !          3506:        if (!s || (*s == '\0')) {       /* No more characters? */
        !          3507:            if (k != 0) {
        !          3508:                if (z == max) break;    /* Only go up to max. */
        !          3509:                z++;                    /* Count it. */
        !          3510: #ifndef NOSPL
        !          3511:                if (macro) {
        !          3512:                    varnam[1] = z + '0'; /* Assign last argument */
        !          3513:                    addmac(varnam,p);
        !          3514:                } else
        !          3515: #endif /* NOSPL */
        !          3516:                  list[z] = p;
        !          3517:                break;                  /* And get out. */
        !          3518:            } else break;
        !          3519:        } 
        !          3520:        if (k == 0 && (*s == SP || *s == HT)) { /* Eat leading blanks */
        !          3521:            s++;
        !          3522:            continue;
        !          3523:        } else if (*s == '{') {         /* An opening brace */
        !          3524:            if (k == 0 && y == 0) {     /* If leading brace */
        !          3525:                p = s+1;                /* point past it */
        !          3526:                b = 1;                  /* and flag that we did this */
        !          3527:            }
        !          3528:            k = 1;                      /* Flag that we're in a word */
        !          3529:            y++;                        /* Count the brace. */
        !          3530:        } else if (*s == '}') {         /* A closing brace. */
        !          3531:            y--;                        /* Count it. */
        !          3532:            if (y == 0 && b != 0) {     /* If it matches the leading brace */
        !          3533:                *s = SP;                /* change it to a space */
        !          3534:                b = 0;                  /* and we're not in braces any more */
        !          3535:            } else if (y < 0) k = 1;    /* otherwise just start a new word. */
        !          3536:        } else if (*s != SP && *s != HT) { /* Nonspace means we're in a word */
        !          3537:            if (k == 0) p = s;          /* Mark the beginning */
        !          3538:            k = 1;                      /* Set in-word flag */
        !          3539:        }
        !          3540:        /* If we're not inside a braced quantity, and we are in a word, and */
        !          3541:        /* we have hit whitespace, then we have an argument to assign. */
        !          3542:        if ((y < 1) && (k != 0) && (*s == SP || *s == HT)) { 
        !          3543:            *s = '\0';                  /* terminate the arg with null */
        !          3544:            k = 0;                      /* say we're not in a word any more */
        !          3545:            y = 0;                      /* start braces off clean again */
        !          3546:            if (z == max) break;        /* Only go up to max. */
        !          3547:            z++;                        /* count this arg */
        !          3548: #ifndef NOSPL
        !          3549:            if (macro) {
        !          3550:                varnam[1] = z + '0';    /* compute its name */
        !          3551:                addmac(varnam,p);       /* add it to the macro table */
        !          3552:            } else
        !          3553: #endif /* NOSPL */
        !          3554:              list[z] = p;
        !          3555:            p = s+1;
        !          3556:        }
        !          3557:        s++;                            /* Point past this character */
        !          3558:     }
        !          3559:     if ((z == 0) && (y > 1)) {         /* Extra closing brace(s) at end */
        !          3560:        z++;
        !          3561: #ifndef NOSPL
        !          3562:        if (macro) {
        !          3563:            varnam[1] = z + '0';        /* compute its name */
        !          3564:            addmac(varnam,p);           /* Add rest of line to last arg */
        !          3565:        } else
        !          3566: #endif /* NOSPL */
        !          3567:          list[z] = p;
        !          3568:     }
        !          3569: #ifndef NOSPL
        !          3570:     if (macro) macargc[maclvl] = z + 1;        /* Set \v(argc) variable */
        !          3571: #endif /* NOSPL */
        !          3572:     return;
        !          3573: }
        !          3574: #endif /* XWORDS */
        !          3575: 
        !          3576: #ifndef NOSPL
        !          3577: /* D O D O  --  Do a macro */
        !          3578: 
        !          3579: /*
        !          3580:   Call with x = macro table index, s = pointer to arguments.
        !          3581:   Returns 0 on failure, 1 on success.
        !          3582: */
        !          3583: 
        !          3584: int
        !          3585: dodo(x,s) int x; char *s; {
        !          3586:     int y;
        !          3587: 
        !          3588:     debug(F101,"dodo maclvl","",maclvl);
        !          3589:     if (++maclvl > MACLEVEL) {         /* Make sure we have storage */
        !          3590:         debug(F101,"dodo maclvl too deep","",maclvl);
        !          3591:        --maclvl;
        !          3592:        printf("Macros nested too deeply\n");
        !          3593:        return(0);
        !          3594:     }
        !          3595:     macp[maclvl] = mactab[x].mval;     /* Point to the macro body */ 
        !          3596:     macx[maclvl] = mactab[x].mval;     /* Remember where the beginning is */
        !          3597:     debug(F111,"do macro",macp[maclvl],maclvl);
        !          3598: 
        !          3599:     cmdlvl++;                          /* Entering a new command level */
        !          3600:     if (cmdlvl > CMDSTKL) {            /* Too many macros + TAKE files? */
        !          3601:         debug(F101,"dodo cmdlvl too deep","",cmdlvl);
        !          3602:        cmdlvl--;
        !          3603:        printf("?TAKE files and DO commands nested too deeply\n");
        !          3604:        return(0);
        !          3605:     }
        !          3606: #ifdef VMS
        !          3607:     conres();                          /* So Ctrl-C, etc, will work. */
        !          3608: #endif /* VMS */
        !          3609:     ifcmd[cmdlvl] = 0;
        !          3610:     iftest[cmdlvl] = 0;
        !          3611:     count[cmdlvl] = 0;
        !          3612:     cmdstk[cmdlvl].src = CMD_MD;       /* Say we're in a macro */
        !          3613:     cmdstk[cmdlvl].lvl = maclvl;       /* and remember the macro level */
        !          3614:     mrval[maclvl] = NULL;              /* Initialize return value */
        !          3615: 
        !          3616:     debug(F110,"do macro",mactab[x].kwd,0);
        !          3617: 
        !          3618: /* Clear old %0..%9 arguments */
        !          3619: 
        !          3620:     addmac("%0",mactab[x].kwd);                /* Define %0 = name of macro */
        !          3621:     varnam[0] = '%';
        !          3622:     varnam[2] = '\0';
        !          3623:     for (y = 1; y < 10; y++) {         /* Clear args %1..%9 */
        !          3624:        varnam[1] = y + '0';
        !          3625:        delmac(varnam);
        !          3626:     }  
        !          3627: 
        !          3628: /* Assign the new args one word per arg, allowing braces to group words */
        !          3629: 
        !          3630:     xwords(s,9,NULL);
        !          3631:     return(1);
        !          3632: }
        !          3633: 
        !          3634: /* Insert "literal" quote around each comma-separated command to prevent */
        !          3635: /* its premature expansion.  Only do this if object command is surrounded */
        !          3636: /* by braces. */
        !          3637: 
        !          3638: static char* flit = "\\flit(";
        !          3639: 
        !          3640: int
        !          3641: litcmd(src,dest) char **src, **dest; {
        !          3642:     int bc = 0, pp = 0;
        !          3643:     char *s, *lp, *ss;
        !          3644: 
        !          3645:     s = *src;
        !          3646:     lp = *dest;
        !          3647: 
        !          3648:     while (*s == SP) s++;              /* strip extra leading spaces */
        !          3649:     if (*s == '{') {
        !          3650: 
        !          3651:         pp = 0;                                /* paren counter */
        !          3652:        bc = 1;                         /* count leading brace */
        !          3653:        *lp++ = *s++;                   /* copy it */
        !          3654:        while (*s == SP) s++;           /* strip interior leading spaces */
        !          3655:        ss = flit;                      /* point to "\flit(" */
        !          3656:        while (*lp++ = *ss++) ;         /* copy it */
        !          3657:        lp--;                           /* back up over null */
        !          3658:        while (*s) {                    /* go thru rest of text */
        !          3659:            ss = flit;                  /* point back to start of "\flit(" */
        !          3660:            if (*s == '{') bc++;        /* count brackets */
        !          3661:            if (*s == '(') pp++;        /* and parens */
        !          3662:            if (*s == ')') pp--;
        !          3663:            if (*s == '}') {            /* Closing brace. */
        !          3664:                if (--bc == 0) {        /* Final one? */
        !          3665:                    *lp++ = ')';        /* Add closing paren for "\flit()" */
        !          3666:                    *lp++ = *s++;
        !          3667:                    break;
        !          3668:                }
        !          3669:            }
        !          3670:            if (*s == ',' && pp == 0) { /* comma not inside of parens */
        !          3671:                *lp++ = ')';            /* closing ) of \flit( */
        !          3672:                *lp++ = ',';            /* insert the comma */
        !          3673:                while (*lp++ = *ss++) ; /* start new "\flit(" */
        !          3674:                lp--;                   /* back up over null */
        !          3675:                s++;                    /* skip over comma in source string */
        !          3676:                while (*s++ == SP);     /* eat leading spaces again. */
        !          3677:                s--;                    /* back up over nonspace */
        !          3678:                continue;
        !          3679:            }
        !          3680:             *lp++ = *s++;              /* Copy anything but comma here. */
        !          3681:         }
        !          3682:        *lp = NUL;
        !          3683:     } else {                           /* No brackets around, */
        !          3684:        while (*lp++ = *s++) ;          /* just copy. */
        !          3685:        lp--;
        !          3686:     }
        !          3687:     *src = s;
        !          3688:     *dest = lp;
        !          3689:     if (bc) return(-1);
        !          3690:     else return(0);
        !          3691: }
        !          3692: #endif /* NOSPL */
        !          3693: 
        !          3694: int
        !          3695: docd() {                               /* Do the CD command */
        !          3696:     int x;
        !          3697:     char *s;
        !          3698: 
        !          3699: #ifdef GEMDOS
        !          3700:     if ((x = cmdir("Name of local directory, or carriage return",homdir,&s,
        !          3701:                   NULL)) < 0 )
        !          3702: #else
        !          3703:     if ((x = cmdir("Name of local directory, or carriage return",homdir,&s,
        !          3704:                   xxstring)) < 0 )
        !          3705: #endif /* GEMDOS */
        !          3706:       return(x);
        !          3707:     if (x == 2) {
        !          3708:        printf("?Wildcards not allowed in directory name\n");
        !          3709:        return(-9);
        !          3710:     }
        !          3711:     strcpy(line,s);                    /* Make a safe copy */
        !          3712:     s = line;
        !          3713:     if ((x = cmcfm()) < 0)             /* Get confirmation */
        !          3714:       return(x);
        !          3715:     if (! zchdir(s)) {
        !          3716:        cwdf = 0;
        !          3717:        perror(s);
        !          3718:     } else cwdf = 1;
        !          3719: #ifdef OS2
        !          3720:     printf("%s\n", zgtdir());
        !          3721: #else /* Not OS2 */
        !          3722: #ifndef MAC
        !          3723:     zsyscmd(PWDCMD);                   /* assume this works... */
        !          3724: #endif /* MAC */
        !          3725: #endif /* OS2 */
        !          3726:     return(cwdf);
        !          3727: }
        !          3728: 
        !          3729: VOID
        !          3730: fixcmd() {                     /* Fix command parser after interruption */
        !          3731:     dostop();                  /* Back to top level (also calls conint()). */
        !          3732:     bgchk();                   /* Check background status */
        !          3733:     if (*psave) {              /* If old prompt saved, */
        !          3734:        cmsetp(psave);          /* restore it. */
        !          3735:        *psave = NUL;
        !          3736:     }
        !          3737:     success = 0;               /* Tell parser last command failed */
        !          3738: }
        !          3739: 
        !          3740: VOID
        !          3741: prtopt(s) char *s; {                   /* Print an option */
        !          3742:     static int x = 0;                  /* (used by SHOW VER) */
        !          3743:     int y;                             /* Does word wrap. */
        !          3744:     if (!s) { x = 0; return; }         /* Call with null pointer to */
        !          3745:     y = (int)strlen(s);                        /* reset horizontal position. */
        !          3746:     x += y;
        !          3747:     if (x > 79) {
        !          3748:        printf("\n%s",s);
        !          3749:        x = y;
        !          3750:     } else printf("%s",s);
        !          3751: }
        !          3752: 
        !          3753: #endif /* NOICP */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.