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