/* 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); }