# 2.11BSD#431 - /usr/src/new/kermit5.188/ckuus6.c

##### Functions

    doask             X
    dobug             X
    dodef             X
    dodel             X
    dodial            X
    dodir             X
    doelse            X
    doenable          X
    dofor             X
    doget             X
    dogoto            X
    dogta             X
    doif              X
    doincr            X
    doopen            X
    dopaus            X
    dorenam           X
    doreturn          X
    dotake            X
    ludial            X
    xxstrcmp          X

##### Variables

    cwdf              X
    dialnum           X
    ifc               X
    ifcond            X
    ifcp              X
    iftab             X
    mstab             X
    nif               X
    nms               X
    nopn              X
    not               X
    opntab            X

##### Macros

    fclose            X
    feof              X
    fgets             X
    fopen             X
    rewind            X
    xsystem           X

       1: #ifndef NOICP
       2:
       3: /*  C K U U S 6 --  "User Interface" for Unix Kermit (Part 6)  */
       4:
       5: /*
       6:   Author: Frank da Cruz (fdc@columbia.edu, FDCCU@CUVMA.BITNET),
       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 "ckcxla.h"
      23: #include "ckcnet.h"         /* Network symbols */
      24:
      25: #ifdef datageneral
      26: #define fgets(stringbuf,max,fd) dg_fgets(stringbuf,max,fd)
      27: #endif /* datageneral */
      28:
      29: #ifdef MAC              /* internal MAC file routines */
      30: #define feof mac_feof
      31: #define rewind mac_rewind
      32: #define fgets mac_fgets
      33: #define fopen mac_fopen
      34: #define fclose mac_fclose
      35:
      36: int mac_feof();
      37: void mac_rewind();
      38: char *mac_fgets();
      39: FILE *mac_fopen();
      40: int mac_fclose();
      41: #endif /* MAC */
      42:
      43: /* External Kermit Variables, see ckmain.c for description. */
      44:
      45: extern int size, rpsiz, urpsiz, local, stdinf, sndsrc, xitsta,
      46:   displa, binary, parity, escape, xargc, flow,
      47:   turn, duplex, nfils, ckxech, pktlog, seslog, tralog, stdouf,
      48:   turnch, dfloc, keep, maxrps, warn, cnflg, tlevel, pflag, msgflg,
      49:   mdmtyp, zincnt, fblksiz, frecl, frecfm, atcapr, atdiso, verwho, quiet;
      50: extern int repars, terror, techo;
      51:
      52: extern long vernum, speed;
      53: extern char *versio, *protv, *ckxv, *ckzv, *fnsv, *connv, *dftty, *cmdv;
      54: extern char *dialv, *loginv, *for_def[], *whil_def[], *xif_def[];
      55: extern char *ckxsys, *ckzsys, *cmarg, *cmarg2, **xargv;
      56: extern char *DIRCMD, *PWDCMD, *DELCMD, *WHOCMD, ttname[], filnam[];
      57: extern CHAR sstate;
      58: extern char *zinptr;
      59:
      60: #ifndef NOMSEND             /* Multiple SEND */
      61: extern char *msfiles[];
      62: #endif /* NOMSEND */
      63: extern char fspec[];            /* Most recent filespec */
      64:
      65: /* Declarations from cmd package */
      66:
      67: #ifdef DCMDBUF
      68: extern char *cmdbuf, *atmbuf;       /* Command buffers */
      69: #else
      70: extern char cmdbuf[], atmbuf[];     /* Command buffers */
      71: #endif /* DCMDBUF */
      72:
      73: #ifndef NOSPL
      74: extern struct mtab *mactab;
      75: extern int nmac;
      76: #endif /* NOSPL */
      77:
      78: /* Declarations from ck?fio.c module */
      79:
      80: extern int backgrd, bgset;      /* Kermit executing in background */
      81:
      82: #ifdef COMMENT
      83: /*
      84:   These must be on stack!
      85: */
      86: #ifndef NOSPL
      87: extern char vnambuf[];          /* Buffer for variable names */
      88: extern char *vnp;           /* Pointer to same */
      89: #endif /* NOSPL */
      90: #endif /* COMMENT */
      91:
      92: extern char psave[];            /* For saving & restoring prompt */
      93: extern char tmpbuf[], *tp;      /* Temporary buffer */
      94:
      95: /* Keyword tables specific to this module */
      96:
      97: /* Modem signal table */
      98:
      99: struct keytab mstab[] = {
     100: #ifdef COMMENT
     101: /* The forms preceded by backslash are for MS-DOS Kermit compatibility. */
     102: /* But... \dsr doesn't work because \d = decimal constant introducer */
     103:     "\\cd",  BM_DCD, CM_INV,        /* Carrier Detect */
     104:     "\\cts", BM_CTS, CM_INV,        /* Clear To Send  */
     105:     "\\dsr", BM_DSR, CM_INV,        /* Data Set Ready */
     106:     "\\ri",  BM_RNG, CM_INV,        /* Ring Indicator */
     107: #endif /* COMMENT */
     108:     "cd",    BM_DCD, 0,         /* Carrier Detect */
     109:     "cts",   BM_CTS, 0,         /* Clear To Send  */
     110:     "dsr",   BM_DSR, 0,         /* Data Set Ready */
     111:     "ri",    BM_RNG, 0          /* Ring Indicator */
     112: };
     113: int nms = (sizeof(mstab) / sizeof(struct keytab));
     114:
     115: #ifndef NOSPL
     116: struct keytab opntab[] = {
     117: #ifndef NOPUSH
     118:     "!read",  XYFZ_Y, 0,
     119:     "!write", XYFZ_X, 0,
     120: #endif /* NOPUSH */
     121:     "append", XYFZ_A, 0,
     122:     "read",   XYFZ_O, 0,
     123:     "write",  XYFZ_N, 0
     124: };
     125: int nopn = (sizeof(opntab) / sizeof(struct keytab));
     126:
     127: struct keytab iftab[] = {       /* IF commands */
     128:     "<",          XXIFLT, 0,
     129:     "=",          XXIFAE, 0,
     130:     ">",          XXIFGT, 0,
     131:     "background", XXIFBG, 0,
     132:     "count",      XXIFCO, 0,
     133:     "defined",    XXIFDE, 0,
     134: #ifdef COMMENT
     135:     "eof",        XXIFEO, 0,
     136: #endif /* COMMENT */
     137:     "equal",      XXIFEQ, 0,
     138:     "error",      XXIFFA, CM_INV,
     139:     "exist",      XXIFEX, 0,
     140:     "failure",    XXIFFA, 0,
     141:     "foreground", XXIFFG, 0,
     142:     "llt",        XXIFLL, 0,
     143:     "lgt",        XXIFLG, 0,
     144:     "not",        XXIFNO, 0,
     145:     "numeric",    XXIFNU, 0,
     146:     "success",    XXIFSU, 0
     147: };
     148: int nif = (sizeof(iftab) / sizeof(struct keytab));
     149: #endif /* NOSPL */
     150:
     151: /* Variables and symbols local to this module */
     152:
     153: #ifndef NODIAL
     154: char *dialnum = (char *)0;      /* Remember DIAL number for REDIAL */
     155: extern char * dialdir;          /* Dial directory file name */
     156: extern FILE * dialfd;           /* Dial directory file descriptor */
     157: #endif /* NODIAL */
     158:
     159: #ifndef NOSPL
     160: int ifc,                /* IF case */
     161:     not = 0,                /* Flag for IF NOT */
     162:     ifargs;             /* Count of IF condition words */
     163: char ifcond[100];           /* IF condition text */
     164: char *ifcp;             /* Pointer to IF condition text */
     165: #ifdef DCMDBUF
     166: extern int *ifcmd, *count, *iftest;
     167: #else
     168: extern int ifcmd[];         /* Last command was IF */
     169: extern int iftest[];            /* Last IF was true */
     170: extern int count[];         /* For IF COUNT, one for each cmdlvl */
     171: #endif /* DCMDBUF */
     172: #endif /* NOSPL */
     173:
     174: #ifdef DCMDBUF
     175: extern char *line;          /* Character buffer for anything */
     176: #else
     177: extern char line[];
     178: #endif /* DCMDBUF */
     179: extern char *lp;            /* Pointer to line buffer */
     180:
     181: int cwdf = 0;               /* CWD has been done */
     182:
     183: extern int en_cwd, en_del, en_dir, en_fin, /* Flags for ENABLE/DISABLE */
     184:    en_get, en_hos, en_sen, en_set, en_spa, en_typ, en_who, en_bye;
     185:
     186: extern FILE *tfile[];           /* File pointers for TAKE command */
     187: extern char *tfnam[];           /* Names of TAKE files */
     188:
     189: extern int success;         /* Command success/failure flag */
     190:
     191: #ifndef NOSPL
     192: extern int              /* SET INPUT parameters. */
     193:   incase;
     194:
     195: extern int maclvl;          /* Macro to execute */
     196: extern char *macx[];            /* Index of current macro */
     197: extern char *mrval[];           /* Macro return value */
     198: extern char *macp[];            /* Pointer to macro */
     199: extern int macargc[];           /* ARGC from macro invocation */
     200:
     201: extern char *m_arg[MACLEVEL][NARGS];    /* Stack of macro arguments */
     202: extern char *g_var[];           /* Global variables %a, %b, etc */
     203:
     204: #ifdef DCMDBUF
     205: extern struct cmdptr *cmdstk;       /* The command stack itself */
     206: #else
     207: extern struct cmdptr cmdstk[];      /* The command stack itself */
     208: #endif /* DCMDBUF */
     209: extern int cmdlvl;          /* Current position in command stack */
     210: #endif /* NOSPL */
     211:
     212: #define xsystem(s) zsyscmd(s)
     213:
     214: static int x, y, z = 0;
     215: static char *s, *p;
     216:
     217: /*  X X S T R C M P  --  Caseless string comparison  */
     218: /*
     219:   Call with pointers to the two strings, s1 and s2, and a length, n.
     220:   Compares up to n characters of the two strings and returns:
     221:     1 if s1 > t1
     222:     0 if s1 = s2
     223:    -1 if s1 < t1
     224: */
     225: int
     226: xxstrcmp(s1,s2,n) char *s1, *s2; int n; { /* Caseless string comparison. */
     227:     char t1, t2;
     228:
     229:     if (!s1) s1 = "";           /* Watch out for null pointers. */
     230:     if (!s2) s2 = "";
     231:     while (n--) {
     232:     t1 = *s1++;         /* Get next character from each. */
     233:     if (isupper(t1)) t1 = tolower(t1);
     234:     t2 = *s2++;
     235:     if (isupper(t2)) t2 = tolower(t2);
     236:     if (t1 < t2) return(-1);    /* s1 < s2 */
     237:     if (t1 > t2) return(1);     /* s1 > s2 */
     238:     }
     239:     return(0);              /* They're equal */
     240: }
     241:
     242: #ifndef NOSPL
     243:
     244: /* Do the ASK, ASKQ, GETOK, and READ commands */
     245:
     246: #ifndef NOFRILLS
     247:    extern struct keytab yesno[];
     248:    extern int nyesno;
     249: #endif /* NOFRILLS */
     250:
     251: int
     252: doask(cx) int cx; {
     253:
     254:     if (cx != XXGOK) {          /* Get variable name */
     255:     if ((y = cmfld("Variable name","",&s,NULL)) < 0) {
     256:         if (y == -3) {
     257:         printf("?Variable name required\n");
     258:         return(-9);
     259:         } else return(y);
     260:     }
     261:     strcpy(line,s);         /* Make a copy. */
     262:     lp = line;
     263:     if ((y = parsevar(s,&x,&z)) < 0)  /* Check to make sure it's a */
     264:       return(y);              /* variable name. */
     265:     }
     266:     if (cx == XXREA) {          /* READ command */
     267:     if ((y = cmcfm()) < 0)      /* Get confirmation */
     268:       return(y);
     269:     if (chkfn(ZRFILE) < 1) {    /* File open? */
     270:         printf("?Read file not open\n");
     271:         return(0);
     272:     }
     273:     s = line+VNAML+1;       /* Where to read into. */
     274:     y = zsinl(ZRFILE, s, LINBUFSIZ - VNAML - 1); /* Read a line. */
     275:     debug(F111,"read zsinl",s,y);
     276:     if (y < 0) {            /* On EOF or other error, */
     277:         zclose(ZRFILE);     /* close the file, */
     278:         delmac(lp);         /* delete the variable, */
     279:         return(success = 0);    /* and return failure. */
     280:     } else {            /* Read was OK. */
     281:         success = (addmac(lp,s) < 0 ? 0 : 1); /* Define the variable */
     282:             debug(F111,"read addmac",lp,success);
     283:         return(success);        /* Return success. */
     284:     }
     285:     }
     286:
     287:     /* ASK, ASKQ, or GETOK */
     288:
     289:     if ((y = cmtxt("Prompt, enclose in { braces } to preserve\n\
     290: leading and trailing spaces, precede question mark with backslash (\\).",
     291:            cx == XXGOK ? "{ Yes or no? }" : "",
     292:            &p,xxstring)) < 0) return(y);
     293:
     294:     cmsavp(psave,80);           /* Save old prompt */
     295:     if (*p == '{') {            /* New prompt enclosed in braces? */
     296:     x = (int)strlen(p) - 1;     /* Yes, strip them. */
     297:     if (p[x] == '}') {
     298:         p[x] = NUL;
     299:         p++;
     300:     }
     301:     }
     302:     cmsetp(p);              /* Make new prompt */
     303:     if (cx == XXASKQ) {         /* For ASKQ, */
     304:     concb((char)escape);        /* put console in cbreak mode */
     305:     cmini(0);           /* and no-echo mode. */
     306:     } else {                /* For others, regular echoing. */
     307:     cmini(ckxech);
     308:     }
     309:     x = -1;             /* This means to reparse. */
     310: reprompt:
     311:     if (pflag) prompt(xxstring);    /* Issue prompt. */
     312:     if (cx == XXGOK) {
     313: #ifndef NOFRILLS
     314:     x = cmkey(yesno,nyesno,"","",xxstring); /* GETOK uses keyword table */
     315:     if (x < 0) {            /* Parse error */
     316:         if (x == -3) {      /* No answer? */
     317:         printf("Please respond Yes or No\n"); /* Make them answer */
     318:         cmini(ckxech);
     319:         }
     320:         goto reprompt;
     321:     }
     322:     if ((y = cmcfm()) < 0)      /* Get confirmation */
     323:       goto reprompt;
     324:     cmsetp(psave);          /* Restore prompt */
     325:     return(x);          /* Return success or failure */
     326: #else
     327:     ;
     328: #endif /* NOFRILLS */
     329:     } else {                /* ASK or ASKQ */
     330:     while (x == -1) {       /* Prompt till they answer */
     331:         x = cmtxt("Please respond.\n\
     332:  Type \\? to include a question mark in your response.","",&s,NULL);
     333:         debug(F111," cmtxt",s,x);
     334:     }
     335:     if (cx == XXASKQ)       /* ASKQ must echo CRLF here */
     336:       printf("\r\n");
     337:     if (x < 0) {            /* If cmtxt parse error, */
     338:         cmsetp(psave);      /* restore original prompt */
     339:         return(x);          /* and return cmtxt's error code. */
     340:     }
     341:     if (*s == NUL) {        /* If user typed a bare CR, */
     342:         cmsetp(psave);      /* Restore old prompt, */
     343:         delmac(lp);         /* delete variable if it exists, */
     344:         return(success = 1);    /* and return. */
     345:     }
     346:     y = addmac(lp,s);       /* Add it to the macro table. */
     347:     debug(F111,"ask addmac",lp,y);
     348:     cmsetp(psave);          /* Restore old prompt. */
     349:     return(success = y < 0 ? 0 : 1);
     350:     }
     351: }
     352: #endif /* NOSPL */
     353:
     354: #ifndef NOSPL
     355: int
     356: doincr(cx) int cx; {            /* INCREMENT, DECREMENT */
     357:     char vnambuf[VNAML];        /* Buffer for variable names */
     358:
     359:     if ((y = cmfld("Variable name","",&s,NULL)) < 0) {
     360:     if (y == -3) {
     361:         printf("?Variable name required\n");
     362:         return(-9);
     363:     } else return(y);
     364:     }
     365:     if (*s != CMDQ) {
     366:         *vnambuf = CMDQ;
     367:     strncpy(vnambuf+1,s,VNAML-1);
     368:     } else strncpy(vnambuf,s,VNAML);
     369:
     370:     if ((y = parsevar(vnambuf,&x,&z)) < 0)
     371:       return(y);
     372:
     373:     if ((y = cmnum("by amount","1",10,&x,xxstring)) < 0) return(y);
     374:     if ((y = cmcfm()) < 0) return(y);
     375:
     376:     z = (cx == XXINC ? 1 : 0);      /* Increment or decrement? */
     377:
     378:     if (incvar(vnambuf,x,z,&y) < 0) {
     379:     printf("?Variable %s not defined or not numeric\n",vnambuf);
     380:     return(success = 0);
     381:     }
     382:     return(success = 1);
     383: }
     384: #endif /* NOSPL */
     385:
     386:
     387: /* Do the (_)DEFINE and (_)ASSIGN commands */
     388:
     389: #ifndef NOSPL
     390: int
     391: dodef(cx) int cx; {
     392:     char vnambuf[VNAML];        /* Buffer for variable names */
     393:     char *vnp;              /* Pointer to same */
     394:     if (cx == XXDFX || cx == XXASX)
     395:       y = cmfld("Macro or variable name","",&s,xxstring); /* eval var name */
     396:     else
     397:       y = cmfld("Macro or variable name","",&s,NULL);     /* don't evaluate */
     398:     if (y < 0) {
     399:     if (y == -3) {
     400:         printf("?Variable name required\n");
     401:         return(-9);
     402:     } else return(y);
     403:     }
     404:     debug(F110,"dodef",s,0);
     405:     strcpy(vnambuf,s);
     406:     vnp = vnambuf;
     407:     if (vnambuf[0] == CMDQ && (vnambuf[1] == '%' || vnambuf[1] == '&')) vnp++;
     408:     if (*vnp == '%' || *vnp == '&') {
     409:     if ((y = parsevar(vnp,&x,&z)) < 0) return(y);
     410:     debug(F101,"dodef","",x);
     411:     if (y == 1) {           /* Simple variable */
     412:         if ((y = cmtxt("Definition of variable","",&s,NULL)) < 0)
     413:           return(y);
     414:         debug(F110,"xxdef var name",vnp,0);
     415:         debug(F110,"xxdef var def",s,0);
     416:     } else if (y == 2) {        /* Array element */
     417:         if ((y = arraynam(s,&x,&z)) < 0) return(y);
     418:         if (x == 96) {
     419:         printf("?Argument vector array is read-only\n");
     420:         return(-9);
     421:         }
     422:         if (chkarray(x,z) < 0) return(-2);
     423:         if ((y = cmtxt("Definition of array element","",&s,NULL)) < 0)
     424:           return(y);
     425:         debug(F110,"xxdef array ref",vnp,0);
     426:         debug(F110,"xxdef array def",s,0);
     427:     }
     428:     } else {                /* Macro */
     429:     if ((y = cmtxt("Definition of macro","",&s,NULL)) < 0) return(y);
     430:     debug(F110,"xxdef macro name",vnp,0);
     431:     debug(F110,"xxdef macro def",s,0);
     432:     if (*s == '{') {        /* Allow macro def to be bracketed. */
     433:         s++;            /* If it is, remove the brackets. */
     434:         y = (int)strlen(s);     /* FOR command depends on this! */
     435:         if (y > 0 && s[y-1] == '}') s[y-1] = NUL;
     436:     }
     437:     }
     438:     if (*s == NUL) {            /* No arg given, undefine */
     439:     delmac(vnp);            /* silently... */
     440:     return(success = 1);        /* even if it doesn't exist... */
     441:     }
     442:
     443:     /* Defining a new macro or variable */
     444:
     445:     if (cx == XXASS || cx == XXASX) {   /* ASSIGN rather than DEFINE? */
     446:     int t;
     447:     t = LINBUFSIZ-1;
     448:     lp = line;          /* If so, expand its value now */
     449:     xxstring(s,&lp,&t);
     450:     s = line;
     451:     }
     452:     debug(F111,"calling addmac",s,(int)strlen(s));
     453:
     454:     y = addmac(vnp,s);          /* Add it to the appropriate table. */
     455:     if (y < 0) {
     456:     printf("?%s failed\n",(cx == XXASS || cx == XXASX) ?
     457:            "ASSIGN" : "DEFINE");
     458:     return(success = 0);
     459:     }
     460:     return(success = 1);
     461: }
     462: #endif /* NOSPL */
     463:
     464:
     465: #ifndef NODIAL
     466: extern struct keytab partab[];
     467: /*
     468:    L U D I A L  --  Lookup up dialing directory entry.
     469:
     470:    Call with string to look up and file descriptor of open dialing directory
     471:    file.  On success, returns pointer to phone number and sets speed
     472:    and parity according to the directory entry.  On failure, returns the NULL
     473:    pointer.
     474: */
     475: char *
     476: ludial(s,f) char *s; FILE *f; {
     477:     int n, n1, n2, i, t;        /* Workers */
     478:     long xspeed = -1L, x2;      /* Speed to set from directory entry */
     479:     int xparity = -1;           /* Parity to set ...*/
     480:     char *info[5];          /* Array of words from entry */
     481:
     482:     if (!s || !f) return(NULL);     /* Validate arguments */
     483:     if ((n1 = strlen(s)) < 1)
     484:       return(NULL);
     485: /*
     486:   We make one or two passes.  The first pass searches for an exact match.
     487:   If it fails, the second pass searches for the first entry of which the
     488:   search string is an abbreviation.  Of course this could be done in one
     489:   pass, but it was safer to add a couple lines for the for-loop than to
     490:   totally rearrange the code at the last minute.  (Edit 186)
     491: */
     492:     for (i = 0; i < 2; i++) {       /* Do this twice */
     493:     debug(F101,"ludial pass","",i+1);
     494:     rewind(f);          /* Go to beginning of directory file */
     495:     while (1) {
     496:         if (fgets(line,LINBUFSIZ,f) == NULL) { /* Read a line */
     497:         if (i == 0)     /* EOF */
     498:           break;        /* If first pass, start second pass */
     499:         if (!backgrd && !quiet) /* If second pass, give message */
     500:           printf(" %s not in %s\n",s,dialdir);
     501:         debug(F110,"ludial fails",s,0);
     502:         return(NULL);
     503:         }
     504:         n = strlen(line);       /* Strip terminator(s) */
     505:         while ((n > 0) && (line[n-1] < '!'))
     506:           line[--n] = NUL;
     507:         debug(F111,"ludial",line,n);
     508:
     509:         info[0] = NULL; info[1] = NULL; info[2] = NULL;
     510:         info[3] = NULL; info[4] = NULL;
     511:
     512:         xwords(line,4,info);    /* Get the words. */
     513:         if (info[1]) {      /* First word. */
     514:         if ((n2 = (int) strlen(info[1])) < 1) /* Its length */
     515:           continue;     /* If no first word, keep looking. */
     516:
     517:         if (n2 < n1)        /* If directory entry name shorter */
     518:           continue;     /* than search name, then no match. */
     519:         if (i == 0 && n2 != n1) /* Require exact match on first pass */
     520:           continue;
     521:         if (xxstrcmp(s,info[1],n1)) /* Caseless string comparison */
     522:           continue;     /* up to length of search name */
     523:         if (!backgrd && !quiet)
     524:           printf(" From dialing directory %s: %s=%s\n",
     525:              dialdir,info[1],info[2]);
     526:         if (info[3]) {      /* Third word = speed */
     527:             if (*info[3] != '=') { /* "=" means don't change it */
     528:             xspeed = atol(info[3]);
     529:             x2 = xspeed / 10L;
     530:             if (x2 > 0) {
     531:                 if (ttsspd((int) x2) < 0)
     532:                   printf("\n Can't set speed to %s\n",info[3]);
     533:                 else
     534:                   speed = xspeed;
     535:             }
     536:             }
     537:         }
     538:         if (info[4]) {      /* 4th word = parity */
     539:             if (*info[4] != '=') { /* "=" means don't change it */
     540:             if ((xparity = lookup(partab,info[4],5,&t)) > -1)
     541:               parity = xparity;
     542:             }
     543:         }
     544:         return(info[2]);    /* Return 2nd word = phone number */
     545:         }
     546:     }
     547:     }
     548: }
     549:
     550: int
     551: dodial(cx) int cx; {            /* DIAL or REDIAL */
     552:     if (cx == XXRED) {          /* REDIAL or... */
     553:     if ((y = cmcfm()) < 0) return(y);
     554:     if (dialnum) {
     555:         s = dialnum;
     556:     } else {
     557:         printf("?No DIAL command given yet\n");
     558:         return(-9);
     559:     }
     560:     } else if (cx == XXDIAL) {      /* DIAL command */
     561:     char *s2;
     562:     if (dialdir && *dialdir)
     563:       s2 = "Number to dial or entry from dial directory";
     564:     else
     565:       s2 = "Number to dial";
     566:     if ((x = cmtxt(s2,"",&s,xxstring)) < 0)
     567:       return(x);
     568:     if (s == NULL || (int)strlen(s) == 0) {
     569:         printf("?You must specify a number to dial\n");
     570:         return(-9);
     571:     }
     572:     if (dialfd) {           /* Have dialing directory? */
     573:         if (s2 = ludial(s,dialfd))  /* Look up in dialing directory */
     574:           s = s2;           /* Make substitution if found */
     575:     }
     576:     if (dialnum) free(dialnum); /* Make copy for REDIAL */
     577:     dialnum = malloc((int)strlen(s) + 1);
     578:     if (dialnum) strcpy(dialnum,s);
     579:     } else return(-2);
     580: #ifdef VMS
     581:     conres();               /* So Ctrl-C/Y will work */
     582: #endif /* VMS */
     583:     success = ckdial(s);        /* Try to dial */
     584: #ifdef OS2
     585:     ttres();
     586: #endif /* OS2 */
     587: #ifdef VMS
     588:     concb((char)escape);        /* Back to command parsing mode */
     589: #endif /* VMS */
     590:     return(success);
     591: }
     592: #endif /* NODIAL */
     593:
     594: #ifndef MAC
     595: int                 /* Do the DIRECTORY command */
     596: dodir() {
     597:     char *dc;
     598: #ifdef VMS
     599:     if ((x = cmtxt("Directory/file specification","",&s,xxstring)) < 0)
     600:       return(x);
     601:     /* now do this the same as a shell command - helps with LAT  */
     602:     conres();               /* make console normal */
     603:     lp = line;
     604:     if (!(dc = getenv("CK_DIR"))) dc = DIRCMD;
     605:     sprintf(lp,"%s %s",dc,s);
     606:     debug(F110,"Directory string: ", line, 0);
     607:     xsystem(lp);
     608:     return(success = 0);
     609: #else
     610: #ifdef AMIGA
     611:     if ((x = cmtxt("Directory/file specification","",&s,xxstring)) < 0)
     612:       return(x);
     613: #else
     614: #ifdef datageneral
     615:     if ((x = cmtxt("Directory/file specification","+",&s,xxstring)) < 0)
     616:       return(x);
     617: #else /* General Case */
     618:     if ((x = cmdir("Directory/file specification","",&s,xxstring)) < 0)
     619:       if (x != -3) return(x);
     620:     strcpy(tmpbuf,s);
     621:     if ((y = cmcfm()) < 0) return(y);
     622:     s = tmpbuf;
     623: #endif /* datageneral */
     624: #endif /* AMIGA */
     625:     /* General case again */
     626:     lp = line;
     627:     if (!(dc = getenv("CK_DIR"))) dc = DIRCMD;
     628:     sprintf(lp,"%s %s",dc,s);
     629:     xsystem(line);
     630:     return(success = 1);        /* who cares... */
     631: #endif /* VMS */
     632: }
     633: #endif /* MAC */
     634:
     635: #ifndef NOFRILLS
     636: /* Do the ENABLE and DISABLE commands */
     637:
     638: int
     639: doenable(cx,x) int cx, x; {
     640:     y = ((cx == XXENA) ? 1 : 0);
     641:     switch (x) {
     642:       case EN_ALL:
     643:     en_cwd = en_del = en_dir = en_fin = en_get = y;
     644:     en_sen = en_set = en_spa = en_typ = en_who = y;
     645: #ifndef datageneral
     646:         en_bye = y;
     647: #endif /* datageneral */
     648:
     649: #ifndef NOPUSH
     650:     en_hos = y;
     651: #endif /* NOPUSH */
     652:     break;
     653:       case EN_BYE:
     654: #ifndef datageneral
     655: /*
     656:   In Data General AOS/VS Kermit can't log out its superior process.
     657: */
     658:         en_bye = y;
     659: #endif /* datageneral */
     660:     break;
     661:       case EN_CWD:
     662:     en_cwd = y;
     663:     break;
     664:       case EN_DEL:
     665:     en_del = y;
     666:     break;
     667:       case EN_DIR:
     668:     en_dir = y;
     669:     break;
     670:       case EN_FIN:
     671:     en_fin = y;
     672:     break;
     673:       case EN_GET:
     674:     en_get = y;
     675:     break;
     676: #ifndef NOPUSH
     677:       case EN_HOS:
     678:     en_hos = y;
     679:     break;
     680: #endif /* NOPUSH */
     681:       case EN_SEN:
     682:     en_sen = y;
     683:     break;
     684:       case EN_SET:
     685:     en_set = y;
     686:     break;
     687:       case EN_SPA:
     688:     en_spa = y;
     689:     break;
     690:       case EN_TYP:
     691:     en_typ = y;
     692:     break;
     693:       case EN_WHO:
     694:     en_who = y;
     695:     break;
     696:       default:
     697:     return(-2);
     698:     }
     699:     return(1);
     700: }
     701: #endif /* NOFRILLS */
     702:
     703: #ifndef NOFRILLS
     704: int
     705: dodel() {               /* DELETE */
     706:     long zl;
     707:     if ((x = cmifi("File(s) to delete","",&s,&y,xxstring)) < 0) {
     708:     if (x == -3) {
     709:         printf("?A file specification is required\n");
     710:         return(-9);
     711:     } else return(x);
     712:     }
     713: #ifdef MAC
     714:     strcpy(line,s);
     715: #else
     716:     strncpy(tmpbuf,s,50);       /* Make a safe copy of the name. */
     717:     debug(F110,"xxdel tmpbuf",s,0);
     718:     sprintf(line,"%s %s",DELCMD,s); /* Construct the system command. */
     719: #endif /* MAC */
     720:     debug(F110,"xxdel line",line,0);
     721:     if ((y = cmcfm()) < 0) return(y);   /* Confirm the user's command. */
     722: #ifdef VMS
     723:     conres();
     724: #endif /* VMS */
     725: #ifdef MAC
     726:     s = line;
     727:     success = (zdelet(line) == 0);
     728: #else
     729:     s = tmpbuf;
     730:     xsystem(line);          /* Let the system do it. */
     731:     zl = zchki(tmpbuf);
     732:     success = (zl == -1L);
     733: #endif /* MAC */
     734:     if (msgflg)
     735:       printf("%s - %sdeleted\n",s, success ? "" : "not ");
     736:     return(success);
     737: }
     738: #endif /* NOFRILLS */
     739:
     740: #ifndef NOSPL               /* The ELSE command */
     741: int
     742: doelse() {
     743:     if (!ifcmd[cmdlvl]) {
     744:     printf("?ELSE doesn't follow IF\n");
     745:     return(-2);
     746:     }
     747: #ifdef COMMENT
     748: /*
     749:   Wrong.  This prevents IF..ELSE IF...ELSE IF...ELSE IF...ELSE...
     750:   from working.
     751: */
     752:     ifcmd[cmdlvl] = 0;
     753: #endif /* COMMENT */
     754:     if (!iftest[cmdlvl]) {      /* If IF was false do ELSE part */
     755:     if (maclvl > -1) {      /* In macro, */
     756:         pushcmd();          /* save rest of command. */
     757:     } else if (tlevel > -1) {   /* In take file, */
     758:         pushcmd();          /* save rest of command. */
     759:     } else {            /* If interactive, */
     760:         cmini(ckxech);      /* just start a new command */
     761:         printf("\n");       /* (like in MS-DOS Kermit) */
     762:         if (pflag) prompt(xxstring);
     763:     }
     764:     } else {                /* Condition is false */
     765:     if ((y = cmtxt("command to be ignored","",&s,NULL)) < 0)
     766:       return(y);            /* Gobble up rest of line */
     767:     }
     768:     return(0);
     769: }
     770: #endif /* NOSPL */
     771:
     772: #ifndef NOSPL
     773: int
     774: dofor() {               /* The FOR command. */
     775:     int fx, fy, fz;         /* loop variables */
     776:     char *ap;               /* macro argument pointer */
     777:
     778:     if ((y = cmfld("Variable name","",&s,NULL)) < 0) { /* Get variable name */
     779:     if (y == -3) {
     780:         printf("?Variable name required\n");
     781:         return(-9);
     782:     } else return(y);
     783:     }
     784:     if ((y = parsevar(s,&x,&z)) < 0)    /* Check it. */
     785:       return(y);
     786:
     787:     lp = line;              /* Build a copy of the command */
     788:     strcpy(lp,"_forx ");
     789:     lp += (int)strlen(line);        /* "_for" macro. */
     790:     ap = lp;                /* Save pointer to macro args. */
     791:
     792:     if (*s == CMDQ) s++;        /* Skip past backslash if any. */
     793:     while (*lp++ = *s++) ;      /* copy it */
     794:     lp--; *lp++ = SP;           /* add a space */
     795:
     796:     if ((y = cmnum("initial value","",10,&fx,xxstring)) < 0) {
     797:     if (y == -3) return(-2);
     798:     else return(y);
     799:     }
     800:     s = atmbuf;             /* Copy the atom buffer */
     801:     if ((int)strlen(s) < 1) goto badfor;
     802:     while (*lp++ = *s++) ;      /* (what they actually typed) */
     803:     lp--; *lp++ = SP;
     804:
     805:     if ((y = cmnum("final value","",10,&fy,xxstring)) < 0) {
     806:     if (y == -3) return(-2);
     807:     else return(y);
     808:     }
     809:     s = atmbuf;             /* Same deal */
     810:     if ((int)strlen(s) < 1) goto badfor;
     811:     while (*lp++ = *s++) ;
     812:     lp--; *lp++ = SP;
     813:
     814:     if ((y = cmnum("increment","1",10,&fz,xxstring)) < 0) {
     815:     if (y == -3) return(-2);
     816:     else return(y);
     817:     }
     818:     sprintf(tmpbuf,"%d ",fz);
     819:     s = atmbuf;             /* same deal */
     820:     if ((int)strlen(s) < 1) goto badfor;
     821:     while (*lp++ = *s++) ;
     822:     lp--; *lp++ = SP;
     823:
     824:     /* Insert the appropriate comparison operator */
     825:     if (fz < 0)
     826:       *lp++ = '<';
     827:     else
     828:       *lp++ = '>';
     829:     *lp++ = SP;
     830:
     831:     if ((y = cmtxt("Command to execute","",&s,NULL)) < 0) return(y);
     832:     if ((int)strlen(s) < 1) return(-2);
     833:
     834:     if (litcmd(&s,&lp) < 0) {
     835:     printf("?Unbalanced brackets\n");
     836:     return(0);
     837:     }
     838:     if (fz == 0) {
     839:     printf("?Zero increment not allowed\n");
     840:     return(0);
     841:     }
     842:     x = mlook(mactab,"_forx",nmac); /* Look up FOR macro definition */
     843:     if (x < 0) {            /* Not there? */
     844:     addmmac("_forx",for_def);   /* Put it back. */
     845:     if ((x = mlook(mactab,"_forx",nmac)) < 0) { /* Look it up again. */
     846:         printf("?FOR macro definition gone!\n"); /* Shouldn't happen. */
     847:         return(success = 0);
     848:     }
     849:     }
     850:     debug(F110,"FOR command",line,0);
     851:     return(success = dodo(x,ap));   /* Execute the FOR macro. */
     852:
     853: badfor: printf("?Incomplete FOR command\n");
     854:     return(-2);
     855: }
     856: #endif /* NOSPL */
     857:
     858: #ifndef NOFRILLS
     859: /* Do the BUG command */
     860:
     861: int
     862: dobug() {
     863:     printf("\n%s,%s\n Numeric: %ld",versio,ckxsys,vernum);
     864:     if (verwho) printf("-%d",verwho);
     865:     printf("\nTo report C-Kermit bugs, send e-mail to:\n");
     866:     printf(" Info-Kermit@columbia.edu (Internet)\n");
     867:     printf(" KERMIT@CUVMA (EARN/BITNET)\n");
     868:     printf(" ...!uunet!columbia.edu!info-kermit (Usenet)\n");
     869:     printf("Or write to:\n Kermit Development\n Columbia University\n");
     870:     printf(" Center for Computing Activities\n 612 W 115 Street\n");
     871:     printf(" New York, NY 10025 USA\nOr call:\n (212) 854-5126 (USA)\n\n");
     872: #ifndef NOSHOW
     873: #ifndef NOFRILLS
     874:     printf(
     875: "Before reporting problems, please use the SHOW VERSION and SHOW FEATURES\n");
     876:     printf(
     877: "commands to get detailed program version and configuration information.\n\n");
     878: #endif /* NOFRILLS */
     879: #endif /* NOSHOW */
     880:     return(1);
     881: }
     882: #endif /* NOFRILLS */
     883:
     884: #ifndef NOSPL
     885: int
     886: dopaus(cx) int cx; {
     887:     /* Both should take not only secs but also hh:mm:ss as argument. */
     888:     if (cx == XXWAI)
     889:       y = cmnum("seconds to wait","1",10,&x,xxstring);
     890:     else if (cx == XXPAU)
     891:       y = cmnum("seconds to pause","1",10,&x,xxstring);
     892:     else
     893:       y = cmnum("milliseconds to sleep","100",10,&x,xxstring);
     894:     if (y < 0) return(y);
     895:     if (x < 0) x = 0;
     896:     switch (cx) {
     897:       case XXPAU:           /* PAUSE */
     898:       case XXMSL:           /* MSLEEP */
     899:     if ((y = cmcfm()) < 0) return(y);
     900:     break;
     901:       case XXWAI:           /* WAIT */
     902:     z = 0;              /* Modem signal mask */
     903:     while (1) {         /* Read zero or more signal names */
     904:         y = cmkey(mstab,nms,"modem signal","",xxstring);
     905:         if (y == -3) break;     /* -3 means they typed CR */
     906:         if (y < 0) return(y);   /* Other negatives are errors */
     907:         z |= y;         /* OR the bit into the signal mask */
     908:     }
     909:     break;
     910:
     911:       default:              /* Shouldn't happen */
     912:     return(-2);
     913:     }
     914:
     915: /* Command is entered, now do it. */
     916:
     917:     if (cx == XXMSL) {          /* Millisecond sleep */
     918:     msleep(x);
     919:     return(success = 1);
     920:     }
     921:     while (x--) {           /* Sleep loop */
     922:     int mdmsig;
     923:     if (y = conchk()) {     /* Did they type something? */
     924:         while (y--) coninc(0);  /* Yes, gobble it up */
     925:         break;          /* And quit PAUSing or WAITing */
     926:     }
     927:     if (cx == XXWAI && z != 0) {
     928:         mdmsig = ttgmdm();
     929:         if (mdmsig < 0) return(success = 0);
     930:         if ((mdmsig & z) == z) return(success = 1);
     931:     }
     932:     sleep(1);           /* No interrupt, sleep one second */
     933:     }
     934:     if (cx == XXWAI) success = 0;
     935:     else success = (x == -1);       /* Set SUCCESS/FAILURE for PAUSE. */
     936:     return(0);
     937: }
     938: #endif /* NOSPL */
     939:
     940:
     941: #ifndef NOFRILLS
     942: int
     943: dorenam() {
     944:     if ((x = cmifi("File to rename","",&s,&y,xxstring)) < 0) {
     945:     if (x == -3) {
     946:         printf("?Name of existing file required\n");
     947:         return(-9);
     948:     } else return(x);
     949:     }
     950:     if (y) {                /* No wildcards allowed */
     951:     printf("\n?Please specify a single file\n");
     952:     return(-9);
     953:     }
     954:     strcpy(line,s);         /* Make a safe copy of the old name */
     955:     p = line + (int)strlen(line) + 2;   /* Place for new name */
     956:     if ((x = cmofi("New name","",&s,xxstring)) < 0) { /* Get new name */
     957:     if (x == -3) {
     958:         printf("?New name for file required\n");
     959:         return(-9);
     960:     } else return(x);
     961:     }
     962:     strcpy(p,s);            /* Make a safe copy of the new name */
     963:     if ((y = cmcfm()) < 0) return(y);
     964: #ifdef VMS
     965:     conres();               /* Let Ctrl-C work. */
     966: #endif /* VMS */
     967:     return(zrename(line,p));
     968: }
     969: #endif /* NOFRILLS */
     970:
     971:
     972: #ifndef NOSPL
     973:
     974: /* Do the RETURN command */
     975:
     976: int
     977: doreturn(s) char *s; {
     978:     int x; char *p;
     979:     if (maclvl < 0) {
     980:     printf("\n?Can't return from level %d\n",maclvl);
     981:     return(success = 0);
     982:     }
     983:     lp = line;              /* Expand return value now */
     984:     x = LINBUFSIZ-1;
     985:     if (xxstring(s,&lp,&x) > -1) {
     986:     s = line;
     987:     }
     988:     x = (int)strlen(s);         /* Is there a return value? */
     989:     if (x) {                /* Yes */
     990:     p = malloc(x+2);        /* Allocate a place to keep it */
     991:     if (p) {            /* Did we get a place? */
     992:         strcpy(p, s);       /* Yes, copy the string into it. */
     993:         mrval[maclvl] = p;      /* Make return value point to it. */
     994:     } else {            /* No, could not get space. */
     995:         mrval[maclvl] = NULL;   /* Return null pointer. */
     996:         x = 0;          /* Set failure return code. */
     997:     }
     998:     } else mrval[maclvl] = NULL;    /* Blank return code */
     999: #undef FORRET
    1000: /*
    1001:   If we are in a FOR, WHILE, or XIF command list, also copy the return value
    1002:   two levels up.  (But this doesn't work, so forget it.)
    1003: */
    1004: #ifdef FORRET
    1005:     if (maclvl > 1) {
    1006:     if (!strncmp(m_arg[maclvl][0],"_for",4) ||
    1007:         !strncmp(m_arg[maclvl][0],"_whi",4) ||
    1008:         !strncmp(m_arg[maclvl][0],"_xif",4)) {
    1009:         mrval[maclvl-2] = p;
    1010:     }
    1011:     }
    1012: #endif /* FORRET */
    1013:     popclvl();              /* Pop command level */
    1014:
    1015: #ifdef DEBUG
    1016:     if (mrval[maclvl+1])
    1017:       debug(F111,"&return",mrval[maclvl+1],maclvl);
    1018:     else debug(F111,"&return","NULL",maclvl);
    1019: #endif /* DEBUG */
    1020:     return(success = x ? 1 : 0);    /* Return status code */
    1021: }
    1022: #endif /* NOSPL */
    1023:
    1024: #ifndef NOSPL
    1025: /* Do the OPEN command */
    1026:
    1027: int
    1028: doopen()  {             /* OPEN { append, read, write } */
    1029:     int x, y, z; char *s;
    1030:     static struct filinfo fcb;      /* (must be static) */
    1031:     if ((x = cmkey(opntab,nopn,"mode","",xxstring)) < 0) {
    1032:     if (x == -3) {
    1033:         printf("?Mode required\n");
    1034:         return(-9);
    1035:     } else return(x);
    1036:     }
    1037:     switch (x) {
    1038:       case XYFZ_O:          /* Old file (READ) */
    1039:     if (chkfn(ZRFILE) > 0) {
    1040:         printf("?Read file already open\n");
    1041:         return(-2);
    1042:     }
    1043:     if ((z = cmifi("File to read","",&s,&y,xxstring)) < 0) {
    1044:         if (z == -3) {
    1045:         printf("?Input filename required\n");
    1046:         return(-9);
    1047:         } else return(z);
    1048:     }
    1049:     if (y) {                /* No wildcards allowed */
    1050:         printf("\n?Please specify a single file\n");
    1051:         return(-2);
    1052:     }
    1053:     strcpy(line,s);
    1054:     if ((int)strlen(line) < 1) return(-2);
    1055:     if ((y = cmcfm()) < 0) return(y);
    1056:     return(success = zopeni(ZRFILE,line));
    1057:
    1058: #ifndef MAC
    1059: #ifndef NOPUSH
    1060:       case XYFZ_Y:          /* Pipe/Process (READ) */
    1061:     if (chkfn(ZRFILE) > 0) {
    1062:         printf("?Read file already open\n");
    1063:         return(-2);
    1064:     }
    1065:         if ((y = cmtxt("System command to read from","",&s,xxstring)) < 0) {
    1066:         if (y == -3) {
    1067:         printf("?Command name required\n");
    1068:         return(-9);
    1069:         } else return(y);
    1070:     }
    1071:     strcpy(line,s);
    1072:     if ((int)strlen(line) < 1) return(-2);
    1073:     if ((y = cmcfm()) < 0) return(y);
    1074:     return(success = zxcmd(ZRFILE,line));
    1075:
    1076:       case XYFZ_X:          /* Write to pipe */
    1077:     if (chkfn(ZWFILE) > 0) {
    1078:         printf("?Write file already open\n");
    1079:         return(-2);
    1080:     }
    1081:         if ((y = cmtxt("System command to write to","",&s,xxstring)) < 0) {
    1082:         if (y == -3) {
    1083:         printf("?Command name required\n");
    1084:         return(-9);
    1085:         } else return(y);
    1086:     }
    1087:     strcpy(line,s);
    1088:     if ((int)strlen(line) < 1) return(-2);
    1089:     if ((y = cmcfm()) < 0) return(y);
    1090:     success = zxcmd(ZWFILE,line);
    1091:     if (!success && msgflg)
    1092:       printf("Can't open process for writing: %s\n",line);
    1093:     return(success);
    1094: #endif /* NOPUSH */
    1095: #endif /* MAC */
    1096:
    1097:       case XYFZ_N:          /* New file (WRITE) */
    1098:       case XYFZ_A:          /* (APPEND) */
    1099:     if ((z = cmofi("Name of local file to create","",&s,xxstring)) < 0) {
    1100:         if (z == -3) {
    1101:         printf("?Filename required\n");
    1102:         return(-9);
    1103:         } else return(z);
    1104:     }
    1105:     if (chkfn(ZWFILE) > 0) {
    1106:         printf("?Write/Append file already open\n");
    1107:         return(-2);
    1108:     }
    1109:         fcb.bs = fcb.cs = fcb.rl = fcb.fmt = fcb.org = fcb.cc = fcb.typ = 0;
    1110:     fcb.lblopts = 0;
    1111:     fcb.dsp = x;            /* Create or Append */
    1112:     strcpy(line,s);
    1113:     if ((int)strlen(line) < 1) return(-2);
    1114:     if ((y = cmcfm()) < 0) return(y);
    1115:     return(success = zopeno(ZWFILE,line,NULL,&fcb));
    1116:
    1117:       default:
    1118:     printf("?Not implemented");
    1119:     return(-2);
    1120:     }
    1121: }
    1122: #endif /* NOSPL */
    1123:
    1124: /* Finish parsing and do the GET command */
    1125:
    1126: int
    1127: doget() {
    1128:     int x;
    1129:     char *cbp;
    1130:
    1131:     cmarg2 = "";            /* Initialize as-name to nothing */
    1132:     x = 0;
    1133: #ifdef NOFRILLS
    1134:     if (*cmarg == NUL) {
    1135:     printf("?Remote filespec required\n");
    1136:     return(-3);
    1137:     }
    1138: #else
    1139: /*
    1140:   If remote file name omitted, get foreign and local names separately.
    1141:   But multine GET is allowed only if NOFRILLS is not defined.
    1142: */
    1143:     if (*cmarg == NUL) {
    1144:
    1145:     if (tlevel > -1
    1146: #ifndef NOSPL
    1147:         && cmdstk[cmdlvl].src == CMD_TF
    1148: #endif /* NOSPL */
    1149:         ) {
    1150:
    1151: /* Input is from a command file. */
    1152:
    1153:         /* Read 2nd line of GET command */
    1154:
    1155:         if (getnct(cmdbuf,CMDBL) < 0) {
    1156:         printf("Command file ends prematurely in multiline GET\n");
    1157:         popclvl();
    1158:         return(-9);
    1159:         }
    1160:         cmres();            /* Parse it */
    1161:         if ((x = cmtxt("Oofa","",&s,xxstring)) < 0)
    1162:           return(x);
    1163:         if (*s == '{') {        /* Strip enclosing braces */
    1164:         x = (int)strlen(s);
    1165:         if (s[x-1] == '}') {
    1166:             s[x-1] = NUL;
    1167:             s++;
    1168:         }
    1169:         }
    1170:         strcpy(line,s);     /* Make a safe copy */
    1171:         cmarg = line;       /* Point to remote filename */
    1172:         if (*cmarg == NUL) {    /* Make sure there is one */
    1173:         printf("Remote filename missing in multiline GET\n");
    1174:         return(-9);
    1175:         }
    1176:         lp = line + strlen(line) + 1; /* Place for as-name */
    1177:
    1178:         /* And third line... */
    1179:
    1180:         cmarg2 = "";        /* Assume no as-name */
    1181:         if (getnct(cmdbuf,CMDBL) < 0) { /* Get next line */
    1182:         popclvl();      /* There isn't one. */
    1183:         } else {            /* There is... */
    1184:         if (*cmdbuf >= ' ') {   /* Parse as output filename */
    1185:             cmres();
    1186:             if ((x = cmofi("Mupeen",cmarg,&s,xxstring)) < 0)
    1187:               return(x);
    1188:             strcpy(lp,s);   /* Make a safe copy */
    1189:             cmarg2 = lp;    /* Point as-name pointer at it */
    1190:         }
    1191:         }
    1192:             x = 0;          /* Return code OK */
    1193:
    1194: #ifndef NOSPL
    1195: /* Reading commands from a macro definition */
    1196:
    1197:     } else if (cmdlvl > 0 && cmdstk[cmdlvl].src == CMD_MD) {
    1198:
    1199:         /* Read second line of GET command */
    1200:
    1201:         cbp = cmdbuf;
    1202:         if (getncm(cbp,CMDBL) < 0) {
    1203:         printf("Macro definition ends prematurely in multiline GET\n");
    1204:         return(-9);
    1205:         }
    1206:         cmres();
    1207:         if ((x = cmtxt("Oofa","",&s,xxstring)) < 0) return(x);
    1208:         if (*s == NUL) {        /* Make sure we got something */
    1209:         printf("Remote filename missing in multiline GET\n");
    1210:         return(-9);
    1211:         }
    1212:         if (*s == '{') {        /* Strip enclosing braces */
    1213:         x = (int)strlen(s);
    1214:         if (s[x-1] == '}') {
    1215:             s[x-1] = NUL;
    1216:             s++;
    1217:         }
    1218:         }
    1219:         strcpy(line,s);     /* Copy filename to safe place */
    1220:         cmarg = line;       /* Point to it */
    1221:         x = strlen(line);       /* Get its length */
    1222:         lp = line + x + 1;      /* Where to put the next bit */
    1223:         y = LINBUFSIZ - x - 1;  /* Room left for next bit */
    1224:
    1225:         /* And third line... */
    1226:
    1227:         cmarg2 = "";        /* Assume no as-name */
    1228:         if (getncm(lp,y) > -1 && *lp >= ' ') { /* Read next line */
    1229:         x = strlen(lp);
    1230:         if (lp[x-1] == CR) lp[x-1] = NUL; /* Remove CR */
    1231:         cbp = cmdbuf;       /* Interpret the line */
    1232:         *cbp = NUL;     /* ... */
    1233:         y = CMDBL;      /* into the command buffer */
    1234:         xxstring(lp,&cbp,&y);
    1235:         if (*cmdbuf) {      /* If we have something */
    1236:             cmres();        /* parse it as an output filename */
    1237:             strcat(cmdbuf," ");
    1238:             if ((x = cmofi("Mupeen","",&s,NULL)) < 0)
    1239:               return(x);
    1240:             strcpy(lp,s);   /* Copy the name to safe place */
    1241:             cmarg2 = lp;    /* and make as-name pointer */
    1242:         }
    1243:         }
    1244:             x = 0;          /* Return code OK */
    1245: #endif /* NOSPL */
    1246:         } else {            /* Input is from terminal */
    1247:
    1248:         cmsavp(psave,80);
    1249:         cmsetp(" Remote file specification: "); /* Make new one */
    1250:         cmini(ckxech);
    1251:         x = -1;
    1252:         if (pflag) prompt(xxstring);
    1253:         while (x == -1) {       /* Prompt till they answer */
    1254:             x = cmtxt("Name of remote file(s)","",&cmarg,xxstring);
    1255:         debug(F111," cmtxt",cmarg,x);
    1256:         }
    1257:         if (x < 0) {
    1258:         cmsetp(psave);
    1259:         return(x);
    1260:         }
    1261:         if (*cmarg == NUL) {    /* If user types a bare CR, */
    1262:         printf("(cancelled)\n"); /* Forget about this. */
    1263:             cmsetp(psave);      /* Restore old prompt, */
    1264:         return(0);      /* and return. */
    1265:         }
    1266:         if (*cmarg == '{') {    /* Strip enclosing braces */
    1267:         x = (int)strlen(cmarg);
    1268:         if (cmarg[x-1] == '}') {
    1269:             cmarg[x-1] = NUL;
    1270:             cmarg++;
    1271:         }
    1272:         }
    1273:         strcpy(line,cmarg);     /* Make a safe copy */
    1274:         cmarg = line;
    1275:         cmsetp(" Local name to store it under: "); /* New prompt */
    1276:         cmini(ckxech);
    1277:         x = -1;
    1278:         if (pflag) prompt(xxstring);
    1279:         while (x == -1) {       /* Again, parse till answered */
    1280:             x = cmofi("Local file name","",&cmarg2,xxstring);
    1281:         }
    1282:         if (x < 0) {        /* Parse error */
    1283:         if (x == -3) {      /* CR = cancel */
    1284:             printf("(cancelled)\n"); /* Print message */
    1285:             x = 0;      /* Avoid further messages */
    1286:         }
    1287:         cmsetp(psave);      /* Restore prompt */
    1288:         return(x);
    1289:         }
    1290:         x = -1;         /* Get confirmation. */
    1291:         while (x == -1) x = cmcfm();
    1292:         cmsetp(psave);      /* Restore old prompt. */
    1293:         }
    1294:     }
    1295: #endif /* NOFRILLS */
    1296:     if (x == 0) {           /* Good return from cmtxt or cmcfm, */
    1297:     debug(F110,"xxget cmarg",cmarg,0);
    1298:     strncpy(fspec,cmarg,FSPECL);
    1299:     debug(F111,"xxget fspec",fspec,FSPECL);
    1300:     sstate = 'r';           /* Set start state. */
    1301:     if (local) {
    1302:         displa = 1;
    1303:         ttflui();
    1304:     }
    1305:     }
    1306:     return(x);
    1307: }
    1308:
    1309: #ifndef NOSPL
    1310:
    1311: int
    1312: dogta(cx) int cx; {
    1313:     int i; char c; char mbuf[4]; char *p;
    1314:
    1315:     if ((y = cmcfm()) < 0)
    1316:       return(y);
    1317:     if (cx == XXGTA)
    1318:       debug(F101,"_getargs maclvl","",maclvl);
    1319:     else if (cx == XXPTA)
    1320:       debug(F101,"_putargs maclvl","",maclvl);
    1321:     else
    1322:       return(-2);
    1323:     if (maclvl < 1)
    1324:       return(success = 0);
    1325:
    1326: #ifdef COMMENT
    1327: #ifdef NEXT
    1328: /*
    1329:   For some reason, this routine makes Kermit core dump on the next after
    1330:   it returns to docmd().  It works fine, as the debug log shows, but when
    1331:   docmd returns, it gets a memory fault.
    1332: */
    1333:     else return(1);
    1334: #endif /* NEXT */
    1335: #endif /* COMMENT */
    1336:
    1337:     mbuf[0] = '%'; mbuf[1] = '0'; mbuf[2] = '\0'; /* Argument name buf */
    1338:     for (i = 0; i < 10; i++) {      /* For all args */
    1339:     c = (char) i + '0';     /* Make name */
    1340:     mbuf[1] = c;            /* Insert digit */
    1341:     if (cx == XXGTA) {      /* Get arg from level-minus-2 */
    1342:         if (maclvl == 1) p = g_var[c]; /* If at level 1 use globals 0..9 */
    1343:         else p = m_arg[maclvl-2][i]; /* Otherwise they're on the stack */
    1344:         if (!p) {
    1345:         debug(F111,"_getarg p","(null pointer)",i);
    1346:         } else debug(F111,"_getarg p",p,i);
    1347:         addmac(mbuf,p);
    1348:     } else if (cx == XXPTA) {   /* Put args level+2 */
    1349: #ifndef MAC
    1350:         connoi();           /* Turn off interrupts. */
    1351: #endif /* MAC */
    1352:         maclvl -= 2;        /* This is gross.. */
    1353:         p = m_arg[maclvl+2][i];
    1354:         if (p)
    1355:           debug(F111,"_putarg m_arg[maclvl+2][i]",p,i);
    1356:         else
    1357:           debug(F111,"_putarg m_arg[maclvl+2][i]","(null pointer)",i);
    1358:         addmac(mbuf,m_arg[maclvl+2][i]);
    1359:         maclvl += 2;
    1360: #ifndef MAC
    1361:         conint(trap,stptrap);   /* Restore interrupts */
    1362: #endif /* MAC */
    1363:     } else return(success = 0);
    1364:     }
    1365:     debug(F101,"_get/putarg exit","",i);
    1366:     debug(F101,"_get/putarg exit maclvl","",maclvl);
    1367:     return(success = 1);
    1368: }
    1369: #endif /* NOSPL */
    1370:
    1371:
    1372: #ifndef NOSPL
    1373: /* Do the GOTO command */
    1374:
    1375: int
    1376: dogoto(s) char *s; {
    1377:     int i, j, x, y;
    1378:     char tmplbl[50], *lp;
    1379:
    1380:     debug(F101,"goto cmdlvl","",cmdlvl);
    1381:     debug(F101,"goto maclvl","",maclvl);
    1382:     debug(F101,"goto tlevel","",tlevel);
    1383:     debug(F110,"goto before conversion",s,0);
    1384:     y = (int)strlen(s);
    1385:     if (*s != ':') {            /* If the label mentioned */
    1386:     for (i = y; i > 0; i--) {   /* does not begin with a colon, */
    1387:         s[i] = s[i-1];      /* then insert one. */
    1388:     }               /* Also, convert to lowercase. */
    1389:     s[0] = ':';
    1390:     s[++y] = '\0';
    1391:     }
    1392:     debug(F111,"goto after conversion",s,y);
    1393:     if (s[1] == '.' || s[1] == SP || s[1] == NUL) {
    1394:     printf("?Bad label syntax - '%s'\n",s);
    1395:     return(success = 0);
    1396:     }
    1397:     if (cmdlvl == 0) {
    1398:     printf("?Sorry, GOTO only works in a command file or macro\n");
    1399:     return(success = 0);
    1400:     }
    1401:     while (cmdlvl > 0) {        /* Only works inside macros & files */
    1402:     if (cmdstk[cmdlvl].src == CMD_MD) { /* GOTO inside macro */
    1403:         int i, m, flag;
    1404:         char *xp, *tp;
    1405:
    1406:         lp = macx[maclvl];
    1407:         m = (int)strlen(lp) - y + 1;
    1408:         debug(F111,"goto in macro",lp,m);
    1409:
    1410:         flag = 1;           /* flag for valid label position */
    1411:         for (i = 0; i < m; i++,lp++) { /* search for label in macro body */
    1412:         if (*lp == ',') {   /* Really should also watch out */
    1413:             flag = 1;       /* for braces here...  Commas in */
    1414:             continue;       /* in braces are not really commas */
    1415:         }
    1416:         if (flag) {     /* If in valid label position */
    1417:             if (*lp == SP)  /* eat leading spaces */
    1418:               continue;
    1419:             if (*lp != ':') {   /* Look for label introducer */
    1420:             flag = 0;   /* this isn't it */
    1421:             continue;   /* keep looking */
    1422:             }
    1423:         }
    1424:         if (!flag)      /* We don't have a label */
    1425:           continue;     /*  so keep looking... */
    1426:         xp = lp; tp = tmplbl;   /* Copy the label from the macro */
    1427:         j = 0;          /* to make it null-terminated */
    1428:         while (*tp = *xp) {
    1429:             if (j++ > 50) break;  /* j = length of word from macro */
    1430:             if (*tp < 33 || *tp == ',') /* Look for end of word */
    1431:               break;
    1432:             else tp++, xp++;    /* Next character */
    1433:         }
    1434:         *tp = '\0';     /* In case we stopped early */
    1435:         /* Now do caseless string comparison, using longest length */
    1436:         debug(F111,"macro GOTO label",s,y);
    1437:         debug(F111,"macro target label",tmplbl,j);
    1438:         if (!xxstrcmp(s,tmplbl,(y > j) ? y : j))
    1439:           break;
    1440:         else flag = 0;
    1441:         }
    1442:         if (i == m) {       /* didn't find the label */
    1443:         debug(F101,"goto failed at cmdlvl","",cmdlvl);
    1444:         if (!popclvl()) {   /* pop up to next higher level */
    1445:             printf("?Label '%s' not found\n",s); /* if none */
    1446:             return(0);      /* quit */
    1447:         } else continue;    /* otherwise look again */
    1448:         }
    1449:         debug(F110,"goto found macro label",lp,0);
    1450:         macp[maclvl] = lp;      /* set macro buffer pointer */
    1451:         return(1);
    1452:     } else if (cmdstk[cmdlvl].src == CMD_TF) {
    1453:         x = 0;          /* GOTO issued in take file */
    1454:         rewind(tfile[tlevel]);  /* Search file from beginning */
    1455:         while (! feof(tfile[tlevel])) {
    1456:         if (fgets(line,LINBUFSIZ,tfile[tlevel]) == NULL) /* Get line */
    1457:           break;        /* If no more, done, label not found */
    1458:         lp = line;      /* Got line */
    1459:         while (*lp == SP || *lp == HT)
    1460:           lp++;         /* Strip leading whitespace */
    1461:         if (*lp != ':') continue; /* Check for label introducer */
    1462:         tp = lp;        /* Get end of word */
    1463:         j = 0;
    1464:         while (*tp) {       /* And null-terminate it */
    1465:             if (*tp < 33) {
    1466:             *tp = '\0';
    1467:             break;
    1468:             } else tp++, j++;
    1469:         }
    1470:         if (!xxstrcmp(lp,s,(y > j) ? y : j)) { /* Caseless compare */
    1471:             x = 1;      /* Got it */
    1472:             break;      /* done. */
    1473:         }
    1474:         }
    1475:         if (x == 0) {       /* If not found, print message */
    1476:         debug(F101,"goto failed at cmdlvl","",cmdlvl);
    1477:         if (!popclvl()) {   /* pop up to next higher level */
    1478:             printf("?Label '%s' not found\n",s);    /* if none */
    1479:             return(0);      /* quit */
    1480:         } else continue;    /* otherwise look again */
    1481:         }
    1482:         return(x);          /* Send back return code */
    1483:     }
    1484:     }
    1485:     printf("?Stack problem in GOTO %s\n",s); /* Shouldn't see this */
    1486:     return(0);
    1487: }
    1488: #endif /* NOSPL */
    1489:
    1490: #ifndef NOSPL
    1491: /* Finish parsing and do the IF, XIF, and WHILE commands */
    1492:
    1493: int
    1494: doif(cx) int cx; {
    1495:     int x, y, z; char *s, *p;
    1496:
    1497:     not = 0;                /* Flag for whether "NOT" was seen */
    1498:     z = 0;              /* Initial IF condition */
    1499:     ifargs = 0;             /* Count of IF condition words */
    1500:
    1501: ifagain:
    1502:     if ((ifc = cmkey(iftab,nif,"","",xxstring)) < 0) { /* If what?... */
    1503:     if (ifc == -3) {
    1504:         printf("?Condition required\n");
    1505:         return(-9);
    1506:     } else return(ifc);
    1507:     }
    1508:     switch (ifc) {          /* set z = 1 for true, 0 for false */
    1509:       case XXIFNO:          /* IF NOT */
    1510:     not ^= 1;           /* So NOT NOT NOT ... will work */
    1511:     ifargs++;
    1512:     goto ifagain;
    1513:       case XXIFSU:          /* IF SUCCESS */
    1514:     z = ( success != 0 );
    1515:     debug(F101,"if success","",z);
    1516:     ifargs += 1;
    1517:     break;
    1518:       case XXIFFA:          /* IF FAILURE */
    1519:     z = ( success == 0 );
    1520:     debug(F101,"if failure","",z);
    1521:     ifargs += 1;
    1522:     break;
    1523:       case XXIFDE:          /* IF DEFINED */
    1524:     if ((x = cmfld("Macro or variable name","",&s,NULL)) < 0) {
    1525:         if (x == -3) return(-2);
    1526:         else return(x);
    1527:     }
    1528: #ifdef COMMENT
    1529:     strcpy(line,s);         /* Make a copy */
    1530:         if ((int)strlen(line) < 1) return(-2);
    1531:     lp = line;
    1532:     if (line[0] == CMDQ && (line[1] == '%' || line[1] == '&')) lp++;
    1533:     if (*lp == '%') {       /* Is it a variable? */
    1534:         x = *(lp + 1);      /* Fold case */
    1535:         if (isupper(x)) *(lp + 1) = tolower(x);
    1536:         if (x >= '0' && x <= '9' && maclvl > -1) /* Digit is macro arg */
    1537:           z = ( (m_arg[maclvl][x - '0'] != (char *)0)
    1538:            && (int)strlen(m_arg[maclvl][x - '0']) != 0);
    1539:         else            /* Otherwise it's a global variable */
    1540:           z = ( (g_var[x] != (char *)0)
    1541:            &&  (int)strlen(g_var[x]) != 0 );
    1542:     } else if (*lp == '&') {    /* Array reference */
    1543:         int cc, nn;
    1544:         if (arraynam(lp,&cc,&nn) < 0)
    1545:           z = 0;
    1546:         else z = (arrayval(cc,nn) == NULL ? 0 : 1);
    1547:     }
    1548: #else
    1549:         if ((int)strlen(s) < 1) return(-2);
    1550:     z = 0;              /* Assume failure. */
    1551:     if (*s == CMDQ) {       /* Object begins with backslash. */
    1552:         char c;
    1553:         c = s[1];           /* Character following backslash */
    1554:         if (c) {
    1555:         c = islower(c) ? toupper(c) : c;
    1556:         if (c == '%' ||     /* Simple variable */
    1557:             c == '&' ||     /* Array element */
    1558:             c == '$' ||     /* Environment variable */
    1559:             c == 'V' ||     /* Builtin named variable */
    1560:             c == 'M' ||     /* Macro name */
    1561:             c == 'F') {     /* Builtin function */
    1562:             int t;      /* Let xxstring() evaluate it */
    1563:             t = LINBUFSIZ-1;    /* This lets us test \v(xxx) */
    1564:             lp = line;      /* and even \f...(xxx) */
    1565:             xxstring(s,&lp,&t);
    1566:             t = strlen(line);
    1567:             debug(F111,"IF DEF",line,t);
    1568:             z = t > 0;
    1569:         }
    1570:         }
    1571:     }
    1572: #endif /* COMMENT */
    1573:     else {          /* Otherwise it's a macro name */
    1574:         z = ( mxlook(mactab,s,nmac) > -1 ); /* Look for exact match */
    1575:     }
    1576:     debug(F111,"if defined",s,z);
    1577:     ifargs += 2;
    1578:     break;
    1579:
    1580:       case XXIFBG:          /* IF BACKGROUND */
    1581:       case XXIFFG:          /* IF FOREGROUND */
    1582:     bgchk();            /* Check background status */
    1583:     if (ifc == XXIFFG)      /* Foreground */
    1584:       z = pflag ? 1 : 0;
    1585:         else z = pflag ? 0 : 1;     /* Background */
    1586:     ifargs += 1;
    1587:     break;
    1588:
    1589:       case XXIFCO:          /* IF COUNT */
    1590:     z = ( --count[cmdlvl] > 0 );
    1591:     debug(F101,"if count","",z);
    1592:     ifargs += 1;
    1593:     break;
    1594:
    1595:       case XXIFEX:          /* IF EXIST */
    1596:     if ((x = cmfld("File","",&s,xxstring)) < 0) {
    1597:         if (x == -3) {
    1598:         printf("?Filename required\n");
    1599:         return(-9);
    1600:         } else return(x);
    1601:     }
    1602:     z = ( zchki(s) > -1L );
    1603:     debug(F101,"if exist","",z);
    1604:     ifargs += 2;
    1605:     break;
    1606:
    1607:       case XXIFEQ:          /* IF EQUAL (string comparison) */
    1608:       case XXIFLL:          /* IF Lexically Less Than */
    1609:       case XXIFLG:          /* If Lexically Greater Than */
    1610:     if ((x = cmfld("first word or variable name","",&s,xxstring)) < 0) {
    1611:         if (x == -3) {
    1612:         printf("?Text required\n");
    1613:         return(-9);
    1614:         } else return(x);
    1615:     }
    1616:     x = (int)strlen(s);
    1617:     if (x > LINBUFSIZ-1) {
    1618:         printf("?IF: strings too long\n");
    1619:         return(-2);
    1620:     }
    1621:     lp = line;          /* lp points to first string */
    1622:     strcpy(lp,s);
    1623:     if ((y = cmfld("second word or variable name","",&s,xxstring)) < 0) {
    1624:         if (y == -3) {
    1625:         printf("?Text required\n");
    1626:         return(-9);
    1627:         } else return(y);
    1628:     }
    1629:     y = (int)strlen(s);
    1630:     if (x + y + 2 > LINBUFSIZ) {
    1631:         printf("?IF: strings too long\n");
    1632:         return(-2);
    1633:     }
    1634:     tp = lp + y + 2;        /* tp points to second string */
    1635:     strcpy(tp,s);
    1636:     if (incase)         /* INPUT CASE OBSERVE */
    1637:       x = strcmp(lp,tp);
    1638:     else                /* INPUT CASE IGNORE */
    1639:       x = xxstrcmp(lp,tp,(y > x) ? y : x); /* Use longest length */
    1640:     debug(F101,"IF comparison","",x);
    1641:     switch (ifc) {
    1642:       case XXIFEQ:          /* IF EQUAL (string comparison) */
    1643:         z = (x == 0);
    1644:         break;
    1645:       case XXIFLL:          /* IF Lexically Less Than */
    1646:         z = (x < 0);
    1647:         break;
    1648:       case XXIFLG:          /* If Lexically Greater Than */
    1649:         z = (x > 0);
    1650:         break;
    1651:     }
    1652:     ifargs += 3;
    1653:     break;
    1654:
    1655:       case XXIFAE:          /* IF (arithmetically) = */
    1656:       case XXIFLT:          /* IF (arithmetically) < */
    1657:       case XXIFGT: {            /* IF (arithmetically) > */
    1658:     /* Really should use longs here... */
    1659:     /* But cmnum parses ints. */
    1660:     int n1, n2;
    1661:     x = cmfld("first number or variable name","",&s,xxstring);
    1662:     if (x == -3) {
    1663:         printf("?Quantity required\n");
    1664:         return(-9);
    1665:     }
    1666:     if (x < 0) return(x);
    1667:     debug(F101,"xxifgt cmfld","",x);
    1668:     lp = line;
    1669:     strcpy(lp,s);
    1670:     debug(F110,"xxifgt exp1",lp,0);
    1671:     if (!xxstrcmp(lp,"count",5)) {
    1672:         n1 = count[cmdlvl];
    1673:     } else if (!xxstrcmp(lp,"version",7)) {
    1674:         n1 = (int) vernum;
    1675:     } else if (!xxstrcmp(lp,"argc",4)) {
    1676:         n1 = (int) macargc[maclvl];
    1677:     } else {
    1678:         if (!chknum(lp)) return(-2);
    1679:         n1 = atoi(lp);
    1680:     }
    1681:     y = cmfld("second number or variable name","",&s,xxstring);
    1682:     if (y == -3) {
    1683:         printf("?Quantity required\n");
    1684:         return(-9);
    1685:     }
    1686:     if (y < 0) return(y);
    1687:         if ((int)strlen(s) < 1) return(-2);
    1688:     x = (int)strlen(lp);
    1689:     tp = line + x + 2;
    1690:     strcpy(tp,s);
    1691:     debug(F110,"xxifgt exp2",tp,0);
    1692:     if (!xxstrcmp(tp,"count",5)) {
    1693:         n2 = count[cmdlvl];
    1694:     } else if (!xxstrcmp(tp,"version",7)) {
    1695:         n2 = (int) vernum;
    1696:     } else if (!xxstrcmp(tp,"argc",4)) {
    1697:         n2 = (int) macargc[maclvl];
    1698:     } else {
    1699:         if (!chknum(tp)) return(-2);
    1700:         n2 = atoi(tp);
    1701:     }
    1702:     debug(F101,"xxifft ifc","",ifc);
    1703:     z = ((n1 <  n2 && ifc == XXIFLT)
    1704:       || (n1 == n2 && ifc == XXIFAE)
    1705:       || (n1 >  n2 && ifc == XXIFGT));
    1706:     debug(F101,"xxifft n1","",n1);
    1707:     debug(F101,"xxifft n2","",n2);
    1708:     debug(F101,"xxifft z","",z);
    1709:     ifargs += 3;
    1710:     break; }
    1711:
    1712:       case XXIFNU:          /* IF NUMERIC */
    1713:     x = cmfld("variable name or constant","",&s,xxstring);
    1714:     if (x == -3) {
    1715:         printf("?Quantity required\n");
    1716:         return(-9);
    1717:     }
    1718:     if (x < 0) return(x);
    1719:     debug(F111,"xxifnu cmfld",s,x);
    1720:     lp = line;
    1721:     strcpy(lp,s);
    1722:     debug(F110,"xxifnu quantity",lp,0);
    1723:         z = chknum(lp);
    1724:         debug(F101,"xxifnu chknum","",z);
    1725:     ifargs += 2;
    1726:     break;
    1727:
    1728:       default:              /* Shouldn't happen */
    1729:     return(-2);
    1730:     }
    1731:
    1732:     switch (cx) {           /* Separate handling for IF and XIF */
    1733:
    1734:       case XXIF:            /* This is IF... */
    1735:     ifcmd[cmdlvl] = 1;      /* We just completed an IF command */
    1736:     if (not) z = !z;        /* Handle NOT here */
    1737:     if (z) {            /* Condition is true */
    1738:         iftest[cmdlvl] = 1;     /* Remember that IF succeeded */
    1739:         if (maclvl > -1) {      /* In macro, */
    1740:         pushcmd();      /* save rest of command. */
    1741:         } else if (tlevel > -1) {   /* In take file, */
    1742:         debug(F100, "doif: pushing command", "", 0);
    1743:         pushcmd();      /* save rest of command. */
    1744:         } else {            /* If interactive, */
    1745:         cmini(ckxech);      /* just start a new command */
    1746:         printf("\n");       /* (like in MS-DOS Kermit) */
    1747:         if (pflag) prompt(xxstring);
    1748:         }
    1749:     } else {            /* Condition is false */
    1750:         iftest[cmdlvl] = 0;     /* Remember command failed. */
    1751:         if ((y = cmtxt("command to be ignored","",&s,NULL)) < 0)
    1752:           return(y);        /* Gobble up rest of line */
    1753:     }
    1754:     return(0);
    1755:
    1756:       case XXIFX: {         /* This is XIF (Extended IF) */
    1757:       char *p;
    1758:       char e[5];
    1759:       int i;
    1760:       if ((y = cmtxt("Object command","",&s,NULL)) < 0)
    1761:         return(y);          /* Get object command. */
    1762:       p = s;
    1763:       lp = line;
    1764:       if (litcmd(&p,&lp) < 0) { /* Insert quotes in THEN-part */
    1765:           return(-2);
    1766:       }
    1767:       if (!z) {         /* Use ELSE-part, if any */
    1768:           lp = line;        /* Write over THEN part. */
    1769:           *lp = NUL;
    1770:           while (*p == SP) p++; /* Strip trailing spaces */
    1771:           if (*p) {         /* At end? */
    1772:           for (i = 0; i < 4; i++) e[i] = *p++; /* No, check for ELSE */
    1773:           if (xxstrcmp(e,"else",4)) return(-2); /* No, syntax error */
    1774:           if (litcmd(&p,&lp) < 0) { /* Insert quotes */
    1775:               return(-2);
    1776:           }
    1777:           while (*p == SP) p++; /* Strip trailing spaces */
    1778:           if (*p) return(-2);   /* Should be nothing here. */
    1779:           }
    1780:       }
    1781:       if (line[0]) {
    1782:           x = mlook(mactab,"_xif",nmac); /* get index of "_xif" macro. */
    1783:           if (x < 0) {          /* Not there? */
    1784:           addmmac("_xif",xif_def);  /* Put it back. */
    1785:           if (mlook(mactab,"_xif",nmac) < 0) { /* Look it up again. */
    1786:               printf("?XIF macro gone!\n");
    1787:               return(success = 0);
    1788:           }
    1789:           }
    1790:           dodo(x,line);     /* Do the XIF macro */
    1791:       }
    1792:       return(0);
    1793:       }
    1794:       case XXWHI: {         /* WHILE Command */
    1795:       p = cmdbuf;           /* Capture IF condition */
    1796:       ifcond[0] = NUL;      /* from command buffer */
    1797:       while (*p == SP) p++;
    1798:       while (*p != SP) p++;
    1799:       ifcp = ifcond;
    1800:       strcpy(ifcp,"{ \\flit(if not ");
    1801:       ifcp += (int)strlen(ifcp);
    1802:       while (*p != '{' && *p != NUL) *ifcp++ = *p++;
    1803:       p = " goto wbot) } ";
    1804:       while (*ifcp++ = *p++) ;
    1805:       debug(F110,"WHILE cmd",ifcond,0);
    1806:
    1807:       if ((y = cmtxt("Object command","",&s,NULL)) < 0)
    1808:         return(y);          /* Get object command. */
    1809:       p = s;
    1810:       lp = line;
    1811:       if (litcmd(&p,&lp) < 0) { /* Insert quotes in object command */
    1812:           return(-2);
    1813:       }
    1814:       debug(F110,"WHILE body",line,0);
    1815:       if (line[0]) {
    1816:           char *p;
    1817:           x = mlook(mactab,"_while",nmac); /* index of "_while" macro. */
    1818:           if (x < 0) {      /* Not there? */
    1819:           addmmac("_while",whil_def); /* Put it back. */
    1820:           if (mlook(mactab,"_while",nmac) < 0) { /* Look it up again */
    1821:               printf("?WHILE macro definition gone!\n");
    1822:               return(success = 0);
    1823:           }
    1824:           }
    1825:           p = malloc((int)strlen(ifcond) + (int)strlen(line) + 2);
    1826:           if (p) {
    1827:           strcpy(p,ifcond);
    1828:           strcat(p,line);
    1829:           debug(F110,"WHILE dodo",p,0);
    1830:           dodo(x,p);
    1831:           free(p);
    1832:           } else {
    1833:           printf("?Can't allocate storage for WHILE command");
    1834:           return(success = 0);
    1835:           }
    1836:       }
    1837:       return(0);
    1838:       }
    1839:       default:
    1840:     return(-2);
    1841:     }
    1842: }
    1843: #endif /* NOSPL */
    1844:
    1845: /* Set up a TAKE command file */
    1846:
    1847: int
    1848: dotake(s) char *s; {
    1849:     if ((tfile[++tlevel] = fopen(s,"r")) == NULL) {
    1850:     perror(s);
    1851:     debug(F110,"Failure to open",s,0);
    1852:     success = 0;
    1853:     tlevel--;
    1854:     } else {
    1855: #ifdef VMS
    1856:     conres();           /* So Ctrl-C will work */
    1857: #endif /* VMS */
    1858: #ifndef NOSPL
    1859:     cmdlvl++;           /* Entering a new command level */
    1860:     if (cmdlvl > CMDSTKL) {
    1861:         cmdlvl--;
    1862:         printf("?TAKE files and/or DO commands nested too deeply\n");
    1863:         return(success = 0);
    1864:     }
    1865:     if (tfnam[tlevel]) free(tfnam[tlevel]); /* Copy the filename */
    1866:     if (tfnam[tlevel] = malloc(strlen(s) + 1))
    1867:       strcpy(tfnam[tlevel],s);
    1868:     ifcmd[cmdlvl] = 0;      /* Set variables for this cmd file */
    1869:     iftest[cmdlvl] = 0;
    1870:     count[cmdlvl] = 0;
    1871:     cmdstk[cmdlvl].src = CMD_TF;    /* Say we're in a TAKE file */
    1872:     cmdstk[cmdlvl].lvl = tlevel;    /* nested at this level */
    1873: #endif /* NOSPL */
    1874:     }
    1875:     return(1);
    1876: }
    1877: #endif /* NOICP */

