Annotation of researchv10dc/lbin/kermit/ckuusr.c, revision 1.1.1.1

1.1       root        1: char *userv = "User Interface 4E(059), 29 Jan 88";
                      2:  
                      3: /*  C K U U S R --  "User Interface" for Unix Kermit (Part 1)  */
                      4:  
                      5: /*
                      6:  4E, support for Apollo Aegis, Data General added, July 87.
                      7: */
                      8: /*
                      9:  Author: Frank da Cruz (SY.FDC@CU20B),
                     10:  Columbia University Center for Computing Activities, January 1985.
                     11:  Copyright (C) 1985, Trustees of Columbia University in the City of New York.
                     12:  Permission is granted to any individual or institution to use, copy, or
                     13:  redistribute this software so long as it is not sold for profit, provided this
                     14:  copyright notice is retained. 
                     15: */
                     16: 
                     17: /*
                     18:  The ckuusr module contains the terminal input and output functions for Unix
                     19:  Kermit.  It includes a simple Unix-style command line parser as well as
                     20:  an interactive prompting keyword command parser.  It depends on the existence
                     21:  of Unix facilities like fopen, fgets, feof, (f)printf, argv/argc, etc.  Other
                     22:  functions that are likely to vary among Unix implementations -- like setting
                     23:  terminal modes or interrupts -- are invoked via calls to functions that are
                     24:  defined in the system-dependent modules, ck?[ft]io.c.
                     25:  
                     26:  The command line parser processes any arguments found on the command line,
                     27:  as passed to main() via argv/argc.  The interactive parser uses the facilities
                     28:  of the cmd package (developed for this program, but usable by any program).
                     29:  
                     30:  Any command parser may be substituted for this one.  The only requirements
                     31:  for the Kermit command parser are these:
                     32:  
                     33:  1. Set parameters via global variables like duplex, speed, ttname, etc.
                     34:     See ckmain.c for the declarations and descriptions of these variables.
                     35:  
                     36:  2. If a command can be executed without the use of Kermit protocol, then
                     37:     execute the command directly and set the variable sstate to 0. Examples
                     38:     include 'set' commands, local directory listings, the 'connect' command.
                     39:  
                     40:  3. If a command requires the Kermit protocol, set the following variables:
                     41:  
                     42:     sstate                             string data
                     43:       'x' (enter server mode)            (none)
                     44:       'r' (send a 'get' command)         cmarg, cmarg2
                     45:       'v' (enter receive mode)           cmarg2
                     46:       'g' (send a generic command)       cmarg
                     47:       's' (send files)                   nfils, cmarg & cmarg2 OR cmlist
                     48:       'c' (send a remote host command)   cmarg
                     49:  
                     50:     cmlist is an array of pointers to strings.
                     51:     cmarg, cmarg2 are pointers to strings.
                     52:     nfils is an integer.    
                     53:  
                     54:     cmarg can be a filename string (possibly wild), or
                     55:        a pointer to a prefabricated generic command string, or
                     56:        a pointer to a host command string.
                     57:     cmarg2 is the name to send a single file under, or
                     58:        the name under which to store an incoming file; must not be wild.
                     59:     cmlist is a list of nonwild filenames, such as passed via argv.
                     60:     nfils is an integer, interpreted as follows:
                     61:       -1: argument string is in cmarg, and should be expanded internally.
                     62:        0: stdin.
                     63:       >0: number of files to send, from cmlist.
                     64:  
                     65:  The screen() function is used to update the screen during file transfer.
                     66:  The tlog() function maintains a transaction log.
                     67:  The debug() function maintains a debugging log.
                     68:  The intmsg() and chkint() functions provide the user i/o for interrupting
                     69:    file transfers.
                     70: */
                     71: 
                     72: /* Includes */
                     73:  
                     74: #include "ckcdeb.h"
                     75: #include <stdio.h>
                     76: #include <ctype.h>
                     77: #ifndef AMIGA
                     78: #include <signal.h>
                     79: #endif
                     80: #include "ckcker.h"
                     81: #include "ckucmd.h"
                     82: #include "ckuusr.h"
                     83:  
                     84: #ifdef datageneral
                     85: #define fgets(stringbuf,max,fd) dg_fgets(stringbuf,max,fd) 
                     86: #define fork() vfork()
                     87: /* DG version 3.21 of C has bugs in the following routines, since they
                     88:  * depend on /etc/passwd.  In the context where the routines are used,
                     89:  * we don't need them anyway.
                     90:  */
                     91: #define getgid() -1
                     92: #define getuid() -1
                     93: #define geteuid() -1
                     94: #endif
                     95: 
                     96: /* External Kermit Variables, see ckmain.c for description. */
                     97:  
                     98: extern int size, rpsiz, urpsiz, speed, local, 
                     99:   server, displa, binary, parity, deblog, escape, xargc, flow,
                    100:   turn, duplex, nfils, ckxech, pktlog, seslog, tralog, stdouf,
                    101:   turnch, dfloc, keep, maxrps, warn, quiet, cnflg, tlevel;
                    102:  
                    103: extern char *versio, *protv, *ckxv, *ckzv, *fnsv, *connv, *dftty, *cmdv;
                    104: extern char *dialv, *loginv;
                    105: extern char *ckxsys, *ckzsys, *cmarg, *cmarg2, **xargv, **cmlist;
                    106: extern char *DIRCMD, *PWDCMD, cmerrp[];
                    107: extern CHAR sstate, ttname[];
                    108: char *strcpy(), *getenv();
                    109: #ifdef AMIGA
                    110: char *getcwd();
                    111: #endif
                    112:  
                    113: /* Declarations from cmd package */
                    114:  
                    115: extern char cmdbuf[];                  /* Command buffer */
                    116:  
                    117: /* Declarations from ck?fio.c module */
                    118:  
                    119: extern char *SPACMD, *zhome();         /* Space command, home directory. */
                    120: extern int backgrd;                    /* Kermit executing in background */
                    121:  
                    122: /* The background flag is set by ckutio.c (via conint() ) to note whether */
                    123: /* this kermit is executing in background ('&' on shell command line).    */
                    124:  
                    125:  
                    126: /* Variables and symbols local to this module */
                    127:  
                    128: char line[CMDBL+10], *lp;              /* Character buffer for anything */
                    129: char debfil[50];                       /* Debugging log file name */
                    130: char pktfil[50];                       /* Packet log file name */
                    131: char sesfil[50];                       /* Session log file name */
                    132: char trafil[50];                       /* Transaction log file name */
                    133:  
                    134: int n,                                 /* General purpose int */
                    135:     cflg,                              /* Command-line connect cmd given */
                    136:     action,                            /* Action selected on command line*/
                    137:     repars,                            /* Reparse needed */
                    138:     cwdf = 0;                          /* CWD has been done */
                    139:  
                    140: #define MAXTAKE 20                     /* Maximum nesting of TAKE files */
                    141: FILE *tfile[MAXTAKE];                  /* File pointers for TAKE command */
                    142:  
                    143: char *homdir;                          /* Pointer to home directory string */
                    144: char cmdstr[100];                      /* Place to build generic command */
                    145: 
                    146: /*  C M D L I N  --  Get arguments from command line  */
                    147: /*
                    148:  Simple Unix-style command line parser, conforming with 'A Proposed Command
                    149:  Syntax Standard for Unix Systems', Hemenway & Armitage, Unix/World, Vol.1,
                    150:  No.3, 1984.
                    151: */
                    152: cmdlin() {
                    153:     char x;                            /* Local general-purpose int */
                    154:     cmarg = "";                                /* Initialize globals */
                    155:     cmarg2 = "";
                    156:     action = cflg = 0;
                    157:  
                    158:     while (--xargc > 0) {              /* Go through command line words */
                    159:        xargv++;
                    160:        debug(F111,"xargv",*xargv,xargc);
                    161:        if (**xargv == '-') {           /* Got an option (begins with dash) */
                    162:            x = *(*xargv+1);            /* Get the option letter */
                    163:            x = doarg(x);               /* Go handle the option */
                    164:            if (x < 0) doexit(BAD_EXIT);
                    165:        } else {                        /* No dash where expected */
                    166:            usage();
                    167:            doexit(BAD_EXIT);
                    168:        }
                    169:     }
                    170:     debug(F101,"action","",action);
                    171:     if (!local) {
                    172:        if ((action == 'g') || (action == 'r') ||
                    173:            (action == 'c') || (cflg != 0))
                    174:            fatal("-l and -b required");
                    175:     }
                    176:     if (*cmarg2 != 0) {
                    177:        if ((action != 's') && (action != 'r') &&
                    178:            (action != 'v'))
                    179:            fatal("-a without -s, -r, or -g");
                    180:     }
                    181:     if ((action == 'v') && (stdouf) && (!local)) {
                    182:        if (isatty(1))
                    183:            fatal("unredirected -k can only be used in local mode");
                    184:     }
                    185:     if ((action == 's') || (action == 'v') ||
                    186:        (action == 'r') || (action == 'x')) {
                    187:        if (local) displa = 1;
                    188:        if (stdouf) { displa = 0; quiet = 1; }
                    189:     }
                    190:  
                    191:     if (quiet) displa = 0;             /* No display if quiet requested */
                    192:  
                    193:     if (cflg) {
                    194:        conect();                       /* Connect if requested */
                    195:        if (action == 0) {
                    196:            if (cnflg) conect();        /* And again if requested */
                    197:            doexit(GOOD_EXIT);          /* Then exit indicating success */
                    198:        }
                    199:     }
                    200:     if (displa) concb(escape);         /* (for console "interrupts") */
                    201:     return(action);                    /* Then do any requested protocol */
                    202: }
                    203: 
                    204: /*  D O A R G  --  Do a command-line argument.  */
                    205:  
                    206: doarg(x) char x; {
                    207:     int z; char *xp;
                    208:  
                    209:     xp = *xargv+1;                     /* Pointer for bundled args */
                    210:     while (x) {
                    211:        switch (x) {
                    212:  
                    213: case 'x':                              /* server */
                    214:     if (action) fatal("conflicting actions");
                    215:     action = 'x';
                    216:     break;
                    217:  
                    218: case 'f':
                    219:     if (action) fatal("conflicting actions");
                    220:     action = setgen('F',"","","");
                    221:     break;
                    222:  
                    223: case 'r':                              /* receive */
                    224:     if (action) fatal("conflicting actions");
                    225:     action = 'v';
                    226:     break;
                    227:  
                    228: case 'k':                              /* receive to stdout */
                    229:     if (action) fatal("conflicting actions");
                    230:     stdouf = 1;
                    231:     action = 'v';
                    232:     break;
                    233:  
                    234: case 's':                              /* send */
                    235:     if (action) fatal("conflicting actions");
                    236:     if (*(xp+1)) fatal("invalid argument bundling after -s");
                    237:     z = nfils = 0;                     /* Initialize file counter, flag */
                    238:     cmlist = xargv+1;                  /* Remember this pointer */
                    239:     while (--xargc > 0) {              /* Traverse the list */ 
                    240:        *xargv++;
                    241:        if (**xargv == '-') {           /* Check for sending stdin */
                    242:            if (strcmp(*xargv,"-") != 0) break;
                    243:            z++;
                    244:         }
                    245:        nfils++;                        /* Bump file counter */
                    246:     }
                    247:     xargc++, *xargv--;                 /* Adjust argv/argc */
                    248:     if (nfils < 1) fatal("missing filename for -s");
                    249:     if (z > 1) fatal("-s: too many -'s");
                    250:     if (z == 1) {
                    251:        if (nfils == 1) nfils = 0;
                    252:        else fatal("invalid mixture of filenames and '-' in -s");
                    253:     }
                    254:     if (nfils == 0) {
                    255:        if (isatty(0)) fatal("sending from terminal not allowed");
                    256:     }
                    257:     debug(F101,*xargv,"",nfils);
                    258:     action = 's';
                    259:     break;
                    260:  
                    261: /* cont'd... */
                    262: 
                    263: /* ...doarg(), cont'd */
                    264:  
                    265: case 'g':                              /* get */
                    266:     if (action) fatal("conflicting actions");
                    267:     if (*(xp+1)) fatal("invalid argument bundling after -g");
                    268:     *xargv++, xargc--;
                    269:     if ((xargc == 0) || (**xargv == '-'))
                    270:        fatal("missing filename for -g");
                    271:     cmarg = *xargv;
                    272:     action = 'r';
                    273:     break;
                    274:  
                    275: case 'c':                              /* connect before */
                    276:     cflg = 1;
                    277:     break;
                    278:  
                    279: case 'n':                              /* connect after */
                    280:     cnflg = 1;
                    281:     break;
                    282:  
                    283: case 'h':                              /* help */
                    284:     usage();
                    285:     return(-1);
                    286:  
                    287: case 'a':                              /* "as" */
                    288:     if (*(xp+1)) fatal("invalid argument bundling after -a");
                    289:     *xargv++, xargc--;
                    290:     if ((xargc < 1) || (**xargv == '-'))
                    291:        fatal("missing name in -a");
                    292:     cmarg2 = *xargv;
                    293:     break;
                    294:  
                    295: case 'l':                              /* set line */
                    296:     if (*(xp+1)) fatal("invalid argument bundling after -l");
                    297:     *xargv++, xargc--;
                    298:     if ((xargc < 1) || (**xargv == '-'))
                    299:        fatal("communication line device name missing");
                    300:     strcpy(ttname,*xargv);
                    301: /*  if (strcmp(ttname,dftty) == 0) local = dfloc; else local = 1;  */
                    302:     local = (strcmp(ttname,CTTNAM) != 0); /* (better than old way) */
                    303:     debug(F101,"local","",local);
                    304:     ttopen(ttname,&local,0);
                    305:     break;
                    306:  
                    307: case 'b':                              /* set baud */
                    308:     if (*(xp+1)) fatal("invalid argument bundling");
                    309:     *xargv++, xargc--;
                    310:     if ((xargc < 1) || (**xargv == '-'))
                    311:        fatal("missing baud");
                    312:     z = atoi(*xargv);                  /* Convert to number */
                    313:     if (chkspd(z) > -1) speed = z;     /* Check it */
                    314:        else fatal("unsupported baud rate");
                    315:     break;
                    316:  
                    317: case 'e':                              /* Extended packet length */
                    318:     if (*(xp+1)) fatal("invalid argument bundling");
                    319:     *xargv++, xargc--;
                    320:     if ((xargc < 1) || (**xargv == '-'))
                    321:        fatal("missing length");
                    322:     z = atoi(*xargv);                  /* Convert to number */
                    323:     if (z > 10 && z < maxrps) {
                    324:         rpsiz = urpsiz = z;
                    325:        if (z > 94) rpsiz = 94;         /* Fallback if other Kermit can't */
                    326:     } else fatal("Unsupported packet length");
                    327:     break;
                    328: 
                    329: case 'i':                              /* Treat files as binary */
                    330:     binary = 1;
                    331:     break;
                    332:  
                    333: /* cont'd... */
                    334: 
                    335: /* ...doarg(), cont'd */
                    336:  
                    337:  
                    338: case 'w':                              /* File warning */
                    339:     warn = 1;
                    340:     break;
                    341:  
                    342: case 'q':                              /* Quiet */
                    343:     quiet = 1;
                    344:     break;
                    345:  
                    346: case 'd':                              /* debug */
                    347:     debopn("debug.log");
                    348:     break;
                    349:  
                    350: case 'p':                              /* set parity */
                    351:     if (*(xp+1)) fatal("invalid argument bundling");
                    352:     *xargv++, xargc--;
                    353:     if ((xargc < 1) || (**xargv == '-'))
                    354:        fatal("missing parity");
                    355:     switch(x = **xargv) {
                    356:        case 'e':
                    357:        case 'o':
                    358:        case 'm':
                    359:        case 's': parity = x; break;
                    360:        case 'n': parity = 0; break;
                    361:        default:  fatal("invalid parity");
                    362:         }
                    363:     break;
                    364:  
                    365: case 't':
                    366:     turn = 1;                          /* Line turnaround handshake */
                    367:     turnch = XON;                      /* XON is turnaround character */
                    368:     duplex = 1;                                /* Half duplex */
                    369:     flow = 0;                          /* No flow control */
                    370:     break;
                    371:  
                    372: default:
                    373:     fatal("invalid argument, type 'kermit -h' for help");
                    374:         }
                    375:  
                    376:     x = *++xp;                         /* See if options are bundled */
                    377:     }
                    378:     return(0);
                    379: }
                    380: 
                    381: /* Misc */
                    382:  
                    383: fatal(msg) char *msg; {                        /* Fatal error message */
                    384:     fprintf(stderr,"\r\nFatal: %s\n",msg);
                    385:     tlog(F110,"Fatal:",msg,0l);
                    386:     doexit(BAD_EXIT);                  /* Exit indicating failure */
                    387: }
                    388:  
                    389:  
                    390: ermsg(msg) char *msg; {                        /* Print error message */
                    391:     if (!quiet) fprintf(stderr,"\r\n%s - %s\n",cmerrp,msg);
                    392:     tlog(F110,"Error -",msg,0l);
                    393: }
                    394: 
                    395: /* Interactive command parser */ 
                    396:  
                    397:  
                    398: /* Top-Level Keyword Table */
                    399:  
                    400: struct keytab cmdtab[] = {
                    401:     "!",          XXSHE, 0,
                    402:     "%",          XXCOM, CM_INV,
                    403:     "bye",         XXBYE, 0,
                    404:     "c",           XXCON, CM_INV,
                    405:     "close",      XXCLO, 0,
                    406:     "connect",     XXCON, 0,
                    407:     "cwd",        XXCWD, 0,
                    408:     "dial",       XXDIAL, 0,
                    409:     "directory",   XXDIR, 0,
                    410:     "echo",        XXECH, 0,
                    411:     "exit",       XXEXI, 0,
                    412:     "finish",     XXFIN, 0,
                    413:     "get",        XXGET, 0,
                    414:     "help",       XXHLP, 0,
                    415:     "log",        XXLOG, 0,
                    416:     "quit",       XXQUI, 0,
                    417:     "r",           XXREC, CM_INV,
                    418:     "receive",    XXREC, 0,
                    419:     "remote",     XXREM, 0,
                    420:     "s",           XXSEN, CM_INV,
                    421:     "script",     XXLOGI, 0,
                    422:     "send",       XXSEN, 0,
                    423:     "server",     XXSER, 0,
                    424:     "set",        XXSET, 0,
                    425:     "show",       XXSHO, 0,
                    426:     "space",       XXSPA, 0,
                    427:     "statistics",  XXSTA, 0,
                    428:     "take",       XXTAK, 0
                    429: };
                    430: int ncmd = (sizeof(cmdtab) / sizeof(struct keytab));
                    431: 
                    432: /* Parameter keyword table */
                    433:  
                    434: struct keytab prmtab[] = {
                    435:     "baud",            XYSPEE,  CM_INV,
                    436:     "block-check",     XYCHKT,  0,
                    437:     "delay",           XYDELA,  0,
                    438:     "duplex",          XYDUPL,  0,
                    439:     "end-of-packet",    XYEOL,   CM_INV,    /* moved to send/receive */
                    440:     "escape-character", XYESC,   0,
                    441:     "file",            XYFILE,  0,
                    442:     "flow-control",    XYFLOW,  0,
                    443:     "handshake",       XYHAND,  0,
                    444:     "incomplete",      XYIFD,   0,
                    445:     "line",             XYLINE,  0,
                    446:     "modem-dialer",    XYMODM,  0,
                    447:     "packet-length",    XYLEN,   CM_INV,    /* moved to send/receive */
                    448:     "pad-character",    XYPADC,  CM_INV,    /* moved to send/receive */
                    449:     "padding",          XYNPAD,  CM_INV,    /* moved to send/receive */
                    450:     "parity",          XYPARI,  0,
                    451:     "prompt",          XYPROM,  0,
                    452:     "receive",          XYRECV,  0,
                    453:     "retry",            XYRETR,  0,
                    454:     "send",             XYSEND,  0,
                    455:     "speed",           XYSPEE,  0,
                    456:     "start-of-packet",  XYMARK,  CM_INV,    /* moved to send/receive */
                    457:     "terminal",         XYTERM,  0,
                    458:     "timeout",         XYTIMO,  CM_INV     /* moved to send/receive */
                    459: };
                    460: int nprm = (sizeof(prmtab) / sizeof(struct keytab)); /* How many parameters */
                    461:  
                    462:  
                    463: /* Remote Command Table */
                    464:  
                    465: struct keytab remcmd[] = {
                    466:     "cwd",       XZCWD, 0,
                    467:     "delete",    XZDEL, 0,
                    468:     "directory", XZDIR, 0,
                    469:     "help",      XZHLP, 0,
                    470:     "host",      XZHOS, 0,
                    471:     "space",    XZSPA, 0,
                    472:     "type",     XZTYP, 0,
                    473:     "who",      XZWHO, 0
                    474: };
                    475: int nrmt = (sizeof(remcmd) / sizeof(struct keytab));
                    476:  
                    477: struct keytab logtab[] = {
                    478:     "debugging",    LOGD, 0,
                    479:     "packets",     LOGP, 0,
                    480:     "session",      LOGS, 0,
                    481:     "transactions", LOGT, 0
                    482: };
                    483: int nlog = (sizeof(logtab) / sizeof(struct keytab));
                    484:  
                    485: /* Show command arguments */
                    486:  
                    487: #define SHPAR 0                                /* Parameters */
                    488: #define SHVER 1                                /* Versions */
                    489:  
                    490: struct keytab shotab[] = {
                    491:     "parameters", SHPAR, 0,
                    492:     "versions",   SHVER, 0
                    493: };
                    494: 
                    495: /*  C M D I N I  --  Initialize the interactive command parser  */
                    496:  
                    497: cmdini() {
                    498: 
                    499: #ifdef AMIGA
                    500:     congm();
                    501:     concb(escape);
                    502: #endif 
                    503:     tlevel = -1;                       /* Take file level */
                    504:     cmsetp("C-Kermit>");               /* Set default prompt */
                    505:  
                    506: /* Look for init file in home or current directory. */
                    507: 
                    508:     homdir = zhome();
                    509:     lp = line;
                    510:     lp[0] = '\0';
                    511:     if (homdir) {
                    512:        strcpy(lp,homdir);
                    513:        if (lp[0] == '/') strcat(lp,"/");
                    514:     }
                    515:     strcat(lp,KERMRC);
                    516: #ifdef AMIGA
                    517:     reqoff();                  /* disable requestors */
                    518: #endif
                    519:     if ((tfile[0] = fopen(line,"r")) != NULL) {
                    520:        tlevel = 0;
                    521:        debug(F110,"init file",line,0);
                    522:     }
                    523:     if (homdir && (tlevel < 0)) {
                    524:        strcpy(lp,KERMRC);
                    525:        if ((tfile[0] = fopen(line,"r")) != NULL) {
                    526:            tlevel = 0;
                    527:            debug(F110,"init file",line,0);
                    528:        } else {
                    529:            debug(F100,"no init file","",0);
                    530:         }
                    531:     }
                    532: #ifdef AMIGA
                    533:     reqpop();                          /* restore requestors */
                    534: #else
                    535:     congm();                           /* Get console tty modes */
                    536: #endif
                    537: }
                    538:  
                    539: /* Display version herald and initial prompt */
                    540: 
                    541: herald() {
                    542:     if (!backgrd) printf("%s,%s\nType ? for help\n",versio,ckxsys);
                    543: }
                    544: 
                    545:  
                    546: /*  T R A P  --  Terminal interrupt handler */
                    547:  
                    548: trap() {
                    549:     debug(F100,"terminal interrupt...","",0);
                    550:     doexit(GOOD_EXIT);                 /* Exit indicating success */
                    551: }
                    552: 
                    553: /*  S T P T R A P -- Handle SIGTSTP signals */
                    554: 
                    555: stptrap() {
                    556:     conres();                          /* Reset the console */
                    557: #ifdef SIGTSTP
                    558:     kill(0, SIGSTOP);                  /* If job control, suspend the job */
                    559: #else
                    560:     doexit(GOOD_EXIT);                 /* Probably won't happen otherwise */
                    561: #endif
                    562:     concb();                           /* Put console back in Kermit mode */
                    563: }
                    564: 
                    565: /*  P A R S E R  --  Top-level interactive command parser.  */
                    566:  
                    567: parser() {
                    568:     int xx, cbn;
                    569:     char *cbp;
                    570: 
                    571: #ifdef AMIGA
                    572:     reqres();                  /* restore AmigaDOS requestors */
                    573: #endif
                    574:     concb(escape);             /* Put console in cbreak mode. */
                    575:     conint(trap);              /* Turn on console terminal interrupts. */
                    576: /*
                    577:  sstate becomes nonzero when a command has been parsed that requires some
                    578:  action from the protocol module.  Any non-protocol actions, such as local
                    579:  directory listing or terminal emulation, are invoked directly from below.
                    580: */
                    581:     if (local && !backgrd) printf("\n"); /*** Temporary kludge ***/
                    582:     sstate = 0;                                /* Start with no start state. */
                    583:     while (sstate == 0) {              /* Parse cmds until action requested */
                    584:        while ((tlevel > -1) && feof(tfile[tlevel])) { /* If end of take */
                    585:                fclose(tfile[tlevel--]); /* file, close it. */
                    586:                cmini(ckxech);          /* and clear the cmd buffer. */
                    587:                if (tlevel < 0) {       /* Just popped out of cmd files? */
                    588:                    conint(trap);       /* Check background stuff again. */
                    589:                    return(0);          /* End of init file or whatever. */
                    590:                }
                    591:        }
                    592: debug(F101,"tlevel","",tlevel);
                    593:        if (tlevel > -1) {              /* If in take file */
                    594:            cbp = cmdbuf;               /* Get the next line. */
                    595:            cbn = CMDBL;
                    596:  
                    597: /* Loop to get next command line and all continuation lines from take file. */
                    598:  
                    599: again:     if (fgets(line,cbn,tfile[tlevel]) == NULL) continue;
                    600:            lp = line;                  /* Got one, copy it. */
                    601:            while (*cbp++ = *lp++)
                    602:                if (--cbn < 1) fatal("Command too long for internal buffer");
                    603:            if (*(cbp - 3) == '\\') {   /* Continued on next line? */
                    604:                cbp -= 3;               /* If so, back up pointer, */
                    605:                goto again;             /* go back, get next line. */
                    606:            }
                    607:            stripq(cmdbuf);             /* Strip any quotes from cmd buffer. */
                    608:  
                    609:        } else {                        /* No take file, get typein. */
                    610:  
                    611:            if (!backgrd) prompt();     /* Issue interactive prompt. */
                    612:            cmini(ckxech);
                    613:        }
                    614:        repars = 1;
                    615:        displa = 0;
                    616:        while (repars) {
                    617:            cmres();                    /* Reset buffer pointers. */
                    618:            xx = cmkey(cmdtab,ncmd,"Command","");
                    619:            debug(F101,"top-level cmkey","",xx);
                    620:            switch (docmd(xx)) {
                    621:                case -4:                /* EOF */
                    622:                    doexit(GOOD_EXIT);  /* ...exit successfully */
                    623:                case -1:                /* Reparse needed */
                    624:                    repars = 1;
                    625:                    continue;
                    626:                case -2:                /* Invalid command given */
                    627:                    if (backgrd)        /* if in background, terminate */
                    628:                        fatal("Kermit command error in background execution");
                    629:                    if (tlevel > -1) {  /* If in take file, quit */
                    630:                        ermsg("Kermit command error: take file terminated.");
                    631:                        fclose(tfile[tlevel]);
                    632:                        tlevel--;
                    633:                    }
                    634:                    cmini(ckxech);      /* (fall thru) */
                    635:                case -3:                /* Empty command OK at top level */
                    636:                default:                /* Anything else (fall thru) */
                    637:                    repars = 0;         /* No reparse, get new command. */
                    638:                    continue;
                    639:             }
                    640:         }
                    641:     }
                    642: /* Got an action command; disable terminal interrupts and return start state */
                    643:  
                    644:     if (!local) connoi();              /* Interrupts off only if remote */
                    645:     return(sstate);
                    646: }
                    647: 
                    648: /*  D O E X I T  --  Exit from the program.  */
                    649:  
                    650: doexit(exitstat) int exitstat; {
                    651:     
                    652:     ttclos();                          /* Close external line, if any */
                    653:     if (local) {
                    654:        strcpy(ttname,dftty);           /* Restore default tty */
                    655:        local = dfloc;                  /* And default remote/local status */
                    656:     }
                    657:     if (!quiet) conres();              /* Restore console terminal. */
                    658:     if (!quiet) connoi();              /* Turn off console interrupt traps. */
                    659:  
                    660:     if (deblog) {                      /* Close any open logs. */
                    661:        debug(F100,"Debug Log Closed","",0);
                    662:        *debfil = '\0';
                    663:        deblog = 0;
                    664:        zclose(ZDFILE);
                    665:     }
                    666:     if (pktlog) {
                    667:        *pktfil = '\0';
                    668:        pktlog = 0;
                    669:        zclose(ZPFILE);
                    670:     }
                    671:     if (seslog) {
                    672:        *sesfil = '\0';
                    673:        seslog = 0;
                    674:        zclose(ZSFILE);
                    675:     }
                    676:     if (tralog) {
                    677:        tlog(F100,"Transaction Log Closed","",0l);
                    678:        *trafil = '\0';
                    679:        tralog = 0;
                    680:        zclose(ZTFILE);
                    681:     }
                    682:     syscleanup();
                    683:     exit(exitstat);                            /* Exit from the program. */
                    684: }
                    685: 
                    686: /*  B L D L E N  --  Make length-encoded copy of string  */
                    687:  
                    688: char *
                    689: bldlen(str,dest) char *str, *dest; {
                    690:     int len;
                    691:     len = strlen(str);
                    692:     *dest = tochar(len);
                    693:     strcpy(dest+1,str);
                    694:     return(dest+len+1);
                    695: }
                    696:  
                    697:  
                    698: /*  S E T G E N  --  Construct a generic command  */
                    699:  
                    700: setgen(type,arg1,arg2,arg3) char type, *arg1, *arg2, *arg3; {
                    701:     char *upstr, *cp;
                    702:  
                    703:     cp = cmdstr;
                    704:     *cp++ = type;
                    705:     *cp = NUL;
                    706:     if (*arg1 != NUL) {
                    707:        upstr = bldlen(arg1,cp);
                    708:        if (*arg2 != NUL) {
                    709:            upstr = bldlen(arg2,upstr);
                    710:            if (*arg3 != NUL) bldlen(arg3,upstr);
                    711:        }
                    712:     }
                    713:     cmarg = cmdstr;
                    714:     debug(F110,"setgen",cmarg,0);
                    715:  
                    716:     return('g');
                    717: }
                    718: 
                    719: /*  D O C M D  --  Do a command  */
                    720:  
                    721: /*
                    722:  Returns:
                    723:    -2: user typed an illegal command
                    724:    -1: reparse needed
                    725:     0: parse was successful (even tho command may have failed).
                    726: */ 
                    727:  
                    728: docmd(cx) int cx; {
                    729:     int x, y;
                    730:     char *s;
                    731:  
                    732:     switch (cx) {
                    733:  
                    734: case -4:                               /* EOF */
                    735:     if (!quiet && !backgrd) printf("\r\n");
                    736:     doexit(GOOD_EXIT);
                    737: case -3:                               /* Null command */
                    738:     return(0);
                    739: case -2:                               /* Error */
                    740: case -1:                               /* Reparse needed */
                    741:     return(cx);
                    742:  
                    743: case XXBYE:                            /* bye */
                    744:     if ((x = cmcfm()) < 0) return(x);
                    745:     if (!local) {
                    746:        printf("You have to 'set line' first\n");
                    747:        return(0);
                    748:     }
                    749:     sstate = setgen('L',"","","");
                    750:     return(0);
                    751:  
                    752: case XXCOM:                            /* comment */
                    753:     if ((x = cmtxt("Text of comment line","",&s)) < 0) return(x);
                    754:     return(0);
                    755:  
                    756: case XXCON:                            /* connect */
                    757:     if ((x = cmcfm()) < 0) return(x);
                    758:     return(doconect());
                    759:  
                    760: case XXCWD:
                    761: #ifdef AMIGA
                    762:     if (cmtxt("Name of local directory, or carriage return","",&s) < 0)
                    763:        return(-1);
                    764:     /* if no name, just print directory name */
                    765:     if (*s) {
                    766:        if (chdir(s)) perror(s);
                    767:        cwdf = 1;
                    768:     }
                    769:     if (getcwd(line, sizeof(line)) == NULL)
                    770:        printf("Current directory name not available.\n");
                    771:     else
                    772:        if (!backgrd) printf("%s\n", line);
                    773: #else
                    774:     if (cmtxt("Name of local directory, or carriage return",homdir,&s) < 0)
                    775:        return(-1);    
                    776:     if (chdir(s)) perror(s);
                    777:     cwdf = 1;
                    778:     system(PWDCMD);
                    779: #endif
                    780:     return(0);
                    781: 
                    782: case XXCLO:
                    783:     x = cmkey(logtab,nlog,"Which log to close","");
                    784:     if (x == -3) {
                    785:        printf("?You must tell which log\n");
                    786:        return(-2);
                    787:     }
                    788:     if (x < 0) return(x);
                    789:     if ((y = cmcfm()) < 0) return(y);
                    790:     switch (x) {
                    791:  
                    792:        case LOGD:
                    793:            if (deblog == 0) {
                    794:                printf("?Debugging log wasn't open\n");
                    795:                return(0);
                    796:            }
                    797:            *debfil = '\0';
                    798:            deblog = 0;
                    799:            return(zclose(ZDFILE));
                    800:  
                    801:        case LOGP:
                    802:            if (pktlog == 0) {
                    803:                printf("?Packet log wasn't open\n");
                    804:                return(0);
                    805:            }
                    806:            *pktfil = '\0';
                    807:            pktlog = 0;
                    808:            return(zclose(ZPFILE));
                    809:  
                    810:        case LOGS:
                    811:            if (seslog == 0) {
                    812:                printf("?Session log wasn't open\n");
                    813:                return(0);
                    814:            }
                    815:            *sesfil = '\0';
                    816:            seslog = 0;
                    817:            return(zclose(ZSFILE));
                    818:  
                    819:        case LOGT:
                    820:            if (tralog == 0) {
                    821:                printf("?Transaction log wasn't open\n");
                    822:                return(0);
                    823:            }
                    824:            *trafil = '\0';
                    825:            tralog = 0;
                    826:            return(zclose(ZTFILE));
                    827:  
                    828:        default:
                    829:            printf("\n?Unexpected log designator - %ld\n", x);
                    830:            return(0);
                    831:     }
                    832: 
                    833: case XXDIAL:                           /* dial number */
                    834:     if ((x = cmtxt("Number to be dialed","",&s)) < 0) return(x);
                    835:     return(ckdial(s));
                    836:  
                    837: case XXDIR:                            /* directory */
                    838: #ifdef AMIGA
                    839:     if ((x = cmtxt("Directory/file specification","",&s)) < 0) return(x);
                    840: #else
                    841: #ifdef datageneral
                    842:     if ((x = cmtxt("Directory/file specification","+",&s)) < 0) return(x);
                    843: #else
                    844:     if ((x = cmtxt("Directory/file specification",".",&s)) < 0) return(x);
                    845: #endif
                    846: #endif
                    847:     lp = line;
                    848:     sprintf(lp,"%s %s",DIRCMD,s);
                    849:     system(line);
                    850:     return(0);
                    851:  
                    852:  
                    853: case XXECH:                            /* echo */
                    854:     if ((x = cmtxt("Material to be echoed","",&s)) < 0) return(x);
                    855:     for ( ; *s; s++) {
                    856:        if ((x = *s) == 0134) {         /* Convert octal escapes */
                    857:            s++;                        /* up to 3 digits */
                    858:            for (x = y = 0; *s >= '0' && *s <= '7' && y < 3; s++,y++) {
                    859:                x = x * 8 + (int) *s - 48;
                    860:            }
                    861:            s--;
                    862:         }
                    863:        putchar(x);
                    864:     }
                    865:     printf("\n");
                    866:     return(0);
                    867:  
                    868: case XXQUI:                            /* quit, exit */
                    869: case XXEXI:
                    870:     if ((x = cmcfm()) > -1) doexit(GOOD_EXIT);
                    871:     else return(x);
                    872:  
                    873: case XXFIN:                            /* finish */
                    874:     if ((x = cmcfm()) < 0) return(x);
                    875:     if (!local) {
                    876:        printf("You have to 'set line' first\n");
                    877:        return(0);
                    878:     }
                    879:     sstate = setgen('F',"","","");
                    880:     return(0);
                    881: 
                    882: case XXGET:                            /* get */
                    883:     if (!local) {
                    884:        printf("\nYou have to 'set line' first\n");
                    885:        return(0);
                    886:     }
                    887:     x = cmtxt("Name of remote file(s), or carriage return","",&cmarg);
                    888:     if ((x == -2) || (x == -1)) return(x);
                    889:  
                    890: /* If foreign file name omitted, get foreign and local names separately */
                    891:  
                    892:     x = 0;                             /* For some reason cmtxt returns 1 */
                    893:     if (*cmarg == NUL) {
                    894:  
                    895:        if (tlevel > -1) {              /* Input is from take file */
                    896:  
                    897:            if (fgets(line,100,tfile[tlevel]) == NULL)
                    898:                fatal("take file ends prematurely in 'get'");
                    899: debug(F110,"take-get 2nd line",line,0);
                    900:            stripq(line);
                    901:            for (x = strlen(line);
                    902:                 x > 0 && (line[x-1] == '\n' || line[x-1] == '\r');
                    903:                 x--)
                    904:                line[x-1] = '\0';
                    905:            cmarg = line;
                    906:            if (fgets(cmdbuf,CMDBL,tfile[tlevel]) == NULL)
                    907:                fatal("take file ends prematurely in 'get'");
                    908:            stripq(cmdbuf);
                    909:            for (x = strlen(cmdbuf);
                    910:                 x > 0 && (cmdbuf[x-1] == '\n' || cmdbuf[x-1] == '\r');
                    911:                 x--)
                    912:                cmdbuf[x-1] = '\0';
                    913:            if (*cmdbuf == NUL) cmarg2 = line; else cmarg2 = cmdbuf;
                    914:             x = 0;                     /* Return code */
                    915: 
                    916:         } else {                       /* Input is from terminal */
                    917:  
                    918:            char psave[40];             /* Save old prompt */
                    919:            cmsavp(psave,40);
                    920:            cmsetp(" Remote file specification: "); /* Make new one */
                    921:            cmini(ckxech);
                    922:            x = -1;
                    923:            if (!backgrd) prompt();
                    924:            while (x == -1) {           /* Prompt till they answer */
                    925:                x = cmtxt("Name of remote file(s)","",&cmarg);
                    926:                debug(F111," cmtxt",cmarg,x);
                    927:            }
                    928:            if (x < 0) {
                    929:                cmsetp(psave);
                    930:                return(x);
                    931:            }
                    932:            if (*cmarg == NUL) {        /* If user types a bare CR, */
                    933:                printf("(cancelled)\n"); /* Forget about this. */
                    934:                cmsetp(psave);          /* Restore old prompt, */
                    935:                return(0);              /* and return. */
                    936:            }
                    937:            strcpy(line,cmarg);         /* Make a safe copy */
                    938:            cmarg = line;
                    939:            cmsetp(" Local name to store it under: ");  /* New prompt */
                    940:            cmini(ckxech);
                    941:            x = -1;
                    942:            if (!backgrd) prompt();
                    943:            while (x == -1) {           /* Again, parse till answered */
                    944:                x = cmofi("Local file name","",&cmarg2);
                    945:            }
                    946:            if (x == -3) {                      /* If bare CR, */
                    947:                printf("(cancelled)\n");        /* escape from this... */
                    948:                cmsetp(psave);                  /* Restore old prompt, */
                    949:                return(0);                      /* and return. */
                    950:            } else if (x < 0) return(x);        /* Handle parse errors. */
                    951:            
                    952:            x = -1;                     /* Get confirmation. */
                    953:            while (x == -1) x = cmcfm();
                    954:            cmsetp(psave);              /* Restore old prompt. */
                    955:         }
                    956:     }
                    957:     if (x == 0) {                      /* Good return from cmtxt or cmcfm, */
                    958:        sstate = 'r';                   /* set start state. */
                    959:        if (local) displa = 1;
                    960:     }
                    961:     return(x);
                    962: 
                    963: case XXHLP:                            /* Help */
                    964:     x = cmkey(cmdtab,ncmd,"C-Kermit command","help");
                    965:     return(dohlp(x));
                    966:  
                    967: case XXLOG:                            /* Log */
                    968:     x = cmkey(logtab,nlog,"What to log","");
                    969:     if (x == -3) {
                    970:        printf("?You must specify what is to be logged\n");
                    971:        return(-2);
                    972:     }
                    973:     if (x < 0) return(x);
                    974:     return(dolog(x));
                    975:  
                    976: case XXLOGI:                           /* Send script remote system */
                    977:     if ((x = cmtxt("Text of login script","",&s)) < 0) return(x);
                    978:     return( login(s) );                        /* Return 0=completed, -2=failed */
                    979:  
                    980: case XXREC:                            /* Receive */
                    981:     cmarg2 = "";
                    982:     x = cmofi("Name under which to store the file, or CR","",&cmarg2);
                    983:     if ((x == -1) || (x == -2)) return(x);
                    984:     debug(F111,"cmofi cmarg2",cmarg2,x);
                    985:     if ((x = cmcfm()) < 0) return(x);
                    986:     sstate = 'v';
                    987:     if (local) displa = 1;
                    988:     return(0);
                    989:  
                    990: case XXREM:                            /* Remote */
                    991:     if (!local) {
                    992:        printf("\nYou have to 'set line' first\n");
                    993:        return(-2);
                    994:     }
                    995:     x = cmkey(remcmd,nrmt,"Remote Kermit server command","");
                    996:     if (x == -3) {
                    997:        printf("?You must specify a command for the remote server\n");
                    998:        return(-2);
                    999:     }
                   1000:     return(dormt(x));
                   1001: 
                   1002: case XXSEN:                            /* Send */
                   1003:     cmarg = cmarg2 = "";
                   1004:     if ((x = cmifi("File(s) to send","",&s,&y)) < 0) {
                   1005:        if (x == -3) {
                   1006:            printf("?A file specification is required\n");
                   1007:            return(-2);
                   1008:        }
                   1009:        return(x);
                   1010:     }
                   1011:     nfils = -1;                                /* Files come from internal list. */
                   1012:     strcpy(line,s);                    /* Save copy of string just parsed. */
                   1013:     debug(F101,"Send: wild","",y);
                   1014:     *cmarg2 = '\0';                    /* Initialize send-as name */
                   1015:     if (y == 0) {
                   1016:        if ((x = cmtxt("Name to send it with","",&cmarg2)) < 0) return(x);
                   1017:     } else {
                   1018:        if ((x = cmcfm()) < 0) return(x);
                   1019:     }
                   1020:     cmarg = line;                      /* File to send */
                   1021:     debug(F110,"Sending:",cmarg,0);
                   1022:     if (*cmarg2 != '\0') debug(F110," as:",cmarg2,0);
                   1023:     sstate = 's';                      /* Set start state */
                   1024:     if (local) displa = 1;
                   1025:     return(0);
                   1026:  
                   1027: case XXSER:                            /* Server */
                   1028:     if ((x = cmcfm()) < 0) return(x);
                   1029:     sstate = 'x';
                   1030:     if (local) displa = 1;
                   1031: #ifdef AMIGA
                   1032:     reqoff();                          /* no DOS requestors while server */
                   1033: #endif
                   1034:     return(0);
                   1035:  
                   1036: case XXSET:                            /* Set */
                   1037:     x = cmkey(prmtab,nprm,"Parameter","");
                   1038:     if (x == -3) {
                   1039:        printf("?You must specify a parameter to set\n");
                   1040:        return(-2);
                   1041:     }
                   1042:     if (x < 0) return(x);
                   1043:     return(doprm(x));
                   1044:     
                   1045: /* XXSHE code by H. Fischer; copyright rights assigned to Columbia Univ */
                   1046: /*
                   1047:  Adapted to use getpwuid to find login shell because many systems do not
                   1048:  have SHELL in environment, and to use direct calling of shell rather
                   1049:  than intermediate system() call. -- H. Fischer
                   1050: */
                   1051: case XXSHE:                            /* Local shell command */
                   1052:     {
                   1053:     int pid;
                   1054: #ifdef AMIGA
                   1055:     if (cmtxt("Command to execute","",&s) < 0) return(-1);
                   1056: #else
                   1057:     if (cmtxt("Unix shell command to execute","",&s) < 0) return(-1);
                   1058: #endif
                   1059:     conres();                          /* Make console normal  */
                   1060: #ifdef AMIGA
                   1061:     system(s);
                   1062: #else
                   1063: #ifdef MSDOS
                   1064:     zxcmd(s);
                   1065: #else
                   1066: #ifdef vax11c
                   1067:  
                   1068:     system(s);                         /* Best we can do for VMS? */
                   1069: #else                                  /* All Unix systems... */
                   1070: #ifdef datageneral
                   1071:     if (*s == NUL)                     /* Interactive shell requested? */
                   1072: #ifdef mvux
                   1073:        system("/bin/sh ");
                   1074: #else
                   1075:         system("x :cli prefix Kermit_Baby:");
                   1076: #endif
                   1077:     else                               /* Otherwise, */
                   1078:         system(s);                     /* Best for aos/vs?? */
                   1079:  
                   1080: #else                                  /* All Unix systems... */
                   1081: #ifdef apollo
                   1082:     if ((pid = vfork()) == 0) {                /* Make child quickly */
                   1083:        char *shpath, *shname, *shptr;  /* For finding desired shell */
                   1084: 
                   1085:         if ((shpath = getenv("SHELL")) == NULL) shpath = "/com/sh";
                   1086: #else
                   1087:  
                   1088:     if ((pid = fork()) == 0) {         /* Make child */
                   1089:        char *shpath, *shname, *shptr;  /* For finding desired shell */
                   1090:        struct passwd *p;
                   1091:        extern struct passwd * getpwuid();
                   1092:        extern int getuid();
                   1093:        char *defShel = "/bin/sh";      /* Default */
                   1094:  
                   1095:        p = getpwuid( getuid() );       /* Get login data */
                   1096:        if ( p == (struct passwd *) NULL || !*(p->pw_shell) )
                   1097:            shpath = defShel;
                   1098:        else
                   1099:            shpath = p->pw_shell;
                   1100: #endif
                   1101:        shptr = shname = shpath;
                   1102:        while (*shptr != '\0')
                   1103:            if (*shptr++ == '/') shname = shptr;
                   1104: 
                   1105: /* Remove following uid calls if they cause trouble */
                   1106: #ifdef BSD4
                   1107:        setegid(getgid());              /* Override 4.3BSD csh security */
                   1108:        seteuid(getuid());              /*  checks. */
                   1109: #endif
                   1110: 
                   1111:        if (*s == NUL)                  /* Interactive shell requested? */
                   1112:            execl(shpath,shname,"-i",NULL);    /* Yes, do that */
                   1113:        else                            /* Otherwise, */
                   1114:            execl(shpath,shname,"-c",s,NULL); /* exec the given command */
                   1115:        exit(BAD_EXIT); }               /* Just punt if it didn't work */
                   1116:  
                   1117:     else {                             /* Parent */
                   1118:  
                   1119:        int wstat;                      /* Kermit must wait for child */
                   1120:        SIGTYP (*istat)(), (*qstat)();
                   1121:  
                   1122:        istat = signal(SIGINT,SIG_IGN); /* Let the fork handle keyboard */
                   1123:        qstat = signal(SIGQUIT,SIG_IGN); /* interrupts itself... */
                   1124:  
                   1125:        while (((wstat = wait((int *)0)) != pid) && (wstat != -1))
                   1126:                                        /* Wait for fork */
                   1127:        signal(SIGINT,istat);           /* Restore interrupts */
                   1128:        signal(SIGQUIT,qstat);
                   1129:     }
                   1130: #endif
                   1131: #endif
                   1132: #endif
                   1133: #endif
                   1134:     concb(escape);                     /* Console back in cbreak mode */
                   1135:     return(0);
                   1136: }
                   1137: 
                   1138: case XXSHO:                            /* Show */
                   1139:     x = cmkey(shotab,2,"","parameters");
                   1140:     if (x < 0) return(x);
                   1141:     if ((y = cmcfm()) < 0) return(y);
                   1142:     switch (x) {
                   1143:  
                   1144:        case SHPAR:
                   1145:            shopar();
                   1146:            break;
                   1147:  
                   1148:        case SHVER:
                   1149:            printf("\nVersions:\n %s\n %s\n",versio,protv);
                   1150:            printf(" %s\n",fnsv);
                   1151:            printf(" %s\n %s\n",cmdv,userv);
                   1152:            printf(" %s for%s\n",ckxv,ckxsys);
                   1153:            printf(" %s for%s\n",ckzv,ckzsys);
                   1154:            printf(" %s\n",connv);
                   1155:            printf(" %s\n %s\n\n",dialv,loginv);
                   1156:            break;
                   1157:  
                   1158:        default:
                   1159:            printf("\nNothing to show...\n");
                   1160:            break;
                   1161:     }
                   1162:     return(0);
                   1163:  
                   1164: case XXSPA:                            /* space */
                   1165: #ifdef datageneral
                   1166:     /* The DG can take an argument after its "space" command. */
                   1167:     if ((x = cmtxt("Confirm, or local directory name","",&s)) < 0) return(x);
                   1168:     if (*s == NULL) system(SPACMD);
                   1169:     else {
                   1170:        char *cp;
                   1171:        cp = alloc(strlen(s) + 7);      /* For "space *s" */
                   1172:        strcpy(cp,"space "), strcat(cp,s);
                   1173:        system(cp);
                   1174:        free(cp);
                   1175:     }
                   1176: #else
                   1177:     if ((x = cmcfm()) < 0) return(x);
                   1178:     system(SPACMD);
                   1179: #endif
                   1180:     return(0);
                   1181:  
                   1182: case XXSTA:                            /* statistics */
                   1183:     if ((x = cmcfm()) < 0) return(x);
                   1184:     return(dostat());
                   1185: 
                   1186: case XXTAK:                            /* take */
                   1187:     if (tlevel > MAXTAKE-1) {
                   1188:        printf("?Take files nested too deeply\n");
                   1189:        return(-2);
                   1190:     }
                   1191:     if ((y = cmifi("C-Kermit command file","",&s,&x)) < 0) { 
                   1192:        if (y == -3) {
                   1193:            printf("?A file specification is required\n");
                   1194:            return(-2);
                   1195:        } else return(y);
                   1196:     }
                   1197:     if (x != 0) {
                   1198:        printf("?Wildcards not allowed in command file name\n");
                   1199:        return(-2);
                   1200:     }
                   1201:     strcpy(line,s);                    /* Make a safe copy of the string */
                   1202:     if ((y = cmcfm()) < 0) return(y);
                   1203:     if ((tfile[++tlevel] = fopen(line,"r")) == NULL) {
                   1204:        perror(line);
                   1205:        debug(F110,"Failure to open",line,0);
                   1206:        tlevel--;
                   1207:     }
                   1208:     return(0);
                   1209:  
                   1210: default:
                   1211:     printf("Not available - %s\n",cmdbuf);
                   1212:     return(-2);
                   1213:     }
                   1214: }
                   1215: 
                   1216: /*  D O C O N E C T  --  Do the connect command  */
                   1217:  
                   1218: /*  Note, we don't call this directly from dial, because we need to give */
                   1219: /*  the user a chance to change parameters (e.g. parity) after the */
                   1220: /*  connection is made. */
                   1221:  
                   1222: doconect() {
                   1223:     int x;
                   1224:     conres();                          /* Put console back to normal */
                   1225:     x = conect();                      /* Connect */
                   1226:     concb(escape);                     /* Put console into cbreak mode, */
                   1227:     return(x);                         /* for more command parsing. */
                   1228: }

unix.superglobalmegacorp.com

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