Annotation of 43BSD/contrib/kermit/ckuusr.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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