#### Defined functions

doask defined in line 251; used 2 times

- in /usr/src/new/kermit5.188/ckuusr.c line 989, 1380

dobug defined in line 861; used 1 times

- in /usr/src/new/kermit5.188/ckuusr.c line 996

dodef defined in line 390; used 1 times

- in /usr/src/new/kermit5.188/ckuusr.c line 1071

dodel defined in line 704; used 1 times

- in /usr/src/new/kermit5.188/ckuusr.c line 1100

dodial defined in line 550; used 1 times

- in /usr/src/new/kermit5.188/ckuusr.c line 1095

dodir defined in line 595; used 1 times

- in /usr/src/new/kermit5.188/ckuusr.c line 1105

doelse defined in line 741; used 1 times

- in /usr/src/new/kermit5.188/ckuusr.c line 1110

doenable defined in line 638; used 1 times

- in /usr/src/new/kermit5.188/ckuusr.c line 1126

dofor defined in line 773; used 1 times

- in /usr/src/new/kermit5.188/ckuusr.c line 1351

doget defined in line 1126; used 1 times

- in /usr/src/new/kermit5.188/ckuusr.c line 1369

dogoto defined in line 1375; used 1 times

- in /usr/src/new/kermit5.188/ckuusr.c line 1440

dogta defined in line 1311; used 1 times

