C-KERMIT (Part 5 of 10)

gregg at okstate.UUCP gregg at okstate.UUCP
Fri Mar 8 17:47:00 AEST 1985



echo x - ckuser.c
sed '1,$s/^X//' <<\!FUNKY!STUFF! > ckuser.c
Xchar *userv = "User Interface V4.2(038), 5 Mar 85";
X
X/*  C K U S E R --  "User Interface" for Unix Kermit (Part 1)  */
X
X/*  Frank da Cruz, Columbia University Center for Computing Activities, 1985 */
X/*
X The ckuser module contains the terminal input and output functions for Unix
X Kermit.  It includes a simple Unix-style command line parser as well as
X an interactive prompting keyword command parser.  It depends on the existence
X of Unix facilities like fopen, fgets, feof, (f)printf, argv/argc, etc.  Other
X functions that are likely to vary among Unix implementations -- like setting
X terminal modes or interrupts -- are invoked via calls to functions that are
X defined in the system-dependent modules, ck[xz]*.c.
X
X The command line parser processes any arguments found on the command line,
X as passed to main() via argv/argc.  The interactive parser uses the facilities
X of the cmd package (developed for this program, but usable by any program).
X
X Any command parser may be substituted for this one.  The only requirements
X for the Kermit command parser are these:
X
X 1. Set parameters via global variables like duplex, speed, ttname, etc.
X    See ckmain.c for the declarations and descriptions of these variables.
X
X 2. If a command can be executed without the use of Kermit protocol, then
X    execute the command directly and set the variable sstate to 0. Examples
X    include 'set' commands, local directory listings, the 'connect' command.
X
X 3. If a command requires the Kermit protocol, set the following variables:
X
X    sstate                             string data
X      'x' (enter server mode)            (none)
X      'r' (send a 'get' command)         cmarg, cmarg2
X      'v' (enter receive mode)           cmarg2
X      'g' (send a generic command)       cmarg
X      's' (send files)                   nfils, cmarg & cmarg2 OR cmlist
X      'c' (send a remote host command)   cmarg
X
X    cmlist is an array of pointers to strings.
X    cmarg, cmarg2 are pointers to strings.
X    nfils is an integer.    
X
X    cmarg can be a filename string (possibly wild), or
X       a pointer to a prefabricated generic command string, or
X       a pointer to a host command string.
X    cmarg2 is the name to send a single file under, or
X       the name under which to store an incoming file; must not be wild.
X    cmlist is a list of nonwild filenames, such as passed via argv.
X    nfils is an integer, interpreted as follows:
X      -1: argument string is in cmarg, and should be expanded internally.
X       0: stdin.
X      >0: number of files to send, from cmlist.
X
X The screen() function is used to update the screen during file transfer.
X The tlog() function maintains a transaction log.
X The debug() function maintains a debugging log.
X The intmsg() and chkint() functions provide the user i/o for interrupting
X   file transfers.
X*/
X
X/* Includes */
X
X#include "ckermi.h"
X#include "ckcmd.h"
X#include "ckuser.h"
X
X/* External Kermit Variables, see ckmain.c for description. */
X
Xextern int size, spsiz, npad, timint, speed, local, server, image, flow,
X  displa, binary, fncnv, delay, parity, deblog, escape, xargc,
X  turn, duplex, cxseen, czseen, nfils, ckxech, pktlog, seslog, tralog, stdouf,
X  turnch, chklen, bctr, bctu, fsize, dfloc, mdmtyp,
X  rptflg, ebqflg, warn, quiet, cnflg, timef, mypadn;
X
Xextern long filcnt, tlci, tlco, ffc, tfc;
X
Xextern char *versio, *protv, *ckxv, *ckzv, *fnsv, *connv, *dftty, *cmdv;
Xextern char *ckxsys, *ckzsys, *cmarg, *cmarg2, **xargv, **cmlist;
Xextern char mystch, sstate, mypadc, padch, eol, ctlq, filnam[], ttname[];
Xchar *strcpy();
X
X/* Declarations from cmd package */
X
Xextern char cmdbuf[];			/* Command buffer */
X
X/* Declarations from ckz??? module */
X
Xextern char *SPACMD, *zhome();		/* Space command, home directory. */
Xextern int backgrd;			/* Kermit executing in background */
X
X/* The background flag is set by ckxunx.c (via conint() ) to note whether */
X/* this kermit is executing in background ('&' on shell command line).    */
X
X
X/* Variables and symbols local to this module */
X
Xchar line[100], *lp;			/* Character buffer for anything */
Xchar debfil[50];			/* Debugging log file name */
Xchar pktfil[50];			/* Packet log file name */
Xchar sesfil[50];			/* Session log file name */
Xchar trafil[50];			/* Transaction log file name */
X
Xint n,					/* General purpose int */
X    cflg,				/* Command-line connect cmd given */
X    action,				/* Action selected on command line*/
X    ncmd,				/* Number of commands */
X    nprm,	    	    	    	/* Number of parameters */
X    nrmt,				/* Number of remote commands */
X    repars,				/* Reparse needed */
X    tlevel,				/* Take command level */
X    cwdf = 0;				/* CWD has been done */
X
X#define MAXTAKE 20			/* Maximum nesting of TAKE files */
XFILE *tfile[MAXTAKE];			/* File pointers for TAKE command */
X
Xchar *homdir;				/* Pointer to home directory string */
Xchar cmdstr[100];
X
X/*  C M D L I N  --  Get arguments from command line  */
X/*
X Simple Unix-style command line parser, conforming with 'A Proposed Command
X Syntax Standard for Unix Systems', Hemenway & Armitage, Unix/World, Vol.1,
X No.3, 1984.
X*/
Xcmdlin() {
X    char x;
X    cmarg = "";				/* Initialize. */
X    cmarg2 = "";
X    action = cflg = 0;
X
X    while (--xargc > 0) {		/* Go through command line words */
X	*xargv++;
X	debug(F111,"xargv",*xargv,xargc);
X    	if (**xargv == '-') {		/* Got an option (begins with dash) */
X	    x = *(*xargv+1);		/* Get the option letter */
X	    x = doarg(x);		/* Go handle the option */
X	    if (x < 0) exit(0);
X    	} else {			/* No dash where expected */
X	    usage();
X	    exit(1);
X	}
X    }
X    debug(F101,"action","",action);
X    if (!local) {
X	if ((action == 'g') || (action == 'r') ||
X	    (action == 'c') || (cflg != 0))
X	    fatal("-l and -b required");
X    }
X    if (*cmarg2 != 0) {
X	if ((action != 's') && (action != 'r') &&
X	    (action != 'v'))
X	    fatal("-a without -s, -r, or -g");
X    }
X    if ((action == 'v') && (stdouf) && (!local)) {
X    	if (isatty(1))
X	    fatal("unredirected -k can only be used in local mode");
X    }
X    if ((action == 's') || (action == 'v') ||
X    	(action == 'r') || (action == 'x')) {
X	if (local) displa = 1;
X	if (stdouf) displa = 0;
X    }
X
X    if (quiet) displa = 0;		/* No display if quiet requested */
X
X    if (cflg) {
X	conect();			/* Connect if requested */
X	if (action == 0) {
X	    if (cnflg) conect();	/* And again if requested */
X	    doexit(0);			/*  exit with status = 0 */
X	}
X    }
X    if (displa) concb(escape);		/* (for console "interrupts") */
X    return(action);			/* Then do any requested protocol */
X}
X
X/*  D O A R G  --  Do a command-line argument.  */
X
Xdoarg(x) char x; {
X    int z; char *xp;
X
X    xp = *xargv+1;			/* Pointer for bundled args */
X    while (x) {
X	switch (x) {
X
Xcase 'x':				/* server */
X    if (action) fatal("conflicting actions");
X    action = 'x';
X    break;
X
Xcase 'f':
X    if (action) fatal("conflicting actions");
X    action = setgen('F',"","","");
X    break;
X
Xcase 'r':				/* receive */
X    if (action) fatal("conflicting actions");
X    action = 'v';
X    break;
X
Xcase 'k':				/* receive to stdout */
X    if (action) fatal("conflicting actions");
X    stdouf = 1;
X    action = 'v';
X    break;
X
Xcase 's': 				/* send */
X    if (action) fatal("conflicting actions");
X    if (*(xp+1)) fatal("invalid argument bundling after -s");
X    z = nfils = 0;			/* Initialize file counter, flag */
X    cmlist = xargv+1;			/* Remember this pointer */
X    while (--xargc > 0) {		/* Traverse the list */	
X	*xargv++;
X	if (**xargv == '-') {		/* Check for sending stdin */
X	    if (strcmp(*xargv,"-") != 0) break;
X	    z++;
X        }
X	nfils++;			/* Bump file counter */
X    }
X    xargc++, *xargv--;			/* Adjust argv/argc */
X    if (nfils < 1) fatal("missing filename for -s");
X    if (z > 1) fatal("-s: too many -'s");
X    if (z == 1) {
X	if (nfils == 1) nfils = 0;
X	else fatal("invalid mixture of filenames and '-' in -s");
X    }
X    if (nfils == 0) {
X	if (isatty(0)) fatal("sending from terminal not allowed");
X    }
X    debug(F101,*xargv,"",nfils);
X    action = 's';
X    break;
X
X/* cont'd... */
X
X/* ...doarg(), cont'd */
X
Xcase 'g':				/* get */
X    if (action) fatal("conflicting actions");
X    if (*(xp+1)) fatal("invalid argument bundling after -g");
X    *xargv++, xargc--;
X    if ((xargc == 0) || (**xargv == '-'))
X    	fatal("missing filename for -g");
X    cmarg = *xargv;
X    action = 'r';
X    break;
X
Xcase 'c':				/* connect before */
X    cflg = 1;
X    break;
X
Xcase 'n':				/* connect after */
X    cnflg = 1;
X    break;
X
Xcase 'h':				/* help */
X    usage();
X    return(-1);
X
Xcase 'a':				/* "as" */
X    if (*(xp+1)) fatal("invalid argument bundling after -a");
X    *xargv++, xargc--;
X    if ((xargc < 1) || (**xargv == '-'))
X    	fatal("missing name in -a");
X    cmarg2 = *xargv;
X    break;
X
Xcase 'l':				/* set line */
X    if (*(xp+1)) fatal("invalid argument bundling after -l");
X    *xargv++, xargc--;
X    if ((xargc < 1) || (**xargv == '-'))
X    	fatal("communication line device name missing");
X    strcpy(ttname,*xargv);
X    if (strcmp(ttname,dftty) == 0) local = dfloc; else local = 1;
X    break;
X
Xcase 'b':   	    			/* set baud */
X    if (*(xp+1)) fatal("invalid argument bundling");
X    *xargv++, xargc--;
X    if ((xargc < 1) || (**xargv == '-'))
X    	fatal("missing baud");
X    z = atoi(*xargv);			/* Convert to number */
X    if (chkspd(z) > -1) speed = z;	/* Check it */
X    	else fatal("unsupported baud rate");
X    break;
X
Xcase 'i':				/* Treat files as binary */
X    binary = 1;
X    break;
X
X/* cont'd... */
X
X/* ...doarg(), cont'd */
X
X
Xcase 'w':				/* File warning */
X    warn = 1;
X    break;
X
Xcase 'q':				/* Quiet */
X    quiet = 1;
X    break;
X
Xcase 'd':				/* debug */
X    debopn("debug.log");
X    break;
X
Xcase 'p':				/* set parity */
X    if (*(xp+1)) fatal("invalid argument bundling");
X    *xargv++, xargc--;
X    if ((xargc < 1) || (**xargv == '-'))
X    	fatal("missing parity");
X    switch(x = **xargv) {
X	case 'e':
X	case 'o':
X	case 'm':
X	case 's': parity = x; break;
X	case 'n': parity = 0; break;
X	default:  fatal("invalid parity");
X        }
X    break;
X
Xcase 't':
X    turn = 1;				/* Line turnaround handshake */
X    turnch = XON;			/* XON is turnaround character */
X    duplex = 1;				/* Half duplex */
X    flow = 0;				/* No flow control */
X    break;
X
Xdefault:
X    fatal("invalid argument, type 'kermit -h' for help");
X        }
X
X    x = *++xp;				/* See if options are bundled */
X    }
X    return(0);
X}
X
X/* Misc */
X
Xfatal(msg) char *msg; {			/* Fatal error message */
X    fprintf(stderr,"\r\nFatal: %s\n",msg);
X    tlog(F110,"Fatal:",msg,0l);
X    doexit(1);				/*  exit with status = 1 */
X}
X
X
Xermsg(msg) char *msg; {			/* Print error message */
X    if (!quiet) fprintf(stderr,"\r\nError - %s\n",msg);
X    tlog(F110,"Error -",msg,0l);
X}
X
X/* Interactive command parser */ 
X
X
X/* Top-Level Keyword Table */
X
Xstruct keytab cmdtab[] = {
X    "!",	   XXSHE, 0,
X    "bye",         XXBYE, 0,
X    "c",           XXCON, CM_INV,
X    "close",	   XXCLO, 0,
X    "connect",     XXCON, 0,
X    "cwd",	   XXCWD, 0,
X    "dial",	   XXDIAL, 0,
X    "directory",   XXDIR, 0,
X    "echo",        XXECH, 0,
X    "exit",	   XXEXI, 0,
X    "finish",	   XXFIN, 0,
X    "get",	   XXGET, 0,
X    "help",	   XXHLP, 0,
X    "log",  	   XXLOG, 0,
X    "quit",	   XXQUI, 0,
X    "r",           XXREC, CM_INV,
X    "receive",	   XXREC, 0,
X    "remote",	   XXREM, 0,
X    "s",           XXSEN, CM_INV,
X    "script",	   XXLOGI, 0,
X    "send",	   XXSEN, 0,
X    "server",	   XXSER, 0,
X    "set",	   XXSET, 0,
X    "show", 	   XXSHO, 0,
X    "space",       XXSPA, 0,
X    "statistics",  XXSTA, 0,
X    "take",	   XXTAK, 0
X};
Xint ncmd = (sizeof(cmdtab) / sizeof(struct keytab));
X
X/* Parameter keyword table */
X
Xstruct keytab prmtab[] = {
X    "baud",	        XYSPEE,  CM_INV,
X    "block-check",  	XYCHKT,  0,
X    "delay",	    	XYDELA,  0,
X    "duplex",	    	XYDUPL,  0,
X    "end-of-packet",    XYEOL,   0,
X    "escape-character", XYESC,   0,
X    "file", 	  	XYFILE,  0,
X    "flow-control", 	XYFLOW,  0,
X    "handshake",    	XYHAND,  0,
X    "line",             XYLINE,  0,
X    "modem-dialer",	XYMODM,	 0,
X    "packet-length",    XYLEN,   0,
X    "pad-character",    XYPADC,  0,
X    "padding",          XYNPAD,  0,
X    "parity",	    	XYPARI,  0,
X    "prompt",	    	XYPROM,  0,
X    "speed",	        XYSPEE,  0,
X    "start-of-packet",  XYMARK,  0,
X    "timeout",	        XYTIMO,  0
X};
Xint nprm = (sizeof(prmtab) / sizeof(struct keytab)); /* How many parameters */
X
X
X/* Remote Command Table */
X
Xstruct keytab remcmd[] = {
X    "cwd",       XZCWD, 0,
X    "delete",    XZDEL, 0,
X    "directory", XZDIR, 0,
X    "help",      XZHLP, 0,
X    "host",      XZHOS, 0,
X    "space",	 XZSPA, 0,
X    "type", 	 XZTYP, 0,
X    "who",  	 XZWHO, 0
X};
Xint nrmt = (sizeof(remcmd) / sizeof(struct keytab));
X
Xstruct keytab logtab[] = {
X    "debugging",    LOGD, 0,
X    "packets",	    LOGP, 0,
X    "session",      LOGS, 0,
X    "transactions", LOGT, 0
X};
Xint nlog = (sizeof(logtab) / sizeof(struct keytab));
X
X/* Show command arguments */
X
X#define SHPAR 0				/* Parameters */
X#define SHVER 1				/* Versions */
X
Xstruct keytab shotab[] = {
X    "parameters", SHPAR, 0,
X    "versions",   SHVER, 0
X};
X
X/*  C M D I N I  --  Initialize the interactive command parser  */
X
Xcmdini() {
X
X    printf("%s,%s\nType ? for help\n",versio,ckxsys);
X    cmsetp("C-Kermit>");		/* Set default prompt. */
X
X    tlevel = -1;			/* Take file level */
X
X/* Look for init file ".kermrc" in home or current directory. */
X
X    homdir = zhome();
X    lp = line;
X    if (homdir)
X	sprintf(lp,"%s/.kermrc",homdir);
X    else
X    	sprintf(lp,".kermrc");
X    if ((tfile[0] = fopen(line,"r")) != NULL) {
X	tlevel = 0;
X	debug(F110,"init file",line,0);
X    }
X    if (homdir && (tlevel < 0)) {
X    	sprintf(lp,".kermrc");
X	if ((tfile[0] = fopen(line,"r")) != NULL) {
X	    tlevel = 0;
X	    debug(F110,"init file",line,0);
X	} else {
X	    debug(F100,"no init file","",0);
X        }
X    }
X
X    congm();				/* Get console tty modes */
X}
X
X
X/*  T R A P  --  Terminal interrupt handler */
X
Xtrap() {
X    debug(F100,"terminal interrupt...","",0);
X    doexit(0);				/* exit with status = 0 */
X}
X
X/*  P A R S E R  --  Top-level interactive command parser.  */
X
Xparser() {
X    int xx;
X    concb(escape);		/* Put console in cbreak mode. */
X    conint(trap);		/* Turn on console terminal interrupts. */
X/*
X sstate becomes nonzero when a command has been parsed that requires some
X action from the protocol module.  Any non-protocol actions, such as local
X directory listing or terminal emulation, are invoked directly from below.
X*/
X    if (local) printf("\n");		/*** Temporary kludge ***/
X    sstate = 0;				/* Start with no start state. */
X    while (sstate == 0) {		/* Parse cmds until action requested */
X	while ((tlevel > -1) && feof(tfile[tlevel])) { /* If end of take */
X		fclose(tfile[tlevel]);	/* file, close it */
X		tlevel--;		/* and forget about it. */
X		cmini(ckxech);		/* and clear the cmd buffer. */
X 	}
X	if (tlevel > -1) {
X	    if (fgets(cmdbuf,CMDBL,tfile[tlevel]) == NULL) continue;
X	    stripq(cmdbuf);		/* Strip any quotes. */
X	} else {			/* Otherwise. */
X	    prompt();			/* Issue interactive prompt. */
X	    cmini(ckxech);
X    	}
X	repars = 1;
X	displa = 0;
X	while (repars) {
X	    cmres();			/* Reset buffer pointers. */
X	    xx = cmkey(cmdtab,ncmd,"Command","");
X	    debug(F101,"top-level cmkey","",xx);
X	    switch (docmd(xx)) {
X		case -4:		/* EOF */
X		    doexit(0);		/*  exit with status 0 */
X	        case -1:		/* Reparse needed */
X		    repars = 1;
X		    continue;
X	    	case -2:		/* Invalid command given */
X		    if (backgrd) 	/* if in background, terminate */
X			fatal("Kermit command error in background execution");
X		    if (tlevel > -1) {	/* If in take file, quit */
X			ermsg("Kermit command error: take file terminated.");
X			fclose(tfile[tlevel]);
X			tlevel--;
X		    }
X		    cmini(ckxech);	/* (fall thru) */
X 	    	case -3:		/* Empty command OK at top level */
X		default:		/* Anything else (fall thru) */
X		    repars = 0;		/* No reparse, get new command. */
X		    continue;
X            }
X        }
X    }
X/* Got an action command; disable terminal interrupts and return start state */
X
X    if (!local) connoi();		/* Interrupts off only if remote */
X    return(sstate);
X}
X
X/*  D O E X I T  --  Exit from the program.  */
X
Xdoexit(exitstat) int exitstat; {
X    
X    ttclos();				/* Close external line, if any */
X    if (local) {
X	strcpy(ttname,dftty);		/* Restore default tty */
X	local = dfloc;			/* And default remote/local status */
X    }
X    if (!quiet) conres();		/* Restore console terminal. */
X    if (!quiet) connoi();		/* Turn off console interrupt traps. */
X
X    if (deblog) {			/* Close any open logs. */
X	debug(F100,"Debug Log Closed","",0);
X	*debfil = '\0';
X	deblog = 0;
X	zclose(ZDFILE);
X    }
X    if (pktlog) {
X	*pktfil = '\0';
X	pktlog = 0;
X	zclose(ZPFILE);
X    }
X    if (seslog) {
X    	*sesfil = '\0';
X	seslog = 0;
X	zclose(ZSFILE);
X    }
X    if (tralog) {
X	tlog(F100,"Transaction Log Closed","",0l);
X	*trafil = '\0';
X	tralog = 0;
X	zclose(ZTFILE);
X    }
X    exit(exitstat);				/* Exit from the program. */
X}
X
X/*  B L D L E N  --  Make length-encoded copy of string  */
X
Xchar *
Xbldlen(str,dest) char *str, *dest; {
X    int len;
X    len = strlen(str);
X    *dest = tochar(len);
X    strcpy(dest+1,str);
X    return(dest+len+1);
X}
X
X
X/*  S E T G E N  --  Construct a generic command  */
X
Xsetgen(type,arg1,arg2,arg3) char type, *arg1, *arg2, *arg3; {
X    char *upstr, *cp;
X
X    cp = cmdstr;
X    *cp++ = type;
X    *cp = NUL;
X    if (*arg1 != NUL) {
X	upstr = bldlen(arg1,cp);
X	if (*arg2 != NUL) {
X	    upstr = bldlen(arg2,upstr);
X	    if (*arg3 != NUL) bldlen(arg3,upstr);
X	}
X    }
X    cmarg = cmdstr;
X    debug(F110,"setgen",cmarg,0);
X
X    return('g');
X}
X
X/*  D O C M D  --  Do a command  */
X
X/*
X Returns:
X   -2: user typed an illegal command
X   -1: reparse needed
X    0: parse was successful (even tho command may have failed).
X*/ 
X
Xdocmd(cx) int cx; {
X    int x, y;
X    char *s;
X
X    switch (cx) {
X
Xcase -4:				/* EOF */
X    if (!quiet) printf("\r\n");
X    doexit(0);
Xcase -3:				/* Null command */
X    return(0);
Xcase -2:				/* Error */
Xcase -1:				/* Reparse needed */
X    return(cx);
X
Xcase XXBYE:				/* bye */
X    if ((x = cmcfm()) < 0) return(x);
X    if (!local) {
X	printf("You have to 'set line' first\n");
X	return(0);
X    }
X    sstate = setgen('L',"","","");
X    return(0);
X
Xcase XXCON:                     	/* connect */
X    if ((x = cmcfm()) < 0) return(x);
X    conres();				/* restore tty to normal mode */
X    x = conect();
X    concb(escape);			/* tty back in character mode */
X    return(x);
X
Xcase XXCWD:
X    if (cmtxt("Name of local directory, or carriage return",homdir,&s) < 0)
X    	return(-1);    
X    if (chdir(s)) perror(s);
X    cwdf = 1;
X    system("pwd");
X    return(0);
X
Xcase XXCLO:
X    x = cmkey(logtab,nlog,"Which log to close","");
X    if (x == -3) {
X	printf("?You must tell which log\n");
X	return(-2);
X    }
X    if (x < 0) return(x);
X    if ((y = cmcfm()) < 0) return(y);
X    switch (x) {
X
X	case LOGD:
X	    if (deblog == 0) {
X		printf("?Debugging log wasn't open\n");
X		return(0);
X	    }
X	    *debfil = '\0';
X	    deblog = 0;
X	    return(zclose(ZDFILE));
X
X	case LOGP:
X	    if (pktlog == 0) {
X		printf("?Packet log wasn't open\n");
X		return(0);
X	    }
X	    *pktfil = '\0';
X	    pktlog = 0;
X	    return(zclose(ZPFILE));
X
X	case LOGS:
X	    if (seslog == 0) {
X		printf("?Session log wasn't open\n");
X		return(0);
X	    }
X	    *sesfil = '\0';
X	    seslog = 0;
X	    return(zclose(ZSFILE));
X
X    	case LOGT:
X	    if (tralog == 0) {
X		printf("?Transaction log wasn't open\n");
X		return(0);
X	    }
X	    *trafil = '\0';
X	    tralog = 0;
X	    return(zclose(ZTFILE));
X
X	default:
X	    printf("\n?Unexpected log designator - %ld\n", x);
X	    return(0);
X    }
X
Xcase XXDIAL:				/* dial number */
X    if ((x = cmtxt("Number to be dialed","",&s)) < 0) return(x);
X    return( dial(s) );			/* return success 0=connected -2=fail*/
X
Xcase XXDIR:				/* directory */
X    if ((x = cmtxt("Directory/file specification","*",&s)) < 0) return(x);
X    lp = line;
X    sprintf(lp,"ls -l %s",s);
X    system(line);
X    return(0);
X
Xcase XXECH:				/* echo */
X    x = cmtxt("Material to be echoed","",&s);
X    if (x < 0) return(x);
X    printf("%s\n",s);
X    return(0);
X
Xcase XXQUI:				/* quit, exit */
Xcase XXEXI:
X    if ((x = cmcfm()) > -1) doexit(0);	/*  exit with status 0 */
X    else return(x);
X
Xcase XXFIN:				/* finish */
X    if ((x = cmcfm()) < 0) return(x);
X    if (!local) {
X	printf("You have to 'set line' first\n");
X	return(0);
X    }
X    sstate = setgen('F',"","","");
X    return(0);
X
Xcase XXGET:				/* Get */
X    if (!local) {
X	printf("\nYou have to 'set line' first\n");
X	return(0);
X    }
X    x = cmtxt("Name of remote file(s), or carriage return","",&cmarg);
X    if ((x == -2) || (x == -1)) return(x);
X
X/* If foreign file name omitted, get foreign and local names separately */
X
X    if (*cmarg == NUL) {
X
X	if (tlevel > -1) {		/* Input is from take file */
X
X	    if (fgets(line,100,tfile[tlevel]) == NULL)
X	    	fatal("take file ends prematurely in 'get'");
X	    stripq(line);
X	    cmarg = line;
X	    if (fgets(cmdbuf,CMDBL,tfile[tlevel]) == NULL)
X	    	fatal("take file ends prematurely in 'get'");
X		stripq(cmdbuf);
X	    if (*cmdbuf == NUL) cmarg2 = line; else cmarg2 = cmdbuf;
X
X        } else {			/* Input is from terminal */
X
X	    char psave[40];		/* Save old prompt */
X	    cmsavp(psave,40);
X	    cmsetp(" Remote file specification: "); /* Make new one */
X	    cmini(ckxech);
X	    x = -1;
X	    while (x < 0) {		/* Prompt till they answer */
X	    	prompt();
X	    	x = cmtxt("Name of remote file(s)","",&cmarg);
X	    	if (*cmarg == NUL) x = -1;
X	    }
X	    strcpy(line,cmarg);		/* Make a safe copy */
X	    cmarg = line;
X	    cmsetp(" Local name to store it under: ");	/* New prompt */
X	    cmini(ckxech);
X	    x = -1;
X	    while (x < 0) {		/* Again, prompt till answered */
X	    	prompt();
X	    	x = cmofi("Local file name",cmarg,&cmarg2);
X		if (x == -2) return(x);
X            }
X	    cmsetp(psave);		/* Restore old prompt. */
X	    if ((x == cmcfm()) < 0) return(-2);
X        }
X    }
X    sstate = 'r';			/* All ok, set start state. */
X    if (local) displa = 1;
X    return(0);
X
Xcase XXHLP:				/* Help */
X    x = cmkey(cmdtab,ncmd,"C-Kermit command","help");
X    return(dohlp(x));
X
Xcase XXLOG:				/* Log */
X    x = cmkey(logtab,nlog,"What to log","");
X    if (x == -3) {
X	printf("?You must specify what is to be logged\n");
X	return(-2);
X    }
X    if (x < 0) return(x);
X    return(dolog(x));
X
Xcase XXLOGI:				/* login to remote system */
X    if ((x = cmtxt("Text of login script","",&s)) < 0) return(x);
X    return( login(s) );			/* return success 0=completed -2=fail*/
X
Xcase XXREC:				/* Receive */
X    cmarg2 = "";
X    x = cmofi("Name under which to store the file, or CR","",&cmarg2);
X    if ((x == -1) || (x == -2)) return(x);
X    debug(F111,"cmofi cmarg2",cmarg2,x);
X    if ((x = cmcfm()) < 0) return(x);
X    sstate = 'v';
X    if (local) displa = 1;
X    return(0);
X
Xcase XXREM:				/* Remote */
X    if (!local) {
X	printf("\nYou have to 'set line' first\n");
X	return(-2);
X    }
X    x = cmkey(remcmd,nrmt,"Remote Kermit server command","");
X    if (x == -3) {
X	printf("?You must specify a command for the remote server\n");
X	return(-2);
X    }
X    return(dormt(x));
X
Xcase XXSEN:				/* Send */
X    cmarg = cmarg2 = "";
X    if ((x = cmifi("File(s) to send","",&s,&y)) < 0) {
X	if (x == -3) {
X	    printf("?A file specification is required\n");
X	    return(-2);
X	}
X	return(x);
X    }
X    nfils = -1;				/* Files come from internal list. */
X    strcpy(line,s);			/* Save copy of string just parsed. */
X    debug(F101,"Send: wild","",y);
X    *cmarg2 = '\0';			/* Initialize send-as name */
X    if (y == 0) {
X	if ((x = cmfld("Name to send it with",line,&cmarg2)) < 0) return(x);
X    }
X    if ((x = cmcfm()) < 0) return(x);
X    cmarg = line;			/* File to send */
X    debug(F110,"Sending:",cmarg,0);
X    debug(F110," as:",cmarg2,0);
X    sstate = 's';			/* Set start state */
X    if (local) displa = 1;
X    return(0);
X
Xcase XXSER:				/* Server */
X    if (x = (cmcfm()) < 0) return(x);
X    sstate = 'x';
X    if (local) displa = 1;
X    return(0);
X
Xcase XXSET:				/* Set */
X    x = cmkey(prmtab,nprm,"Parameter","");
X    if (x == -3) {
X	printf("?You must specify a parameter to set\n");
X	return(-2);
X    }
X    if (x < 0) return(x);
X    return(doprm(x));
X    
Xcase XXSHE:				/* Local shell command */
X    if (cmtxt("Unix shell command to execute","",&s) < 0) return(-1);
X    conres();				/* Make console normal  */
X    system(s);				/* Execute the command */
X    concb(escape);			/* Console back in cbreak mode */
X    return(0);
X
Xcase XXSHO:				/* Show */
X    x = cmkey(shotab,2,"","parameters");
X    if (x < 0) return(x);
X    if (y = (cmcfm()) < 0) return(y);
X    switch (x) {
X
X	case SHPAR:
X	    shopar();
X	    break;
X
X	case SHVER:
X	    printf("\nVersions:\n %s\n %s\n %s\n",versio,protv,fnsv);
X	    printf(" %s\n %s\n %s for%s\n",cmdv,userv,ckxv,ckxsys);
X            printf(" %s for%s\n %s\n\n",ckzv,ckzsys,connv);
X	    break;
X
X	default:
X	    printf("\nNothing to show...\n");
X	    break;
X    }	    
X    return(0);
X
Xcase XXSPA:				/* space */
X    if (x = (cmcfm()) < 0) return(x);
X    system(SPACMD);
X    return(0);
X
Xcase XXSTA:				/* statistics */
X    if (x = (cmcfm()) < 0) return(x);
X    printf("\nMost recent transaction --\n");
X    printf(" files: %ld\n",filcnt);
X    printf(" total file characters  : %ld\n",tfc);
X    printf(" communication line in  : %ld\n",tlci);
X    printf(" communication line out : %ld\n\n",tlco);
X    printf(" block check type used  : %d\n",bctu);
X    printf(" compression            : ");
X    if (rptflg) printf("yes\n"); else printf("no\n");
X    printf(" 8th bit prefixing      : ");
X    if (ebqflg) printf("yes\n"); else printf("no\n\n");
X    return(0);
X
Xcase XXTAK:				/* take */
X    if (tlevel > MAXTAKE-1) {
X	printf("?Take files nested too deeply\n");
X	return(-2);
X    }
X    if ((y = cmifi("C-Kermit command file","",&s,&x)) < 0) { 
X	if (y == -3) {
X	    printf("?A file specification is required\n");
X	    return(-2);
X	} else return(y);
X    }
X    if (x != 0) {
X	printf("?Wildcards not allowed in command file name\n");
X	return(-2);
X    }
X    strcpy(line,s);			/* Make a safe copy of the string */
X    if ((y = cmcfm()) < 0) return(y);
X    if ((tfile[++tlevel] = fopen(line,"r")) == NULL) {
X	perror("take");
X	printf("Can't open command file - %s\n",line);
X	debug(F110,"Failure to open",line,0);
X	tlevel--;
X	return(0);
X    }
X    return(0);
X
Xdefault:
X    printf("Not available yet - %s\n",cmdbuf);
X    return(-2);
X    }
X}
X
X/*  S H O P A R  --  Show Parameters  */
X
Xshopar() {
X
X    printf("\nLine: %s, speed: %d, mode: ",ttname,speed);
X    if (local) printf("local"); else printf("remote");
X    printf(", modem-dialer: ");
X    if (mdmtyp == 1) printf("hayes");
X	else if (mdmtyp == 2) printf("ventel");
X	else printf("direct");
X    printf("\n Parity: ");
X    switch (parity) {
X	case 'e': printf("even");  break;
X	case 'o': printf("odd");   break;
X	case 'm': printf("mark");  break;
X	case 's': printf("space"); break;
X	case 0:   printf("none");  break;
X	default:  printf("invalid - %d",parity); break;
X    }		
X    printf(", duplex: ");
X    if (duplex) printf("half, "); else printf("full, ");
X    printf("flow: ");
X    if (flow == 1) printf("xon/xoff");
X	else if (flow == 0) printf("none");
X	else printf("%d",flow);
X    printf(", handshake: ");
X    if (turn) printf("%d\n",turnch); else printf("none\n");
X    printf(" Timeout: %d, delay: %d\n",timint,delay);
X    printf(" Padding: %d, pad character: %d\n",mypadn,mypadc);
X    printf(" Packet start: %d, end: %d, length: %d",mystch,eol,spsiz);
X    printf(", block check: %d\n",bctr);
X    printf("\nFile parameters:\n");
X    printf(" Names:        ");
X    if (fncnv) printf("converted\n"); else printf("literal\n");
X    printf(" Type:         ");
X    if (binary) printf("binary\n"); else printf("text\n");
X    printf(" Warning:      ");
X    if (warn) printf("on\n"); else printf("off\n");
X    printf(" Display:      ");
X    if (quiet) printf("off\n"); else printf("on\n");
X    printf("\nLogs:");
X    printf("\n Debugging:    ");
X    if (deblog) printf("%s",debfil); else printf("none");
X    printf("\n Packets:      ");
X    if (pktlog) printf("%s",pktfil); else printf("none");
X    printf("\n Session:      ");
X    if (seslog) printf("%s",sesfil); else printf("none");
X    printf("\n Transactions: ");
X    if (tralog) printf("%s",trafil); else printf("none");
X    printf("\n\n");
X}
X
X/*  D O L O G  --  */
X
Xdolog(x) int x; {
X    int y; char *s;
X
X    switch (x) {
X
X	case LOGD:
X	    y = cmofi("Name of debugging log file","debug.log",&s);
X	    break;
X
X	case LOGP:
X	    y = cmofi("Name of packet log file","packet.log",&s);
X	    break;
X
X	case LOGS:
X	    y = cmofi("Name of session log file","session.log",&s);
X	    break;
X
X	case LOGT:
X	    y = cmofi("Name of transaction log file","transaction.log",&s);
X	    break;
X
X	default:
X	    printf("\n?Unexpected log designator - %d\n",x);
X	    return(-2);
X    }
X    if (y < 0) return(y);
X
X    strcpy(line,s);
X    s = line;
X    if ((y = cmcfm()) < 0) return(y);
X
X/* cont'd... */
X
X/* ...dolog, cont'd */
X
X
X    switch (x) {
X
X	case LOGD:
X	    return(deblog = debopn(s));
X
X	case LOGP:
X	    zclose(ZPFILE);
X	    y = zopeno(ZPFILE,s);
X	    if (y > 0) strcpy(pktfil,s); else *pktfil = '\0';
X	    return(pktlog = y);
X
X	case LOGS:
X	    zclose(ZSFILE);
X	    y = zopeno(ZSFILE,s);
X	    if (y > 0) strcpy(sesfil,s); else *sesfil = '\0';
X	    return(seslog = y);
X
X	case LOGT:
X	    zclose(ZTFILE);
X	    tralog = zopeno(ZTFILE,s);
X	    if (tralog > 0) {
X		strcpy(trafil,s);
X		tlog(F110,"Transaction Log:",versio,0l);
X		tlog(F100,ckxsys,"",0);
X		ztime(&s);
X		tlog(F100,s,"",0l);
X    	    }
X	    else *trafil = '\0';
X	    return(tralog);
X
X	default:
X	    return(-2);
X    }
X}
X
X
X/*  D E B O P N  --  Open a debugging file  */
X
Xdebopn(s) char *s; {
X    char *tp;
X    zclose(ZDFILE);
X    deblog = zopeno(ZDFILE,s);
X    if (deblog > 0) {
X	strcpy(debfil,s);
X	debug(F110,"Debug Log ",versio,0);
X	debug(F100,ckxsys,"",0);
X	ztime(&tp);
X	debug(F100,tp,"",0);
X    } else *debfil = '\0';
X    return(deblog);
X}
X
!FUNKY!STUFF!



More information about the Comp.sources.unix mailing list