home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
archives
/
sinclairqla.tar.gz
/
sinclairqla.tar
/
qlkus2.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-05-08
|
16KB
|
527 lines
/*
US2_C - QL-Kermit SET command
Based on ckuus[123].c, (C) Columbia University
*/
/* Include files */
#include "flp1_ctype_h" /* Character type functions */
#include "flp1_fcntl_h" /* File opening modes */
#include "ram1_ker_h" /* Kermit definitions */
#include "ram1_cmd_h" /* Command interpreter definitions */
#include "ram1_usr_h" /* User command definitions */
/* External variables */
extern int slen; /* Send packet size */
extern int rlen; /* Receive packet size */
extern int rtmo; /* Timeout we use */
extern int stmo; /* Timeout remote uses */
extern int ttychid; /* QDOS channel ID for serial line */
extern int debug; /* Debugging level */
extern int trans; /* File name translation */
extern int speed; /* Line speed (baud rate) */
extern int xfertyp; /* File transfer type */
extern int ttyfd; /* FD for communication line */
extern int retry; /* Retry limit */
extern int delay; /* Delay before SEND starts */
extern int serno; /* Serial port in use */
extern int parity; /* Parity setting */
extern int npad; /* How much padding remote needs */
extern bool timer; /* Timer enabled flag */
extern bool echo; /* Local echo flag */
extern bool local; /* Local/remote flag */
extern bool keep; /* Incomplete file disposition */
extern bool tkecho; /* Show TAKE commands flag */
extern bool tkabort; /* Error abort flag */
extern char ssop; /* Packet start remote needs */
extern char rsop; /* Packet start I need */
extern char reol; /* EOL I need */
extern char seol; /* EOL remote needs */
extern char quote; /* Control prefix */
extern char pebq; /* Eight-bit prefix */
extern char enter[]; /* What ENTER sends */
extern unsigned char padch; /* Pad character remote needs */
extern char ttyname[]; /* Communication device name */
extern char *dftty; /* Default ditto */
extern char *sourdev; /* Default source device */
extern char *destdev; /* Default destination device */
extern char *takedev; /* Default TAKE file device */
extern char *suffix; /* Sending file suffix */
extern int _oserr; /* QDOS error code */
extern int oserr; /* Copy of above */
/* External functions */
extern bool chkquote(); /* Check for valid quote character */
/* Keyword tables */
struct keytab srtab[] = /* SEND/RECEIVE parameters */
{
0, "end-of-line", XYEOL,
0, "packet-length", XYLEN,
CM_INV, "start-of-packet", XYMARK,
0, "marker", XYMARK,
0, "timeout", XYTIMO
};
int nsrtab = (sizeof(srtab) / sizeof(struct keytab));
struct keytab filetab[] = /* FILE parameters */
{
0, "type", XZTYPE,
0, "incomplete", XZIFD,
0, "name", XZNAME,
0, "suffix", XZSUFF
};
int nfiletab = (sizeof(filetab) / sizeof(struct keytab));
struct keytab devtab[] = /* DEVICE parameters */
{
0, "source", XZSOUR,
0, "destination", XZDEST,
0, "take-file", XZTAKE
};
int ndevtab = (sizeof(devtab) / sizeof(struct keytab));
struct keytab fntab[4] = /* File name translation */
{
0, "normal", FNNORM,
CM_INV, "translated", FNNORM,
0, "untranslated", FNUNTR,
CM_INV, "literal", FNUNTR
};
struct keytab onoff[2] = /* On/off */
{
0, "off", 0,
0, "on", 1
};
struct keytab deblvl[] = /* Debugging level */
{
0, "off", DBOFF,
0, "on", DBON,
0, "full", DBFULL
};
int ndeblvl = (sizeof(deblvl) / sizeof(struct keytab));
struct keytab ifdtab[3] = /* Incomplete file disposition */
{
0, "delete", 0,
CM_INV, "discard", 0,
0, "keep", 1
};
struct keytab fttab[3] = /* File transfer type */
{
0, "ascii", FTASC,
CM_INV, "text", FTASC,
0, "binary", FTBIN
};
struct keytab ptytab[] = /* PARITY setting */
{
0, "none", PYNONE,
CM_INV, "off", PYNONE,
0, "even", PYEVEN,
0, "odd", PYODD,
0, "mark", PYMARK,
0, "space", PYSPC
};
int nptytab = (sizeof(ptytab) / sizeof(struct keytab));
struct keytab linetab[2] = /* LINE setting */
{
0, "1", 1,
0, "2", 2
};
struct keytab spdtab[] = /* Baud rate */
{
0, "75", 75,
0, "300", 300,
0, "600", 600,
0, "1200", 1200,
0, "2400", 2400,
0, "4800", 4800,
0, "9600", 9600
};
int nspdtab = (sizeof(spdtab) / sizeof(struct keytab));
struct keytab enttab[] = /* ENTER action */
{
0, "cr", 256*CR,
0, "lf", 256*LF,
0, "crlf", 256*CR+LF,
0, "lfcr", 256*LF+CR
};
int nenttab = (sizeof(enttab) / sizeof(struct keytab));
/* DOPRM - Handle the SET command
Returns:
-2: illegal input
-1: reparse needed
0: success
*/
int doprm(xx)
int xx;
{
int x,y,z;
char *s;
switch (xx)
{
case XYEOL: /* These have all been moved */
case XYLEN: /* to SET SEND/RECEIVE, so */
case XYMARK: /* let the user know what to do */
case XYTIMO:
x = cmcfm();
error("Use SET SEND or SET RECEIVE");
return(-2);
case XYENT: /* ENTER action */
if ((y = cmkey(enttab,nenttab,"cr","What ENTER sends"))<0) return(y);
if ((x = cmcfm())<0) return(x);
enter[0] = (y&0177400)>>8;
enter[1] = y&0377;
return(0);
case XYTKAB: /* TAKE file abort */
return(seton(&tkabort));
case XYTIME: /* Timer status */
return(seton(&timer));
case XYTKEC: /* TAKE command echo */
return(seton(&tkecho));
case XYDEB: /* Debugging display level */
if ((y = cmkey(deblvl,ndeblvl,"off","Debug level"))<0) return(y);
if ((x = cmcfm())<0) return(x);
debug = y;
return(0);
case XYECHO: /* Local echo */
return(seton(&echo));
case XYLINE: /* Communication line */
x = cmkey(linetab,2,"","Serial port");
if (x==-1 || x==-2) return(x);
if ((y = cmcfm())<0) return(y);
if (x==-3) x = -1; /* Nothing given, unset line */
serno = x; /* Set new port number */
return(newtty()); /* and reopen it */
case XYPARI: /* Parity */
x = cmkey(ptytab,nptytab,"","Parity setting");
if (x==-3)
{
error("Parity setting not specified");
x = -2;
}
if (x<0) return(x);
if ((y = cmcfm())<0) return(y);
parity = x; /* Set new parity type */
if (serno>0) return(newtty()); /* and re-open line if set */
else return(0); /* otherwise leave it */
case XYRETR: /* Retry limit */
y = cmnum("5",&x,"Number of retries");
return(setnum(&retry,x,y));
case XYDEL: /* SEND delay */
y = cmnum("5",&x,"Delay before SEND");
return(setnum(&delay,x,y));
case XYPAD: /* Padding */
y = cmnum("0",&x,"Amount of padding"); /* Get how much to use */
if (y<0) return(y);
y = cmnum("0",&z,"Character to pad with (decimal)");
if (y<0) return(y); /* Get character to use */
if ((y = cmcfm())<0) return(y);
npad = x; /* Store results */
padch = (unsigned char) z;
return(0);
case XYRECV: /* SET SEND */
case XYSEND: /* SET RECEIVE */
y = cmkey(srtab,nsrtab,"","What to set");
if (y==-3)
{
error("SEND or RECEIVE parameter not specified");
y = -2;
}
if (y<0) return(y);
switch (y)
{
case XYEOL: y = cmnum("0",&x,"Packet end character");
if ((y = setcc(&z,x,y))<0) return(y);
if (xx==XYRECV) reol = z; else seol = z;
return(0);
case XYLEN: y = cmnum("90",&x,"Maximum packet length");
if ((y = setnum(&z,x,y))<0) return(y);
if (xx==XYRECV) rlen = z; else slen = z;
return(0);
case XYMARK: y = cmnum("1",&x,"Packet start character");
if ((y = setcc(&z,x,y))<0) return(y);
if (xx==XYRECV) rsop = z; else ssop = z;
return(0);
case XYTIMO: if ((y = cmnum("5",&x,"Timeout in seconds"))<0) return(y);
if ((x<1) || (x>94))
{
error("Timeout must be in range 1 to 94");
return(-2);
}
if ((y = cmcfm())<0) return(y);
if (xx==XYRECV) rtmo = x; else stmo = x;
return(0);
default: error("Unknown SET SEND/RECEIVE option");
return(-2);
}
case XYFILE: /* SET FILE */
y = cmkey(filetab,nfiletab,"","File option");
if (y==-3)
{
error("FILE parameter not specified");
y = -2;
}
if (y<0) return(y);
switch (y)
{
case XZTYPE: if ((y = cmkey(fttab,3,"ascii","Transfer type"))<0) return(y);
if ((x = cmcfm())<0) return(x);
xfertyp = y;
return(0);
case XZIFD: if ((y = cmkey(ifdtab,3,"discard","Incomplete file action"))<0) return(y);
if ((x = cmcfm())<0) return(x);
keep = (y==1);
return(0);
case XZNAME: if ((y = cmkey(fntab,4,"normal","File name action"))<0) return(y);
if ((x = cmcfm())<0) return(x);
trans = y;
return(0);
case XZSUFF: y = cmfld("",&s,"Outgoing file suffix");
if (y==-1 || y==-2) return(y);
if ((x = cmcfm())<0) return(x);
strcpy(suffix,s);
return(0);
default: error("Unknown SET FILE option");
return(-2);
}
case XYDEV: /* SET DEVICE */
y = cmkey(devtab,ndevtab,"","Device to set");
if (y==-3)
{
error("DEVICE parameter not specified");
y = -2;
}
if (y<0) return(y);
switch(y)
{
case XZSOUR: return(setdev("Transfer source device",sourdev));
case XZDEST: return(setdev("Transfer destination device",destdev));
case XZTAKE: return(setdev("Command file device",takedev));
default: error("Unknown SET DEVICE option");
return(-2);
}
case XYSPEE: /* Speed (baud rate) */
if (!local)
{
error("Communication line not set");
return(-2);
}
if ((y = cmkey(spdtab,nspdtab,DFSPEED,"Baud rate"))<0) return(y);
if (x = (cmcfm())<0) return(x);
if ((x = setbaud(y))<0)
{
error("Can't set speed to %d",y);
return(-2);
}
speed = y;
if (debon) printf("%s set to %d baud\n",ttyname,speed);
return(0);
case XYQCTL: /* Control quote */
return(setq("e,pebq,"#","Control quote character"));
case XYEBQ: /* 8-bit quote */
return(setq(&pebq,quote,"&","8-bit quote character"));
default: if ((x = cmcfm())<0) return(x);
error("Unknown SET option");
return(-2);
}
}
/* SETQ - Parse and set a quote character */
int setq(c,other,xdef,xhlp)
char *c;
char other;
char *xdef,*xhlp;
{
int x,y;
char *s;
if ((y = cmfld(xdef,&s,xhlp))<0) return(y); /* Read parameter */
if ((y = cmcfm())<0) return(y); /* Confirm end */
if (strlen(s)!=1) /* Check length */
{
error("Not a single character - %s",s);
return(-2);
}
x = *s;
if (!chkquote(x)) /* Check for valid quote character */
{
error("Not a valid quote character - %c",x);
return(-2);
}
if (x==other) /* Check for duplication */
{
error("Quote characters identical");
return(-2);
}
*c = x; /* Valid, set new value */
return(0);
}
/* SETON - Parse ON/OFF (default ON), set parameter to result */
int seton(prm)
int *prm;
{
int x, y;
if ((y = cmkey(onoff,2,"on","Option"))<0) return(y);
if ((x = cmcfm())<0) return(x);
*prm = (y==1);
return(0);
}
/* SETNUM - Set parameter to result of cmnum() parse
Call with:
x = number from cnum parse
y = return code from cmnum
*/
int setnum(prm,x,y)
int *prm,x,y;
{
if (y<0) return(y); /* cmnum error */
if (x>94 || x<0) /* Check range */
{
error("Number not in range 0..94 - %d",x);
return(-2);
}
if ((y = cmcfm())<0) return(y);
*prm = x;
return(0);
}
/* SETCC - Set parameter to an ASCII control character value */
int setcc(prm,x,y)
int *prm,x,y;
{
if (y<0) return(y); /* cmnum error */
if ((x>037) && (x!=0177)) /* Check range */
{
error("Number not in ASCII control range - %d",x);
return(-2);
}
if ((y = cmcfm())<0) return(y);
*prm = x;
return(0);
}
/* SETDEV - Read and set a device name */
int setdev(xhlp,str)
char *xhlp,*str;
{
char *s;
int x;
x = cmfld("",&s,xhlp); /* Read device name */
if (x==-3)
{
error("Device not specified"); /* Must be given */
x = -2;
}
if (x<0) return(x);
if ((x = cmcfm())<0) return(x); /* Check end of line */
strcpy(str,s); /* Copy name to resting place */
return(0);
}