- in /usr/src/new/kermit5.188/ckuusr.c line 979

doif defined in line 1493; used 1 times

- in /usr/src/new/kermit5.188/ckuusr.c line 1447

doincr defined in line 355; used 1 times

- in /usr/src/new/kermit5.188/ckuusr.c line 1066

doopen defined in line 1027; used 1 times

- in /usr/src/new/kermit5.188/ckuusr.c line 1191

dopaus defined in line 885; used 1 times

- in /usr/src/new/kermit5.188/ckuusr.c line 1275

dorenam defined in line 942; used 1 times

- in /usr/src/new/kermit5.188/ckuusr.c line 1560

doreturn defined in line 976; used 1 times

- in /usr/src/new/kermit5.188/ckuusr.c line 1146

dotake defined in line 1847; used 3 times

- in /usr/src/new/kermit5.188/ckcmai.c line 835, 970
- in /usr/src/new/kermit5.188/ckuusr.c line 1823

ludial defined in line 475; used 1 times

- in line 573

xxstrcmp defined in line 225; used 12 times

- in line 521, 1438, 1470, 1639, 1671-1675(3), 1692-1696(3), 1773
- in /usr/src/new/kermit5.188/ckuus3.c line 908

#### Defined variables

cwdf defined in line 181; used 3 times

