/** xprfuncs.c * * Call-back functions for eXternal PRotocol support * **/ #include "vt100.h" #include /* * 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); }