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