- in /usr/src/new/kermit5.188/ckuus5.c line 3716-3718(2), 3726

dialnum defined in line 154; used 9 times

- in line 554-555(2), 576-578(5)
- in /usr/src/new/kermit5.188/ckuus4.c line 1235(2)

ifc defined in line 160; used 10 times

- in line 1502-1508(4), 1583, 1641, 1702-1705(4)

ifcond defined in line 163; used 5 times

- in line 1796-1799(2), 1805, 1825-1827(2)

ifcp defined in line 164; used 6 times

- in line 1799-1804(6)

iftab defined in line 127; used 2 times

- in line 148, 1502

mstab defined in line 99; used 2 times

- in line 113, 904

nif defined in line 148; used 1 times

- in line 1502

nms defined in line 113; used 1 times

- in line 904

nopn defined in line 125; used 1 times

- in line 1031

not defined in line 161; used 3 times

- in line 1497, 1510, 1736

opntab defined in line 116; used 2 times

- in line 125, 1031

p defined in line 215; used 57 times

- in line 292-302(7), 955, 962-967(2), 978, 990-993(4), 1009, 1313, 1342-1347(5), 1353-1355(3), 1495, 1757-1764(3), 1770-1778(8), 1795-1816(13), 1825-1831(7)

s defined in line 215; used 184 times

