home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 1
/
GoldFishApril1994_CD1.img
/
d2xx
/
d240
/
xprlib
/
comm-program
/
xprfuncs.c
< prev
Wrap
C/C++ Source or Header
|
1989-08-28
|
10KB
|
505 lines
/** xprfuncs.c
*
* Call-back functions for eXternal PRotocol support
*
**/
#include "vt100.h"
#include <stat.h>
/*
* xproto.h is given in Appendix B
*/
#include "xproto.h"
/*
* xfer.h is a VLT private header file containing some information for
* file transfer protocols
*/
#include "xfer.h"
/*
* These are the C versions of the interface
*/
long vlt_update(), vlt_swrite(), vlt_fread(), vlt_fopen(),
vlt_fclose(), vlt_gets(), vlt_sread(), vlt_chkabort(),
vlt_fwrite(), vlt_fseek(), vlt_ffirst(), vlt_fnext(),
vlt_sflush(), vlt_chkmisc(), vlt_setserial(), vlt_finfo(),
vlt_options();
/*
* These are the assembly level glue functions, see vltface.asm
*/
extern long avlt_update(), avlt_swrite(), avlt_fread(), avlt_fopen(),
avlt_fclose(), avlt_gets(), avlt_sread(), avlt_chkabort(),
avlt_fwrite(), avlt_fseek(), avlt_ffirst(), avlt_fnext(),
avlt_sflush(), avlt_chkmisc(), avlt_setserial(), avlt_finfo(),
avlt_options();
/**
*
* This function initializes an XPR_IO structure.
*
**/
xpr_setup(IO)
struct XPR_IO *IO;
{
/*
* NULL out all the functions we don't do yet.
* Fill the other ones with the addresses to the assembler glue version
* of the interface routines. See vltface.asm
*/
IO->xpr_filename = NULL;
IO->xpr_fopen = avlt_fopen;
IO->xpr_fclose = avlt_fclose;
IO->xpr_fread = avlt_fread;
IO->xpr_fwrite = avlt_fwrite;
IO->xpr_sread = avlt_sread;
IO->xpr_swrite = avlt_swrite;
IO->xpr_sflush = avlt_sflush;
IO->xpr_update = avlt_update;
IO->xpr_chkabort = avlt_chkabort;
IO->xpr_chkmisc = avlt_chkmisc;
IO->xpr_gets = avlt_gets;
IO->xpr_setserial = avlt_setserial;
IO->xpr_ffirst = avlt_ffirst;
IO->xpr_fnext = avlt_fnext;
IO->xpr_finfo = avlt_finfo;
IO->xpr_fseek = avlt_fseek;
/*
* We support 1 extension field
*/
IO->xpr_extension = 1L;
IO->xpr_options = avlt_options;
/*
* NULL out the XPR private data field.
*/
IO->xpr_data = NULL;
return;
}
/**
*
* Interface to VLT's MsgDisplay() function.
*
**/
/*
* These are formats for VLT's requester
*/
static char *xprnamfmt = "%s\n%s\n\n\n\n";
static char *filnamfmt = "\n\n%s\n\n\n";
static char *blksizfmt = "\n\n\n\nBlock: %6ld -- Block Size: %6ld\n";
static char *errtimfmt = "\n\n\n\n\nErrors: %6ld -- Timeouts: %6ld";
static char *delayfmt = "\n\n\n\n\nPacket delay %ld";
/*
* Below are some VLT globals to orchestrate the display
*/
long xpr_blocks = 0L, xpr_blocksize = 0L, xpr_errors = 0L, xpr_timeouts = 0L;
/*
* The function
*/
long vlt_update(x)
struct XPR_UPDATE *x;
{
extern struct Window *mywindow;
extern char *XPR_Name;
/*
* First time, determine the window size (50 chars wide, 5 lines tall).
*/
SetMsgWindow(mywindow, 50, 6);
/*
* Use VLT's PostMsg function to display all the information.
*/
if (x->xpru_updatemask & XPRU_PROTOCOL) {
PostMsg(mywindow, xprnamfmt, XPR_Name, x->xpru_protocol);
}
if (x->xpru_updatemask & XPRU_MSG) {
PostMsg(mywindow, xprnamfmt, XPR_Name, x->xpru_msg);
}
if (x->xpru_updatemask & XPRU_ERRORMSG) {
PostMsg(mywindow, xprnamfmt, XPR_Name, x->xpru_errormsg);
}
if (x->xpru_updatemask & XPRU_FILENAME) {
PostMsg(mywindow, filnamfmt, x->xpru_filename);
}
if (x->xpru_updatemask & XPRU_PACKETDELAY) {
PostMsg(mywindow, delayfmt, x->xpru_packetdelay);
}
if (x->xpru_updatemask & (XPRU_BLOCKS | XPRU_BLOCKSIZE)) {
if (x->xpru_updatemask & XPRU_BLOCKS) xpr_blocks = x->xpru_blocks;
if (x->xpru_updatemask & XPRU_BLOCKSIZE) xpr_blocksize = x->xpru_blocksize;
PostMsg(mywindow, blksizfmt, xpr_blocks, xpr_blocksize);
}
if (x->xpru_updatemask & (XPRU_ERRORS | XPRU_TIMEOUTS)) {
if (x->xpru_updatemask & XPRU_ERRORS) xpr_errors = x->xpru_errors;
if (x->xpru_updatemask & XPRU_TIMEOUTS) xpr_timeouts = x->xpru_timeouts;
PostMsg(mywindow, errtimfmt, xpr_errors, xpr_timeouts);
}
return(0L);
}
/**
*
* Prompt the user for input
*
**/
long vlt_gets(s, t)
char *s, *t;
{
/*
* Use VLT's DoRequest() function
*/
return((long) DoRequest(mywindow, t, s, NULL, " Cancel "));
}
/**
*
* Write a string to the serial port
*
**/
long vlt_swrite(s, n)
char *s;
long n;
{
/*
* Use VLT's SendString() function
*/
SendString(s, (int) n);
return(0L);
}
/**
*
* Read characters from the serial port
*
**/
long vlt_sread(buff, length, micros)
unsigned char *buff;
long length, micros;
{
extern int timeout;
long secs = 0L;
if (buff == NULL) return(-1L);
/*
* Convert timeout to seconds and micros if necessary
*/
if (micros) {
if (micros > 1000000L) {
secs = micros / 1000000L;
micros = micros % 1000000L;
}
}
/*
* Cheat! Only return a single character since we have such a nice
* readchar() function in VLT. One day I'll have to modify this to
* save the odd microsecond...
*/
buff[0] = (unsigned char) readchar(secs, micros);
/*
* VLT has a global called timeout. This comes in xfer.h.
* If the read was successful, return having read a single character.
*/
if (timeout == GOODREAD) return(1L);
/*
* Else return error condition
*/
return(-1L);
}
/**
*
* Flush the serial buffer.
*
**/
long vlt_sflush()
{
ClearBuffer();
return(0L);
}
/**
*
* Interfaces to stdio
*
**/
long vlt_fopen(s, t)
char *s, *t;
{
return((long) fopen(s, t));
}
long vlt_fclose(fp)
FILE *fp;
{
return((long) fclose(fp));
}
long vlt_fread(buff, size, count, fp)
char *buff;
long size, count;
FILE *fp;
{
int res;
res = fread(buff, (int) size, (int) count, fp);
return((long) res);
}
long vlt_fwrite(buff, size, count, fp)
char *buff;
long size, count;
FILE *fp;
{
int res;
res = fwrite(buff, (int) size, (int) count, fp);
return((long) res);
}
long vlt_fseek(fp, offset, origin)
FILE *fp;
long offset;
long origin;
{
int res;
res = fseek(fp, offset, (int) origin);
return((long) res);
}
/*
* File name match (Marco's version).
*/
extern char *scdir(); /* MANX pattern matching function */
long vlt_ffirst(buff, pattern)
char *buff;
char *pattern;
{
char *name;
name = scdir(pattern);
if (name) {
strcpy(buff, name);
return(1L);
}
else return(0L);
}
long vlt_fnext(oldstate, buff, pattern)
long oldstate;
char *buff;
char *pattern;
{
return(vlt_ffirst(buff, pattern));
}
/**
*
* Check for Abort
*
**/
long vlt_chkabort()
{
/*
* VLT aborts its protocols when the escape key is pressed.
* CheckForKey loops over the UserPort messages looking for an escape.
*/
return((long) CheckForKey(69));
}
/**
*
* Check for miscellaneous items
*
**/
long vlt_chkmisc()
{
/*
* VLT does nothing
*/
return(0L);
}
/**
*
* File information
*
**/
long vlt_finfo(filename, infotype)
char *filename;
long infotype;
{
struct stat st;
if (infotype == 1L) {
if (stat(filename, &st) != -1) return(st.st_size);
else return(0L);
}
else if (infotype == 2L) {
return((long) (p_xlatemode + 1));
}
}
/**
*
* This function set the serial port and returns the current status.
*
**/
long vlt_setserial(newstatus)
long newstatus;
{
long oldstatus, getserial();
/*
* If only want to know current status return it
*/
if (newstatus == -1L) return(getserial());
/*
* Fields we don't support
*/
if ( newstatus & 0xFF00E070L) return(-1L);
/*
* Baud rates we don't support
*/
if ( ((newstatus & 0x00FF0000L) >> 16L) > 6L) return(-1L);
/*
* Otherwise get old status
*/
oldstatus = getserial();
/*
* Set new status
*/
setserial(newstatus);
/*
* And return old status
*/
return(oldstatus);
}
/**
*
* Get current serial status
*
**/
static long getserial()
{
static long pariarr[] = { 0x0000L, 0x0301L, 0x0101L, 0x0001L, 0x0003L,
0x0400L, 0x1B01L, 0x1901L, 0x1801L, 0x1803L,
0x1C00L, 0x1F01L, 0x1D01L, 0x1C01L, 0x1C03L };
long oldstatus;
oldstatus = pariarr[p_parity];
/*
* No Xon/Xoff
*/
if ((p_handshake & 1) == 0) oldstatus |= 0x0080L;
/*
* 7-wire
*/
if (p_handshake & 2) oldstatus |= 0x0004L;
/*
* Baud rate
*/
oldstatus |= ( ((long) p_baud) << 16L );
return(oldstatus);
}
/**
*
* Set new serial status
*
**/
static int setserial(newstatus)
long newstatus;
{
/*
* Parity
*/
switch (newstatus & 0xFFFFL) {
case 0x0000L :
p_parity = 0;
break;
case 0x0301L :
p_parity = 1;
break;
case 0x0101L :
p_parity = 2;
break;
case 0x0001L :
p_parity = 3;
break;
case 0x0003L :
p_parity = 4;
break;
case 0x0400L :
p_parity = 5;
break;
case 0x1B01L :
p_parity = 6;
break;
case 0x1901L :
p_parity = 7;
break;
case 0x1801L :
p_parity = 8;
break;
case 0x1803L :
p_parity = 9;
break;
case 0x1C00L :
p_parity = 10;
break;
case 0x1F01L :
p_parity = 11;
break;
case 0x1D01L :
p_parity = 12;
break;
case 0x1C01L :
p_parity = 13;
break;
case 0x1C03L :
p_parity = 14;
break;
}
BaudService(4, p_parity);
/*
* Protocol
*/
p_handshake = 0;
if ((newstatus & 0x0080L) == 0) p_handshake = 1;
if ( newstatus & 0x0004L ) p_handshake |= 2;
BaudService(3, p_handshake);
/*
* Baud rate
*/
p_baud = (newstatus & 0x00FF0000) >> 16L;
BaudService(2, p_baud);
return;
}
/**
*
* Options function
*
**/
long vlt_options(n, opt)
long n;
struct xpr_option *opt[];
{
char buff[256];
long changed = 0L, i;
/*
* Just loop over the options until we have time to implement a single
* requester.
*/
for (i = 0L; i < n; i++) {
strncpy(buff, opt[i]->xpro_value, (int) opt[i]->xpro_length);
if (DoRequest(mywindow, buff, opt[i]->xpro_description, NULL, " Cancel ")) {
strncpy(opt[i]->xpro_value, buff, (int) opt[i]->xpro_length);
changed |= (1L << i);
}
}
return(changed);
}