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: }

Defined functions

bldlen defined in line 631; used 3 times
cmdini defined in line 474; used 1 times
cmdlin defined in line 143; used 1 times
debopn defined in line 1273; used 2 times
doarg defined in line 197; used 1 times
docmd defined in line 671; used 1 times
doconect defined in line 1178; used 1 times
doexit defined in line 594; used 11 times
dolog defined in line 1189; used 1 times
ermsg defined in line 369; used 3 times
fatal defined in line 362; used 32 times
parser defined in line 518; used 2 times
setgen defined in line 643; used 9 times
shopar defined in line 1096; used 1 times
trap defined in line 511; used 1 times

Defined variables

action defined in line 126; used 27 times
cflg defined in line 125; used 4 times
cmdstr defined in line 135; used 2 times
cmdtab defined in line 379; used 3 times
cwdf defined in line 129; used 1 times
debfil defined in line 119; used 5 times
homdir defined in line 134; used 5 times
line defined in line 118; used 29 times
logtab defined in line 454; used 3 times
lp defined in line 118; used 13 times
n defined in line 124; never used
ncmd defined in line 409; used 2 times
nlog defined in line 460; used 2 times
nprm defined in line 437; used 2 times
nrmt defined in line 452; used 2 times
pktfil defined in line 120; used 5 times
prmtab defined in line 413; used 3 times
remcmd defined in line 442; used 3 times
repars defined in line 127; used 4 times
sesfil defined in line 121; used 7 times
shotab defined in line 467; used 1 times
tlevel defined in line 128; used 21 times
trafil defined in line 122; used 5 times
userv defined in line 1; used 1 times

Defined macros

KERMRC defined in line 82; used 4 times
MAXTAKE defined in line 131; used 2 times
SHPAR defined in line 464; used 1 times
SHVER defined in line 465; used 1 times
Last modified: 1985-08-14
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3400
Valid CSS Valid XHTML 1.0 Strict