- in line 212(2), 255, 261-263(2), 273-275(3), 281, 332-333(2), 341-346(2), 359, 365-368(3), 395-397(2), 404-405(2), 412-417(3), 423-438(10), 449-454(5), 476(2), 482-483(2), 500-501(2), 521, 555, 566-583(8), 599, 605, 611-622(5), 628, 707, 714-718(4), 726-729(2), 735, 765, 778, 784, 792-793(3), 800-802(3), 809-811(3), 819-821(3), 831-834(3), 944, 954-956(2), 962, 977(2), 985-992(4), 1029, 1043, 1053, 1065, 1071, 1081, 1087, 1099, 1112, 1161-1170(7), 1186-1188(2), 1207-1219(8), 1238-1240(2), 1376(2), 1383-1394(12), 1436-1438(2), 1445, 1470, 1478, 1485, 1495, 1524-1529(2), 1549-1553(3), 1565, 1574-1576(2), 1596, 1602, 1610, 1616, 1622-1623(2), 1629, 1635, 1661, 1669, 1681, 1687-1690(2), 1713, 1719-1721(2), 1751, 1760-1762(2), 1807-1809(2), 1848-1851(5), 1866-1867(2)

x defined in line 214; used 170 times

- in line 263, 296-298(3), 309-316(4), 325-339(6), 370-378(3), 409-410(2), 417-422(3), 566-567(2), 599-600(2), 611-619(7), 639-641(3), 707-711(3), 784, 842-845(3), 851, 889-895(5), 918-921(2), 935, 944-948(3), 956-960(3), 978, 984-990(5), 996, 1020, 1029-1037(5), 1111, 1128-1132(2), 1161-1166(5), 1186-1192(3), 1207(2), 1213-1215(3), 1221-1223(3), 1229-1230(3), 1238-1244(3), 1251-1259(6), 1267-1269(3), 1277-1296(11), 1306, 1377, 1453, 1471-1475(2), 1482, 1495, 1524-1526(3), 1534-1541(9), 1596-1600(3), 1610-1617(5), 1630, 1637-1649(8), 1661-1667(5), 1688-1689(2), 1713-1719(5), 1782-1783(2), 1790, 1817-1818(2), 1830

