Annotation of researchv10dc/lbin/kermit/ckuusr.c, revision 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.