y defined in line 214; used 162 times

- in line 255-268(7), 274-276(3), 289-292(2), 322, 346-349(3), 359-363(3), 370-378(7), 395-402(5), 409-417(8), 423-435(8), 454-455(2), 553(2), 621(2), 640-650(5), 658-694(12), 707, 721(2), 765-766(2), 778-785(5), 796-798(3), 805-807(3), 814-816(3), 831(2), 889-907(12), 923-924(2), 944, 950, 963(2), 1029, 1043, 1049, 1055(2), 1065-1073(5), 1081-1089(5), 1114(2), 1223-1234(4), 1315-1316(2), 1377, 1384-1392(4), 1407, 1436-1438(3), 1470(2), 1495, 1623-1639(8), 1681-1686(4), 1751-1752(2), 1760-1761(2), 1807-1808(2)

z defined in line 214; used 51 times

- in line 263, 370, 376-378(2), 409, 417-422(2), 784, 902-907(2), 927-930(3), 1029, 1043-1047(3), 1099-1103(3), 1495-1498(2), 1514-1520(4), 1537-1550(5), 1568, 1574-1576(2), 1584-1591(4), 1602-1603(2), 1643-1649(3), 1703-1708(2), 1723-1724(2), 1736-1737(3), 1767

#### Defined macros

fclose defined in line 34; never used
feof defined in line 30; used 1 times

- in line 1455

fgets defined in line 32; used 2 times

- in line 496, 1456

fopen defined in line 33; used 1 times

- in line 1849

rewind defined in line 31; used 2 times

- in line 494, 1454

xsystem defined in line 212; used 3 times

- in line 607, 629, 730

Last modified: 1992-11-24 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 7022 |